Pokazywanie postów oznaczonych etykietą no-magic. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą no-magic. Pokaż wszystkie posty

wtorek, 17 marca 2015

Maven 3.2.3 internals - how it works

  1. private MavenExecutionResult doExecute(MavenExecutionRequest request)
Executing maven request contains the following steps:
1). Sets starting time to the request object 2). Instantiates result container object 3). Validates local repository 4). Creates new repository session (RepositorySystemSession) 5). Instantiates new maven session object (for future purposes lets call it just "session") 6). Notifies AbstractMavenLifecycleParticipant listeners that session has been started 7). Fires ExecutionEvent.Type.ProjectDiscoveryStarted event with created session to the EventCatapult instance 8). Gathers projects for maven reactor and puts them into session 9). Validate projects (building plugins with extensions cannot be part of reactor) - puts just warns 10). Creates projects dependency graph 11). Quits if any exceptions occurred so far 12). Creates ReactorReader and updates session with sorted projects list and projects map (Map) 13). Enters into session scope (extends com.google.inject.Scope) 14). Seeds scope with session object 15). Looks up for WorkspaceReader instance in DefaultPlexusContainer instance (Workspace reader manages a repository backed by the IDE workspace, a build session or a similar ad-hoc collection of artifacts) 16). Sets workspace reader in the repository session (the order of precedence is: Reactor, Workspace, User Local Respository (M2_REPO)) 17). Marking repository sesssion read-only 18). Notifies AbstractMavenLifecycleParticipant listeners that session project have been read 19). Builds again projects dependency graph, as the participants can potentially change the build order as are free to change the dependencies and as a result topological order of the projects 20). Finally the session is passed to the execute method of LifecycleStarter instance 21). Once done all projects within session are validated against active profiles. 22). All the AbstractMavenLifecycleParticipant listeners are notified that session is about to end 23). Session scope exists

Ad 8. Collecting all projects

private void collectProjects( List projects, List files, MavenExecutionRequest request )
ProjectBuildingRequest projectBuildingRequest = request.getProjectBuildingRequest();
List results = projectBuilder.build( files, request.isRecursive(), projectBuildingRequest );
In project builder build method ReactorModelPool is created which is intended to holding all POM files that are known to the reactor. This allows the project builder to resolve imported POMs from the reactor when building another project's effective model. Next the project builders iterate through all pom files and for each creates MavenProject which is passed to DefaultModelNuildingListener and set on ModelBuildingRequest instance. Now the ModelBuilder object comes into play. ModelBuildingRequest instance is passed into build method. After some initial helper objects instantiations the readModel method is invoked.
private Model readModel(ModelSource modelSource, 
                        File pomFile,
                        ModelBuildingRequest request,
                        DefaultModelProblemCollector problems) throws ModelBuildingException
DefaultModelProcessor instance do the read.
 public Model read( InputStream input, Map options )
        throws IOException
Finally the new instance of MavenXpp3ReaderEx is created and read method invoked. Once model is done it is registered in projectIndex map.
If project is recursive and contains modules it locates pom.xml for each and add it to moduleFiles list. Such prepared list is again passed into the same build method as the initial aggregator pom file. Once all projects are build, next step is populating ReactorModelPool object, created at the beginning. It goes through all interim results and registers all models
  //DefaultProjetBuilder:593
  private void populateReactorModelPool( ReactorModelPool reactorModelPool, List interimResults )
    {
        for ( InterimResult interimResult : interimResults )
        {
            Model model = interimResult.result.getEffectiveModel();
            reactorModelPool.put( model.getGroupId(), model.getArtifactId(), model.getVersion(), model.getPomFile() );

            populateReactorModelPool( reactorModelPool, interimResult.modules );
        }
    }

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 )