czwartek, 18 grudnia 2014

How maven resolves dependencies - raw draft

Package: org.apache.maven.project.DefaultProjectDependenciesResolver.java Method: resolve(DependencyResolutionRequest request)
public interface DependencyResolutionRequest {
 MavenProject getMavenProject();
 DependencyResolutionRequest setMavenProject( MavenProject project );
 DependencyFilter getResolutionFilter();
 DependencyResolutionRequest setResolutionFilter( DependencyFilter filter );
 RepositorySystemSession getRepositorySession();
 DependencyResolutionRequest setRepositorySession( RepositorySystemSession repositorySession );
}
public class DefaultDependencyResolutionRequest
    implements DependencyResolutionRequest
  public DependencyResolutionResult resolve( DependencyResolutionRequest request )
        throws DependencyResolutionException
    {
        RequestTrace trace = RequestTrace.newChild( null, request );

        DefaultDependencyResolutionResult result = new DefaultDependencyResolutionResult();

        MavenProject project = request.getMavenProject();
        RepositorySystemSession session = request.getRepositorySession();
        if ( logger.isDebugEnabled()
            && session.getConfigProperties().get( DependencyManagerUtils.CONFIG_PROP_VERBOSE ) == null )
        {
            DefaultRepositorySystemSession verbose = new DefaultRepositorySystemSession( session );
            verbose.setConfigProperty( DependencyManagerUtils.CONFIG_PROP_VERBOSE, Boolean.TRUE );
            session = verbose;
        }
        DependencyFilter filter = request.getResolutionFilter();
In this part there is some initialization done and actually no-magic.
        ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry();

        CollectRequest collect = new CollectRequest();
        collect.setRootArtifact( RepositoryUtils.toArtifact( project.getArtifact() ) );
        collect.setRequestContext( "project" );
        collect.setRepositories( project.getRemoteProjectRepositories() );
If the project has not direct dependencies, the dependencies are taken from the model
        if ( project.getDependencyArtifacts() == null )
        {
            for ( Dependency dependency : project.getDependencies() )
            {
                if ( StringUtils.isEmpty( dependency.getGroupId() ) || StringUtils.isEmpty( dependency.getArtifactId() )
                    || StringUtils.isEmpty( dependency.getVersion() ) )
                {
                    // guard against case where best-effort resolution for invalid models is requested
                    continue;
                }
                collect.addDependency( RepositoryUtils.toDependency( dependency, stereotypes ) );
            }
        }
Otherwise all dependencies are gathered in the map maps dependecies with its versionless id, which will be used for discovering potencial conficts.
        else
        {
            Map dependencies = new HashMap();
            for ( Dependency dependency : project.getDependencies() )
            {
                String classifier = dependency.getClassifier();
                if ( classifier == null )
                {
                    ArtifactType type = stereotypes.get( dependency.getType() );
                    if ( type != null )
                    {
                        classifier = type.getClassifier();
                    }
                }
                String key =
                    ArtifactIdUtils.toVersionlessId( dependency.getGroupId(), dependency.getArtifactId(),
                                                    dependency.getType(), classifier );
                dependencies.put( key, dependency );
            }
            for ( Artifact artifact : project.getDependencyArtifacts() )
            {
                String key = artifact.getDependencyConflictId();
                Dependency dependency = dependencies.get( key );
                Collection exclusions = dependency != null ? dependency.getExclusions() : null;
                org.eclipse.aether.graph.Dependency dep = RepositoryUtils.toDependency( artifact, exclusions );
                if ( !JavaScopes.SYSTEM.equals( dep.getScope() ) && dep.getArtifact().getFile() != null )
                {
                    // enable re-resolution
                    org.eclipse.aether.artifact.Artifact art = dep.getArtifact();
                    art = art.setFile( null ).setVersion( art.getBaseVersion() );
                    dep = dep.setArtifact( art );
                }
                collect.addDependency( dep );
            }
        }
Now is time for adding managed dependencies (WTF..)
        DependencyManagement depMngt = project.getDependencyManagement();
        if ( depMngt != null )
        {
            for ( Dependency dependency : depMngt.getDependencies() )
            {
                collect.addManagedDependency( RepositoryUtils.toDependency( dependency, stereotypes ) );
            }
        }

Extras

Btw. list of stereotypes:
 default
 ear
 eclipse-application
 eclipse-feature
 eclipse-plugin
 eclipse-repository
 eclipse-target-definition
 eclipse-test-plugin
 eclipse-update-site
 ejb
 ejb3
 ejb-client
 jar
 javadoc
 java-source
 maven-plugin
 par
 pom
 rar
 test-jar
 war

Resolving list of artifacts

Location: org.eclipse.aether.internal.impl.DefaultArtifactResolver.java:242
 public List resolveArtifacts( RepositorySystemSession session,
                                                  Collection requests )
{
        SyncContext syncContext = syncContextFactory.newInstance( session, false );

        try
        {
            Collection artifacts = new ArrayList( requests.size() );
            for ( ArtifactRequest request : requests )
            {
                if ( request.getArtifact().getProperty( ArtifactProperties.LOCAL_PATH, null ) != null )
                {
                    continue;
                }
                artifacts.add( request.getArtifact() );
            }

            syncContext.acquire( artifacts, null );

            return resolve( session, requests );
        }
        finally
        {
            syncContext.close();
        }
    }

ReactorReader

Find file appropriate for given Artifact in local reactor
public File findArtifact( Artifact artifact )