diff --git a/maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java b/maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java index 962b63e14b..8deb562b1f 100644 --- a/maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java +++ b/maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java @@ -677,7 +677,8 @@ private MavenProject buildInternal( Model model, ProjectBuilderConfiguration config, List parentSearchRepositories, File projectDescriptor, - boolean strict, boolean validProfilesXmlLocation, + boolean strict, + boolean isReactorProject, boolean fromSourceTree ) throws ProjectBuildingException { @@ -711,7 +712,7 @@ private MavenProject buildInternal( Model model, } LinkedHashSet activeInSuperPom = new LinkedHashSet(); - List activated = profileAdvisor.applyActivatedProfiles( superModel, projectDescriptor, validProfilesXmlLocation, profileActivationContext ); + List activated = profileAdvisor.applyActivatedProfiles( superModel, projectDescriptor, isReactorProject, profileActivationContext ); if ( !activated.isEmpty() ) { activeInSuperPom.addAll( activated ); @@ -731,7 +732,7 @@ private MavenProject buildInternal( Model model, LinkedHashSet aggregatedRemoteWagonRepositories = collectInitialRepositories( model, superModel, parentSearchRepositories, projectDescriptor, - validProfilesXmlLocation, + isReactorProject, profileActivationContext ); Model originalModel = ModelUtils.cloneModel( model ); @@ -740,7 +741,7 @@ private MavenProject buildInternal( Model model, try { - project = assembleLineage( model, lineage, config, projectDescriptor, aggregatedRemoteWagonRepositories, strict, validProfilesXmlLocation ); + project = assembleLineage( model, lineage, config, projectDescriptor, aggregatedRemoteWagonRepositories, strict, isReactorProject ); } catch ( InvalidRepositoryException e ) { @@ -1089,7 +1090,7 @@ private void validateModel( Model model, } /** - * @param validProfilesXmlLocation + * @param isReactorProject * @noinspection CollectionDeclaredAsConcreteClass * @todo We need to find an effective way to unit test parts of this method! * @todo Refactor this into smaller methods with discrete purposes. @@ -1099,14 +1100,15 @@ private MavenProject assembleLineage( Model model, ProjectBuilderConfiguration config, File pomFile, Set aggregatedRemoteWagonRepositories, - boolean strict, boolean validProfilesXmlLocation ) + boolean strict, + boolean isReactorProject ) throws ProjectBuildingException, InvalidRepositoryException { ModelLineage modelLineage = new DefaultModelLineage(); - modelLineage.setOrigin( model, pomFile, new ArrayList( aggregatedRemoteWagonRepositories ), validProfilesXmlLocation ); + modelLineage.setOrigin( model, pomFile, new ArrayList( aggregatedRemoteWagonRepositories ), isReactorProject ); - modelLineageBuilder.resumeBuildingModelLineage( modelLineage, config, !strict ); + modelLineageBuilder.resumeBuildingModelLineage( modelLineage, config, !strict, isReactorProject ); // FIXME: Find a way to pass in this context, so it's never null! ProfileActivationContext profileActivationContext; @@ -1143,7 +1145,7 @@ private MavenProject assembleLineage( Model model, // NOTE: the caching aspect may replace the parent project instance, so we apply profiles here. // TODO: Review this...is that a good idea, to allow application of profiles when other profiles could have been applied already? - project.setActiveProfiles( profileAdvisor.applyActivatedProfiles( project.getModel(), project.getFile(), validProfilesXmlLocation, profileActivationContext ) ); + project.setActiveProfiles( profileAdvisor.applyActivatedProfiles( project.getModel(), project.getFile(), isReactorProject, profileActivationContext ) ); lineage.addFirst( project ); diff --git a/maven-project/src/main/java/org/apache/maven/project/build/model/DefaultModelLineageBuilder.java b/maven-project/src/main/java/org/apache/maven/project/build/model/DefaultModelLineageBuilder.java index abda61c949..01798b0749 100644 --- a/maven-project/src/main/java/org/apache/maven/project/build/model/DefaultModelLineageBuilder.java +++ b/maven-project/src/main/java/org/apache/maven/project/build/model/DefaultModelLineageBuilder.java @@ -90,7 +90,7 @@ public ModelLineage buildModelLineage( File pom, ProjectBuilderConfiguration config, List remoteRepositories, boolean allowStubs, - boolean validProfilesXmlLocation ) + boolean isReactorProject ) throws ProjectBuildingException { ModelLineage lineage = new DefaultModelLineage(); @@ -101,7 +101,7 @@ public ModelLineage buildModelLineage( File pom, ModelAndFile current = projectWorkspace.getModelAndFile( pom ); if ( current == null ) { - current = new ModelAndFile( readModel( pom ), pom, validProfilesXmlLocation ); + current = new ModelAndFile( readModel( pom ), pom, isReactorProject ); projectWorkspace.storeModelAndFile( current ); } @@ -131,7 +131,8 @@ public ModelLineage buildModelLineage( File pom, current = resolveParentPom( current, currentRemoteRepositories, config, - allowStubs ); + allowStubs, + isReactorProject ); } while ( current != null ); @@ -140,7 +141,8 @@ public ModelLineage buildModelLineage( File pom, public void resumeBuildingModelLineage( ModelLineage lineage, ProjectBuilderConfiguration config, - boolean allowStubs ) + boolean allowStubs, + boolean isReactorProject ) throws ProjectBuildingException { if ( lineage.size() == 0 ) @@ -164,7 +166,8 @@ public void resumeBuildingModelLineage( ModelLineage lineage, current = resolveParentPom( current, currentRemoteRepositories, config, - allowStubs ); + allowStubs, + isReactorProject); while ( current != null ) { @@ -182,7 +185,8 @@ public void resumeBuildingModelLineage( ModelLineage lineage, current = resolveParentPom( current, currentRemoteRepositories, config, - allowStubs ); + allowStubs, + isReactorProject ); } } @@ -240,8 +244,6 @@ private List updateRepositorySet( Model model, { List repositories = model.getRepositories(); - File projectDir = pomFile == null ? null : pomFile.getParentFile(); - Set artifactRepositories = null; if ( repositories != null ) @@ -254,7 +256,7 @@ private List updateRepositorySet( Model model, loadActiveProfileRepositories( remoteRepos, model, config, - projectDir, + pomFile, useProfilesXml ); artifactRepositories = new LinkedHashSet( remoteRepos.size() @@ -321,11 +323,13 @@ private void loadActiveProfileRepositories( List repositories, * resolve that artifact...then, return the resolved POM file for the parent. * @param projectBuildCache * @param allowStubs + * @param childIsReactorProject */ private ModelAndFile resolveParentPom( ModelAndFile child, List remoteRepositories, ProjectBuilderConfiguration config, - boolean allowStubs ) + boolean allowStubs, + boolean childIsReactorProject ) throws ProjectBuildingException { Model model = child.getModel(); @@ -340,9 +344,39 @@ private ModelAndFile resolveParentPom( ModelAndFile child, validateParentDeclaration( modelParent, model ); String key = modelParent.getGroupId() + ":" + modelParent.getArtifactId() + ":" + modelParent.getVersion(); - getLogger().debug( "Checking cache for parent model-and-file instance: " + key ); - result = projectWorkspace.getModelAndFile( modelParent.getGroupId(), modelParent.getArtifactId(), modelParent.getVersion() ); + File parentPomFile = null; + + if ( childIsReactorProject && modelPomFile != null ) + { + getLogger().debug( "Attempting to locate parent model using relativePath and local filesystem; child is a reactor project." ); + + // if the child isn't a reactor project, don't resolve the parent from the local filesystem...use the repository. + String relativePath = modelParent.getRelativePath(); + File modelDir = modelPomFile.getParentFile(); + + parentPomFile = new File( modelDir, relativePath ); + + if ( parentPomFile.isDirectory() ) + { + parentPomFile = new File( parentPomFile, "pom.xml" ); + } + + getLogger().debug( "Checking cache for parent model-and-file instance: " + key + " using file: " + parentPomFile ); + + result = projectWorkspace.getModelAndFile( parentPomFile ); + if ( result != null && !parentModelMatches( modelParent, result.getModel() ) ) + { + result = null; + } + } + + if ( result == null ) + { + getLogger().debug( "Checking cache for parent model-and-file instance: " + key + " using project groupId:artifactId:version." ); + + result = projectWorkspace.getModelAndFile( modelParent.getGroupId(), modelParent.getArtifactId(), modelParent.getVersion() ); + } if ( result != null ) { @@ -352,11 +386,13 @@ private ModelAndFile resolveParentPom( ModelAndFile child, getLogger().debug( "Allowing parent-model resolution to proceed for: " + key + " (child is: " + model.getId() + ")" ); - File parentPomFile = null; - - if ( ( modelPomFile != null ) ) + if ( parentPomFile != null && parentPomFile.exists() ) { - parentPomFile = resolveParentWithRelativePath( modelParent, modelPomFile ); + Model parentModel = readModel( parentPomFile ); + if ( !parentModelMatches( modelParent, parentModel ) ) + { + parentPomFile = null; + } } boolean isResolved = false; @@ -436,6 +472,23 @@ private ModelAndFile resolveParentPom( ModelAndFile child, return result; } + private boolean parentModelMatches( Parent modelParent, Model parentModel ) + { + + boolean groupsMatch = ( parentModel.getGroupId() == null ) + || parentModel.getGroupId().equals( modelParent.getGroupId() ); + boolean versionsMatch = ( parentModel.getVersion() == null ) + || parentModel.getVersion().equals( modelParent.getVersion() ); + + if ( groupsMatch && !versionsMatch + && parentModel.getArtifactId().equals( modelParent.getArtifactId() ) ) + { + return true; + } + + return false; + } + private void validateParentDeclaration( Parent modelParent, Model model ) throws ProjectBuildingException @@ -500,42 +553,6 @@ private File resolveParentFromRepositories( Parent modelParent, } } - private File resolveParentWithRelativePath( Parent modelParent, - File modelPomFile ) - throws ProjectBuildingException - { - String relativePath = modelParent.getRelativePath(); - File modelDir = modelPomFile.getParentFile(); - - File parentPomFile = new File( modelDir, relativePath ); - - if ( parentPomFile.isDirectory() ) - { -// getLogger().debug( "Parent relative-path is a directory; assuming \'pom.xml\' file exists within." ); - parentPomFile = new File( parentPomFile, "pom.xml" ); - } - -// getLogger().debug( "Looking for parent: " + modelParent.getId() + " in: " + parentPomFile ); - - if ( parentPomFile.exists() ) - { - Model parentModel = readModel( parentPomFile ); - - boolean groupsMatch = ( parentModel.getGroupId() == null ) - || parentModel.getGroupId().equals( modelParent.getGroupId() ); - boolean versionsMatch = ( parentModel.getVersion() == null ) - || parentModel.getVersion().equals( modelParent.getVersion() ); - - if ( groupsMatch && versionsMatch - && parentModel.getArtifactId().equals( modelParent.getArtifactId() ) ) - { - return parentPomFile; - } - } - - return null; - } - private Logger getLogger() { if ( logger == null ) diff --git a/maven-project/src/main/java/org/apache/maven/project/build/model/ModelLineageBuilder.java b/maven-project/src/main/java/org/apache/maven/project/build/model/ModelLineageBuilder.java index 5706d2f254..3723e822bc 100644 --- a/maven-project/src/main/java/org/apache/maven/project/build/model/ModelLineageBuilder.java +++ b/maven-project/src/main/java/org/apache/maven/project/build/model/ModelLineageBuilder.java @@ -41,16 +41,24 @@ public interface ModelLineageBuilder * Construct a lineage of the current POM plus all of its ancestors. * * @param pom The current POM, whose Model will terminate the constructed lineage - * @param localRepository The local repository against which parent POMs should be resolved + * + * @param config The project-building configuration to use, which contains the global profile manager, + * local repository, and execution- and user-level properties. + * * @param remoteRepositories List of ArtifactRepository instances against which parent POMs * should be resolved - * @param profileManager The profile manager containing information about global profiles to be - * applied (from settings.xml, for instance) + * * @param allowStubs Whether stubbed-out Model instances should be constructed in the event that * a parent-POM cannot be resolved. + * + * @param isReactorProject Whether the model being built is part of the build we're trying to execute, + * or if it's actually being read from the repository. */ - ModelLineage buildModelLineage( File pom, ProjectBuilderConfiguration config, List remoteRepositories, - boolean allowStubs, boolean validProfilesXmlLocation ) + ModelLineage buildModelLineage( File pom, + ProjectBuilderConfiguration config, + List remoteRepositories, + boolean allowStubs, + boolean isReactorProject ) throws ProjectBuildingException; /** @@ -58,13 +66,20 @@ ModelLineage buildModelLineage( File pom, ProjectBuilderConfiguration config, Li * parent already in the lineage. * * @param lineage The ModelLineage instance in progress, which should be completed. - * @param localRepository The local repository against which parent POMs should be resolved - * @param profileManager The profile manager containing information about global profiles to be - * applied (from settings.xml, for instance) + * + * @param config The project-building configuration to use, which contains the global profile manager, + * local repository, and execution- and user-level properties. + * * @param allowStubs Whether stubbed-out Model instances should be constructed in the event that * a parent-POM cannot be resolved. + * + * @param isReactorProject Whether the model being built is part of the build we're trying to execute, + * or if it's actually being read from the repository. */ - void resumeBuildingModelLineage( ModelLineage lineage, ProjectBuilderConfiguration config, boolean allowStubs ) + void resumeBuildingModelLineage( ModelLineage lineage, + ProjectBuilderConfiguration config, + boolean allowStubs, + boolean isReactorProject ) throws ProjectBuildingException; } diff --git a/maven-project/src/main/java/org/apache/maven/project/workspace/DefaultProjectWorkspace.java b/maven-project/src/main/java/org/apache/maven/project/workspace/DefaultProjectWorkspace.java index 07ef906b51..34210269e1 100644 --- a/maven-project/src/main/java/org/apache/maven/project/workspace/DefaultProjectWorkspace.java +++ b/maven-project/src/main/java/org/apache/maven/project/workspace/DefaultProjectWorkspace.java @@ -1,6 +1,7 @@ package org.apache.maven.project.workspace; import org.apache.maven.model.Model; +import org.apache.maven.model.Parent; import org.apache.maven.project.MavenProject; import org.apache.maven.project.build.model.ModelAndFile; import org.apache.maven.workspace.MavenWorkspaceStore; @@ -8,7 +9,6 @@ import org.codehaus.plexus.logging.Logger; import java.io.File; -import java.net.URI; import java.util.Map; public class DefaultProjectWorkspace @@ -57,9 +57,7 @@ private Object resolvePathKey( File file ) return null; } - URI path = file.toURI().normalize(); - - return path; + return file.toURI().normalize().toString(); } public MavenProject getProject( File projectFile ) @@ -97,9 +95,38 @@ public void storeModelAndFile( ModelAndFile modelAndFile ) Model model = modelAndFile.getModel(); String key = createCacheKey( model.getGroupId(), model.getArtifactId(), model.getVersion() ); + String keyWithParent = createCacheKeyUsingParent( model ); getLogger().debug( "Storing ModelAndFile instance under: " + key + " in workspace." ); cache.put( key, modelAndFile ); + + if ( !key.equals( keyWithParent ) ) + { + getLogger().debug( "Also Storing ModelAndFile instance using groupId/version information from parent, under: " + keyWithParent + " in workspace." ); + cache.put( keyWithParent, modelAndFile ); + } + } + + private String createCacheKeyUsingParent( Model model ) + { + String groupId = model.getGroupId(); + String version = model.getVersion(); + + Parent parent = model.getParent(); + if ( parent != null ) + { + if ( groupId == null ) + { + groupId = parent.getGroupId(); + } + + if ( version == null ) + { + version = parent.getVersion(); + } + } + + return createCacheKey( groupId, model.getArtifactId(), version ); } public void storeProjectByFile( MavenProject project )