diff --git a/maven-core/src/main/java/org/apache/maven/execution/MavenProjectSession.java b/maven-core/src/main/java/org/apache/maven/execution/MavenProjectSession.java index 168f3f36d5..7a99be0f8c 100644 --- a/maven-core/src/main/java/org/apache/maven/execution/MavenProjectSession.java +++ b/maven-core/src/main/java/org/apache/maven/execution/MavenProjectSession.java @@ -39,21 +39,22 @@ public class MavenProjectSession return projectId; } - public static String createRealmId( Artifact realmArtifact ) + private String createExtensionRealmId( Artifact realmArtifact ) { - return ArtifactUtils.versionlessKey( realmArtifact ); + return projectId + "/extensions/" + ArtifactUtils.versionlessKey( realmArtifact ); } - public boolean containsRealm( Artifact extensionArtifact ) + public boolean containsExtensionRealm( Artifact extensionArtifact ) { - String id = createRealmId( extensionArtifact ); + String id = createExtensionRealmId( extensionArtifact ); return componentRealms.containsKey( id ); } public boolean containsRealm( Plugin plugin ) { - String id = createRealmId( plugin ); - return componentRealms.containsKey( id ); + String realmId = createPluginRealmId( ArtifactUtils.versionlessKey( plugin.getGroupId(), plugin.getArtifactId() ) ); + + return componentRealms.containsKey( realmId ); } public ClassRealm getProjectRealm() @@ -64,8 +65,8 @@ public class MavenProjectSession public ClassRealm createExtensionRealm( Artifact extensionArtifact ) throws DuplicateRealmException { - String realmId = MavenProjectSession.createRealmId( extensionArtifact ); - ClassRealm extRealm = container.getContainerRealm().createChildRealm( projectId + "/" + realmId ); + String realmId = createExtensionRealmId( extensionArtifact ); + ClassRealm extRealm = container.getContainerRealm().createChildRealm( realmId ); componentRealms.put( realmId, extRealm ); @@ -79,16 +80,20 @@ public class MavenProjectSession return groupId + ":" + artifactId + ":" + version; } - public ClassRealm getComponentRealm( String key ) + public ClassRealm getPluginRealm( Plugin plugin ) + throws NoSuchRealmException { - return (ClassRealm) componentRealms.get( key ); + String realmId = createPluginRealmId( ArtifactUtils.versionlessKey( plugin.getGroupId(), plugin.getArtifactId() ) ); + + return projectRealm.getWorld().getRealm( realmId ); } - public ClassRealm createPluginRealm( Plugin projectPlugin ) + public ClassRealm createPluginRealm( Plugin plugin ) throws DuplicateRealmException { - String realmId = MavenProjectSession.createRealmId( projectPlugin ); + String realmId = createPluginRealmId( ArtifactUtils.versionlessKey( plugin.getGroupId(), plugin.getArtifactId() ) ); + ClassRealm extRealm = projectRealm.createChildRealm( realmId ); componentRealms.put( realmId, extRealm ); @@ -96,20 +101,16 @@ public class MavenProjectSession return extRealm; } - public static String createRealmId( Plugin plugin ) + private String createPluginRealmId( String baseId ) { - return ArtifactUtils.versionlessKey( plugin.getGroupId(), plugin.getArtifactId() ); + return projectId + "/plugins/" + baseId; } - public static String createRealmId( PluginDescriptor pd ) - { - return ArtifactUtils.versionlessKey( pd.getGroupId(), pd.getArtifactId() ); - } - - public ClassRealm getPluginRealm( PluginDescriptor pluginDescriptor ) + public ClassRealm getPluginRealm( PluginDescriptor pd ) throws NoSuchRealmException { - String realmId = MavenProjectSession.createRealmId( pluginDescriptor ); + String realmId = createPluginRealmId( ArtifactUtils.versionlessKey( pd.getGroupId(), pd.getArtifactId() ) ); + ClassRealm extRealm = projectRealm.getWorld().getRealm( realmId ); componentRealms.put( realmId, extRealm ); diff --git a/maven-core/src/main/java/org/apache/maven/extension/DefaultBuildExtensionScanner.java b/maven-core/src/main/java/org/apache/maven/extension/DefaultBuildExtensionScanner.java index 4b57fdcb77..aa79a487dd 100644 --- a/maven-core/src/main/java/org/apache/maven/extension/DefaultBuildExtensionScanner.java +++ b/maven-core/src/main/java/org/apache/maven/extension/DefaultBuildExtensionScanner.java @@ -336,8 +336,12 @@ public class DefaultBuildExtensionScanner { getLogger().debug( "Building model-lineage for: " + pom + " to pre-scan for extensions." ); + // NOTE: We're assuming that this scan happens only for local filesystem POMs, + // not for POMs from the repository...otherwise, we would need to be more careful with + // the last parameter here and determine whether it's appropriate for the POM to have + // an accompanying profiles.xml file. lineage = modelLineageBuilder.buildModelLineage( pom, localRepository, originalRemoteRepositories, - globalProfileManager, false ); + globalProfileManager, false, true ); } catch ( ProjectBuildingException e ) { diff --git a/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java b/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java index 4602c36def..3ada793d25 100644 --- a/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java +++ b/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java @@ -45,6 +45,7 @@ import org.apache.maven.project.MavenProject; import org.codehaus.plexus.MutablePlexusContainer; import org.codehaus.plexus.PlexusConstants; import org.codehaus.plexus.PlexusContainerException; +import org.codehaus.plexus.classworlds.ClassWorld; import org.codehaus.plexus.classworlds.realm.ClassRealm; import org.codehaus.plexus.classworlds.realm.DuplicateRealmException; import org.codehaus.plexus.classworlds.realm.NoSuchRealmException; @@ -203,7 +204,7 @@ public class DefaultExtensionManager } // if the extension is null, or if it's already been added to the current project-session, skip it. - if ( ( extensionArtifact != null ) && !projectSession.containsRealm( extensionArtifact ) ) + if ( ( extensionArtifact != null ) && !projectSession.containsExtensionRealm( extensionArtifact ) ) { ArtifactFilter filter = new ProjectArtifactExceptionFilter( artifactFilterManager.getArtifactFilter(), projectArtifact ); @@ -276,45 +277,65 @@ public class DefaultExtensionManager } } - ComponentDiscoverer discoverer = new DefaultComponentDiscoverer(); - discoverer.setManager( new DummyDiscovererManager() ); + importLocalExtensionComponents( extensionRealm, projectSession, extensionArtifact ); + } + } - ClassRealm projectRealm = projectSession.getProjectRealm(); - try + private void importLocalExtensionComponents( ClassRealm extensionRealm, + MavenProjectSession projectSession, + Artifact extensionArtifact ) + throws ExtensionManagerException + { + String projectId = projectSession.getProjectId(); + + ClassRealm discoveryRealm = new ClassRealm( new ClassWorld(), "discovery", Thread.currentThread().getContextClassLoader() ); + try + { + discoveryRealm.addURL( extensionArtifact.getFile().toURL() ); + } + catch ( MalformedURLException e ) + { + throw new ExtensionManagerException( "Unable to generate URL from extension artifact for local-component discovery: " + extensionArtifact.getFile(), extensionArtifact, projectId, e ); + } + + ComponentDiscoverer discoverer = new DefaultComponentDiscoverer(); + discoverer.setManager( new DummyDiscovererManager() ); + + ClassRealm projectRealm = projectSession.getProjectRealm(); + try + { + List componentSetDescriptors = discoverer.findComponents( container.getContext(), discoveryRealm ); + for ( Iterator it = componentSetDescriptors.iterator(); it.hasNext(); ) { - List componentSetDescriptors = discoverer.findComponents( container.getContext(), extensionRealm ); - for ( Iterator it = componentSetDescriptors.iterator(); it.hasNext(); ) + ComponentSetDescriptor compSet = (ComponentSetDescriptor) it.next(); + for ( Iterator compIt = compSet.getComponents().iterator(); compIt.hasNext(); ) { - ComponentSetDescriptor compSet = (ComponentSetDescriptor) it.next(); - for ( Iterator compIt = compSet.getComponents().iterator(); compIt.hasNext(); ) + ComponentDescriptor comp = (ComponentDescriptor) compIt.next(); + String implementation = comp.getImplementation(); + + try { - ComponentDescriptor comp = (ComponentDescriptor) compIt.next(); - String implementation = comp.getImplementation(); + getLogger().debug( "Importing: " + implementation + "\nwith role: " + comp.getRole() + "\nand hint: " + comp.getRoleHint() + "\nfrom extension realm: " + extensionRealm.getId() + "\nto project realm: " + projectRealm.getId() ); - try - { - getLogger().debug( "Importing: " + implementation + "\nwith role: " + comp.getRole() + "\nand hint: " + comp.getRoleHint() + "\nfrom extension realm: " + extensionRealm.getId() + "\nto project realm: " + projectRealm.getId() ); + projectRealm.importFrom( extensionRealm.getId(), implementation ); - projectRealm.importFrom( extensionRealm.getId(), implementation ); - - comp.setRealmId( projectRealm.getId() ); - container.addComponentDescriptor( comp ); - } - catch ( NoSuchRealmException e ) - { - throw new ExtensionManagerException( "Failed to create import for component: " + implementation + " from extension realm: " + extensionRealm.getId() + " to project realm: " + projectRealm.getId(), extensionArtifact, projectId, e ); - } + comp.setRealmId( projectRealm.getId() ); + container.addComponentDescriptor( comp ); + } + catch ( NoSuchRealmException e ) + { + throw new ExtensionManagerException( "Failed to create import for component: " + implementation + " from extension realm: " + extensionRealm.getId() + " to project realm: " + projectRealm.getId(), extensionArtifact, projectId, e ); } } } - catch ( PlexusConfigurationException e ) - { - throw new ExtensionManagerException( "Unable to discover extension components.", extensionArtifact, projectId, e ); - } - catch ( ComponentRepositoryException e ) - { - throw new ExtensionManagerException( "Unable to discover extension components from imports added to project-session realm.", extensionArtifact, projectId, e ); - } + } + catch ( PlexusConfigurationException e ) + { + throw new ExtensionManagerException( "Unable to discover extension components.", extensionArtifact, projectId, e ); + } + catch ( ComponentRepositoryException e ) + { + throw new ExtensionManagerException( "Unable to discover extension components from imports added to project-session realm.", extensionArtifact, projectId, e ); } } diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java b/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java index 1d8ea224c2..3685e8f517 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java @@ -28,6 +28,7 @@ import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; import org.apache.maven.artifact.resolver.ArtifactNotFoundException; import org.apache.maven.artifact.resolver.ArtifactResolutionException; import org.apache.maven.context.BuildContextManager; +import org.apache.maven.execution.MavenProjectSession; import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.ReactorManager; import org.apache.maven.lifecycle.binding.MojoBindingFactory; @@ -54,8 +55,14 @@ import org.apache.maven.plugin.version.PluginVersionNotFoundException; import org.apache.maven.plugin.version.PluginVersionResolutionException; import org.apache.maven.project.MavenProject; import org.apache.maven.project.artifact.InvalidDependencyVersionException; +import org.codehaus.plexus.PlexusConstants; +import org.codehaus.plexus.PlexusContainer; +import org.codehaus.plexus.classworlds.realm.ClassRealm; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; +import org.codehaus.plexus.context.Context; +import org.codehaus.plexus.context.ContextException; import org.codehaus.plexus.logging.AbstractLogEnabled; +import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable; import org.codehaus.plexus.util.xml.Xpp3Dom; import java.util.ArrayList; @@ -75,7 +82,7 @@ import java.util.Stack; */ public class DefaultLifecycleExecutor extends AbstractLogEnabled - implements LifecycleExecutor + implements LifecycleExecutor, Contextualizable { // ---------------------------------------------------------------------- // Components @@ -93,6 +100,9 @@ public class DefaultLifecycleExecutor private BuildContextManager buildContextManager; + // this is needed for setting the lookup realm before we start building a project. + private PlexusContainer container; + // ---------------------------------------------------------------------- // // ---------------------------------------------------------------------- @@ -195,53 +205,63 @@ public class DefaultLifecycleExecutor event, target ); - // NEW: To support forked execution under the new lifecycle architecture, the current project - // is stored in a build-context managed data type. This context type holds the current project - // for the fork being executed, plus a stack of projects used in the ancestor execution contexts. - LifecycleExecutionContext ctx = new LifecycleExecutionContext( rootProject ); - ctx.store( buildContextManager ); + ClassRealm oldLookupRealm = setProjectLookupRealm( session, rootProject ); - // NEW: Build up the execution plan, including configuration. - List mojoBindings = getLifecycleBindings( - segment.getTasks(), - rootProject, - target ); - - // NEW: Then, iterate over each binding in that plan, and execute the associated mojo. - // only call once, with the top-level project (assumed to be provided as a parameter)... - for ( Iterator mojoIterator = mojoBindings.iterator(); mojoIterator.hasNext(); ) + try { - MojoBinding binding = (MojoBinding) mojoIterator.next(); + // NEW: To support forked execution under the new lifecycle architecture, the current project + // is stored in a build-context managed data type. This context type holds the current project + // for the fork being executed, plus a stack of projects used in the ancestor execution contexts. + LifecycleExecutionContext ctx = new LifecycleExecutionContext( rootProject ); + ctx.store( buildContextManager ); - try + // NEW: Build up the execution plan, including configuration. + List mojoBindings = getLifecycleBindings( + segment.getTasks(), + rootProject, + target ); + + // NEW: Then, iterate over each binding in that plan, and execute the associated mojo. + // only call once, with the top-level project (assumed to be provided as a parameter)... + for ( Iterator mojoIterator = mojoBindings.iterator(); mojoIterator.hasNext(); ) { - executeGoalAndHandleFailures( - binding, - session, - dispatcher, - event, - reactorManager, - buildStartTime, - target ); - } - catch ( MojoFailureException e ) - { - AggregatedBuildFailureException error = new AggregatedBuildFailureException( - session.getExecutionRootDirectory(), - binding, - e ); + MojoBinding binding = (MojoBinding) mojoIterator.next(); - dispatcher.dispatchError( event, target, error ); - - if ( handleExecutionFailure( reactorManager, rootProject, error, binding, buildStartTime ) ) + try { - throw error; + executeGoalAndHandleFailures( + binding, + session, + dispatcher, + event, + reactorManager, + buildStartTime, + target ); + } + catch ( MojoFailureException e ) + { + AggregatedBuildFailureException error = new AggregatedBuildFailureException( + session.getExecutionRootDirectory(), + binding, + e ); + + dispatcher.dispatchError( event, target, error ); + + if ( handleExecutionFailure( reactorManager, rootProject, error, binding, buildStartTime ) ) + { + throw error; + } } } } + finally + { + // clean up the execution context, so we don't pollute for future project-executions. + LifecycleExecutionContext.delete( buildContextManager ); + + restoreLookupRealm( oldLookupRealm ); + } - // clean up the execution context, so we don't pollute for future project-executions. - LifecycleExecutionContext.delete( buildContextManager ); reactorManager.registerBuildSuccess( rootProject, @@ -295,45 +315,54 @@ public class DefaultLifecycleExecutor event, target ); - LifecycleExecutionContext ctx = new LifecycleExecutionContext( currentProject ); - ctx.store( buildContextManager ); + ClassRealm oldLookupRealm = setProjectLookupRealm( session, currentProject ); - List mojoBindings = getLifecycleBindings( - segment.getTasks(), - currentProject, - target ); - - for ( Iterator mojoIterator = mojoBindings.iterator(); mojoIterator.hasNext(); ) + try { - MojoBinding binding = (MojoBinding) mojoIterator.next(); + LifecycleExecutionContext ctx = new LifecycleExecutionContext( currentProject ); + ctx.store( buildContextManager ); - getLogger().debug( - "Mojo: " + binding.getGoal() + " has config:\n" - + binding.getConfiguration() ); + List mojoBindings = getLifecycleBindings( + segment.getTasks(), + currentProject, + target ); - try + for ( Iterator mojoIterator = mojoBindings.iterator(); mojoIterator.hasNext(); ) { - executeGoalAndHandleFailures( binding, session, dispatcher, - event, reactorManager, - buildStartTime, target ); - } - catch ( MojoFailureException e ) - { - ProjectBuildFailureException error = new ProjectBuildFailureException( - currentProject.getId(), - binding, - e ); + MojoBinding binding = (MojoBinding) mojoIterator.next(); - dispatcher.dispatchError( event, target, error ); + getLogger().debug( + "Mojo: " + binding.getGoal() + " has config:\n" + + binding.getConfiguration() ); - if ( handleExecutionFailure( reactorManager, currentProject, error, binding, buildStartTime ) ) + try { - throw error; + executeGoalAndHandleFailures( binding, session, dispatcher, + event, reactorManager, + buildStartTime, target ); + } + catch ( MojoFailureException e ) + { + ProjectBuildFailureException error = new ProjectBuildFailureException( + currentProject.getId(), + binding, + e ); + + dispatcher.dispatchError( event, target, error ); + + if ( handleExecutionFailure( reactorManager, currentProject, error, binding, buildStartTime ) ) + { + throw error; + } } } } + finally + { + LifecycleExecutionContext.delete( buildContextManager ); - LifecycleExecutionContext.delete( buildContextManager ); + restoreLookupRealm( oldLookupRealm ); + } reactorManager.registerBuildSuccess( currentProject, @@ -361,6 +390,28 @@ public class DefaultLifecycleExecutor } } + private void restoreLookupRealm( ClassRealm oldLookupRealm ) + { + if ( oldLookupRealm != null ) + { + container.setLookupRealm( oldLookupRealm ); + } + } + + private ClassRealm setProjectLookupRealm( MavenSession session, + MavenProject rootProject ) + { + MavenProjectSession projectSession = session.getProjectSession( rootProject ); + if ( projectSession != null ) + { + return container.setLookupRealm( projectSession.getProjectRealm() ); + } + else + { + return null; + } + } + /** * Retrieves the build plan for the current project, given the specified list of tasks. This build plan will consist * of MojoBindings, each fully configured to execute, which enables us to enumerate the full build plan to the debug @@ -429,7 +480,8 @@ public class DefaultLifecycleExecutor { if ( mojoBinding.isOptional() ) { - getLogger().debug( "Skipping optional mojo execution: " + MojoBindingUtils.toString( mojoBinding ) ); + getLogger().debug( "Skipping optional mojo execution: " + MojoBindingUtils.toString( mojoBinding ), e ); + return; } else { @@ -895,4 +947,10 @@ public class DefaultLifecycleExecutor return tasks; } } + + public void contextualize( Context context ) + throws ContextException + { + container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY ); + } } diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/plan/BuildPlanner.java b/maven-core/src/main/java/org/apache/maven/lifecycle/plan/BuildPlanner.java index 64c0ce7c6f..14ae2e6576 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/plan/BuildPlanner.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/plan/BuildPlanner.java @@ -11,9 +11,9 @@ import java.util.List; * MojoBinding instances that carry all the information necessary to execute a mojo, including configuration from the * POM and other sources. NOTE: the build plan may be constructed of a main lifecycle binding-set, plus any number of * lifecycle modifiers and direct-invocation modifiers, to handle cases of forked execution. - * + * * @author jdcasey - * + * */ public interface BuildPlanner { diff --git a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java index 0cc42b7ea4..95e0de4ffc 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java @@ -345,14 +345,21 @@ public class DefaultPluginManager String key = projectPlugin.getKey(); - ClassRealm pluginRealm; + ClassRealm pluginRealm = null; // if we have a project session, it must mean we have extensions... // which in turn may alter the execution of a plugin. MavenProjectSession projectSession = session.getProjectSession( project ); if ( projectSession != null ) { - pluginRealm = projectSession.getComponentRealm( key ); + try + { + pluginRealm = projectSession.getPluginRealm( projectPlugin ); + } + catch ( NoSuchRealmException e ) + { + getLogger().debug( "Plugin realm is missing for: " + projectPlugin.getKey() + ". New realm will be created." ); + } } else { @@ -373,21 +380,21 @@ public class DefaultPluginManager // Realm creation for a plugin // ---------------------------------------------------------------------------- - ClassRealm componentRealm = null; + getLogger().debug( "Creating a ClassRealm instance for plugin: " + projectPlugin.getKey() + " for project: " + project.getId() ); try { if ( projectSession != null ) { - componentRealm = projectSession.createPluginRealm( projectPlugin ); + pluginRealm = projectSession.createPluginRealm( projectPlugin ); try { - componentRealm.addURL( pluginArtifact.getFile().toURI().toURL() ); + pluginRealm.addURL( pluginArtifact.getFile().toURI().toURL() ); } catch ( MalformedURLException e ) { - throw new PluginContainerException( plugin, componentRealm, "Error rendering plugin artifact: " + pluginArtifact.getId() + " as URL.", e ); + throw new PluginContainerException( plugin, pluginRealm, "Error rendering plugin artifact: " + pluginArtifact.getId() + " as URL.", e ); } for ( Iterator i = artifacts.iterator(); i.hasNext(); ) @@ -397,26 +404,26 @@ public class DefaultPluginManager try { getLogger().debug( "Adding: " + artifact.getId() + " to plugin class-realm: " + key + " in project-session: " + project.getId() ); - componentRealm.addURL( artifact.getFile().toURI().toURL() ); + pluginRealm.addURL( artifact.getFile().toURI().toURL() ); } catch ( MalformedURLException e ) { - throw new PluginContainerException( plugin, componentRealm, "Error rendering plugin artifact: " + artifact.getId() + " as URL.", e ); + throw new PluginContainerException( plugin, pluginRealm, "Error rendering plugin artifact: " + artifact.getId() + " as URL.", e ); } } try { - getLogger().debug( "Discovering components in realm: " + componentRealm ); - container.discoverComponents( componentRealm, false ); + getLogger().debug( "Discovering components in realm: " + pluginRealm ); + container.discoverComponents( pluginRealm, false ); } catch ( PlexusConfigurationException e ) { - throw new PluginContainerException( plugin, componentRealm, "Error re-scanning project realm for components.", e ); + throw new PluginContainerException( plugin, pluginRealm, "Error re-scanning project realm for components.", e ); } catch ( ComponentRepositoryException e ) { - throw new PluginContainerException( plugin, componentRealm, "Error re-scanning project realm for components.", e ); + throw new PluginContainerException( plugin, pluginRealm, "Error re-scanning project realm for components.", e ); } } else @@ -433,18 +440,18 @@ public class DefaultPluginManager jars.add( pluginArtifact.getFile() ); // Now here we need the artifact coreArtifactFilter stuff - componentRealm = container.createComponentRealm( key, jars ); + pluginRealm = container.createComponentRealm( key, jars ); } } catch ( PlexusContainerException e ) { - throw new PluginContainerException( plugin, componentRealm, "Failed to create realm for plugin '" + projectPlugin + throw new PluginContainerException( plugin, pluginRealm, "Failed to create realm for plugin '" + projectPlugin + ".", e ); } catch ( DuplicateRealmException e ) { - throw new PluginContainerException( plugin, componentRealm, "Failed to create project-specific realm for plugin '" + projectPlugin + throw new PluginContainerException( plugin, pluginRealm, "Failed to create project-specific realm for plugin '" + projectPlugin + " in project: " + project.getId(), e ); } @@ -454,8 +461,8 @@ public class DefaultPluginManager // adding for MNG-3012 to try to work around problems with Xpp3Dom (from plexus-utils) // spawning a ClassCastException when a mojo calls plugin.getConfiguration() from maven-model... - componentRealm.importFrom( parentRealmId, Xpp3Dom.class.getName() ); - componentRealm.importFrom( parentRealmId, "org.codehaus.plexus.util.xml.pull" ); + pluginRealm.importFrom( parentRealmId, Xpp3Dom.class.getName() ); + pluginRealm.importFrom( parentRealmId, "org.codehaus.plexus.util.xml.pull" ); // Adding for MNG-2878, since maven-reporting-impl was removed from the // internal list of artifacts managed by maven, the classloader is different @@ -463,11 +470,11 @@ public class DefaultPluginManager // is not available from the AbstractMavenReport since it uses: // getClass().getResourceAsStream( "/default-report.xml" ) // (maven-reporting-impl version 2.0; line 134; affects: checkstyle plugin, and probably others) - componentRealm.importFrom( parentRealmId, "/default-report.xml" ); + pluginRealm.importFrom( parentRealmId, "/default-report.xml" ); } catch ( NoSuchRealmException e ) { - throw new PluginContainerException( plugin, componentRealm, + throw new PluginContainerException( plugin, pluginRealm, "Failed to import Xpp3Dom from core realm for plugin: '" + projectPlugin + ".", e ); } @@ -499,9 +506,9 @@ public class DefaultPluginManager pluginDescriptor.setArtifacts( new ArrayList( artifacts ) ); - getLogger().debug( "Realm for plugin: " + plugin.getKey() + ":\n" + componentRealm ); + getLogger().debug( "Realm for plugin: " + plugin.getKey() + ":\n" + pluginRealm ); - pluginDescriptor.setClassRealm( componentRealm ); + pluginDescriptor.setClassRealm( pluginRealm ); } private Set getPluginArtifacts( Artifact pluginArtifact, diff --git a/maven-core/src/test/java/org/apache/maven/extension/DefaultExtensionManagerTest.java b/maven-core/src/test/java/org/apache/maven/extension/DefaultExtensionManagerTest.java index 9a02909007..bcd3a89a41 100644 --- a/maven-core/src/test/java/org/apache/maven/extension/DefaultExtensionManagerTest.java +++ b/maven-core/src/test/java/org/apache/maven/extension/DefaultExtensionManagerTest.java @@ -2,6 +2,7 @@ package org.apache.maven.extension; import org.apache.maven.ArtifactFilterManager; import org.apache.maven.artifact.factory.ArtifactFactory; +import org.apache.maven.artifact.handler.ArtifactHandler; import org.apache.maven.artifact.manager.WagonManager; import org.apache.maven.artifact.metadata.ArtifactMetadataSource; import org.apache.maven.artifact.repository.ArtifactRepositoryFactory; @@ -9,6 +10,7 @@ import org.apache.maven.artifact.repository.DefaultArtifactRepository; import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout; import org.apache.maven.artifact.resolver.ArtifactResolver; import org.apache.maven.execution.MavenProjectSession; +import org.apache.maven.lifecycle.mapping.LifecycleMapping; import org.apache.maven.model.Build; import org.apache.maven.model.Extension; import org.apache.maven.model.Model; @@ -102,7 +104,10 @@ public class DefaultExtensionManagerTest null, null ) ); - DefaultArtifactRepository localRepository = new DefaultArtifactRepository("local", localRepo.getAbsolutePath(), new DefaultRepositoryLayout() ); + DefaultArtifactRepository localRepository = new DefaultArtifactRepository( + "local", + localRepo.getAbsolutePath(), + new DefaultRepositoryLayout() ); localRepository.setBasedir( localRepo.getAbsolutePath() ); ExtensionManager mgr = newDefaultExtensionManager(); @@ -115,7 +120,8 @@ public class DefaultExtensionManagerTest model.getArtifactId(), model.getVersion() ) ); - List compList = getContainer().getComponentDescriptorList( ArtifactFactory.ROLE, projectSession.getProjectRealm() ); + List compList = getContainer().getComponentDescriptorList( ArtifactFactory.ROLE, + projectSession.getProjectRealm() ); System.out.println( "Got: " + compList ); @@ -127,12 +133,69 @@ public class DefaultExtensionManagerTest getContainer().setLookupRealm( oldRealm ); } + public void test_addExtension_usingModel_ShouldLoadCustomLifecycleMappingAndArtifactHandler() + throws Exception + { + File remoteRepoDir = findRemoteRepositoryDirectory(); + File localRepo = createTempDir(); + + Model model = createModel( "org.test", "artifact-name", "1" ); + Extension ext = addExtension( model, "org.apache.maven.core.test", "test-lifecycle-and-artifactHandler", "1" ); + + List remoteRepositories = new ArrayList(); + remoteRepositories.add( repoFactory.createArtifactRepository( "central", + remoteRepoDir.toURI() + .toURL() + .toExternalForm(), + "default", + null, + null ) ); + + DefaultArtifactRepository localRepository = new DefaultArtifactRepository( + "local", + localRepo.getAbsolutePath(), + new DefaultRepositoryLayout() ); + localRepository.setBasedir( localRepo.getAbsolutePath() ); + + ExtensionManager mgr = newDefaultExtensionManager(); + + Map projectSessions = new HashMap(); + + mgr.addExtension( ext, model, remoteRepositories, localRepository, projectSessions ); + + MavenProjectSession projectSession = (MavenProjectSession) projectSessions.get( MavenProjectSession.createProjectId( model.getGroupId(), + model.getArtifactId(), + model.getVersion() ) ); + + List lcCompList = getContainer().getComponentDescriptorList( LifecycleMapping.ROLE, + projectSession.getProjectRealm() ); + + System.out.println( "Got lifecyle mappings: " + lcCompList ); + + List ahCompList = getContainer().getComponentDescriptorList( ArtifactHandler.ROLE, + projectSession.getProjectRealm() ); + + System.out.println( "Got artifact handlers: " + ahCompList ); + + ClassRealm oldRealm = getContainer().setLookupRealm( projectSession.getProjectRealm() ); + + LifecycleMapping lcResult = (LifecycleMapping) lookup( LifecycleMapping.ROLE, "test" ); + assertNotNull( lcResult ); + + ArtifactHandler ahResult = (ArtifactHandler) lookup( ArtifactHandler.ROLE, "test" ); + assertNotNull( ahResult ); + + getContainer().setLookupRealm( oldRealm ); + } + private ExtensionManager newDefaultExtensionManager() { - DefaultExtensionManager mgr = new DefaultExtensionManager( factory, resolver, metadataSource, - container, filterManager, wagonManager ); + DefaultExtensionManager mgr = new DefaultExtensionManager( factory, resolver, + metadataSource, container, + filterManager, wagonManager ); - Logger logger = getContainer().getLoggerManager().getLoggerForComponent( DefaultExtensionManager.class.getName() ); + Logger logger = getContainer().getLoggerManager() + .getLoggerForComponent( DefaultExtensionManager.class.getName() ); mgr.enableLogging( logger ); diff --git a/maven-core/src/test/repository-projects/test-lifecycle-and-artifactHandler/pom.xml b/maven-core/src/test/repository-projects/test-lifecycle-and-artifactHandler/pom.xml new file mode 100644 index 0000000000..d9e4cde9a1 --- /dev/null +++ b/maven-core/src/test/repository-projects/test-lifecycle-and-artifactHandler/pom.xml @@ -0,0 +1,44 @@ + + 4.0.0 + org.apache.maven.core.test + test-lifecycle-and-artifactHandler + jar + 1 + test-lifecycle-and-artifactHandler + + + + + maven-assembly-plugin + 2.2-beta-2-SNAPSHOT + + + repo-assembly + package + + single + + + + repo.xml + + test-extension + true + ${pom.basedir}/../../resources/org/apache/maven/extension + true + + + + + + + + + + dummy + file:///tmp/dummy-repo + + + + diff --git a/maven-core/src/test/repository-projects/test-lifecycle-and-artifactHandler/repo.xml b/maven-core/src/test/repository-projects/test-lifecycle-and-artifactHandler/repo.xml new file mode 100644 index 0000000000..b73a929225 --- /dev/null +++ b/maven-core/src/test/repository-projects/test-lifecycle-and-artifactHandler/repo.xml @@ -0,0 +1,22 @@ + + repo + + dir + + false + + + runtime + / + + + + + target + /org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1 + + test-lifecycle-and-artifactHandler* + + + + \ No newline at end of file diff --git a/maven-core/src/test/repository-projects/test-lifecycle-and-artifactHandler/src/main/resources/META-INF/plexus/components.xml b/maven-core/src/test/repository-projects/test-lifecycle-and-artifactHandler/src/main/resources/META-INF/plexus/components.xml new file mode 100644 index 0000000000..09e3ad6b8e --- /dev/null +++ b/maven-core/src/test/repository-projects/test-lifecycle-and-artifactHandler/src/main/resources/META-INF/plexus/components.xml @@ -0,0 +1,31 @@ + + + + org.apache.maven.artifact.handler.ArtifactHandler + test + org.apache.maven.artifact.handler.DefaultArtifactHandler + + test + jar + java + true + + + + org.apache.maven.lifecycle.mapping.LifecycleMapping + test + org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping + + + + default + + org.apache.maven.plugins:maven-install-plugin:install + org.apache.maven.plugins:maven-deploy-plugin:deploy + + + + + + + diff --git a/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.jar b/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.jar new file mode 100644 index 0000000000..04fe384696 Binary files /dev/null and b/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.jar differ diff --git a/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom b/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom new file mode 100644 index 0000000000..d9e4cde9a1 --- /dev/null +++ b/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom @@ -0,0 +1,44 @@ + + 4.0.0 + org.apache.maven.core.test + test-lifecycle-and-artifactHandler + jar + 1 + test-lifecycle-and-artifactHandler + + + + + maven-assembly-plugin + 2.2-beta-2-SNAPSHOT + + + repo-assembly + package + + single + + + + repo.xml + + test-extension + true + ${pom.basedir}/../../resources/org/apache/maven/extension + true + + + + + + + + + + dummy + file:///tmp/dummy-repo + + + + diff --git a/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom.md5 b/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom.md5 new file mode 100644 index 0000000000..01d5194202 --- /dev/null +++ b/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom.md5 @@ -0,0 +1 @@ +7f10427af029d20cbea57c21d1aec65e \ No newline at end of file diff --git a/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom.sha1 b/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom.sha1 new file mode 100644 index 0000000000..dac1e45a9d --- /dev/null +++ b/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom.sha1 @@ -0,0 +1 @@ +ed98c808239aefb0ec51a8b9e96f191da7fd92e6 \ No newline at end of file diff --git a/maven-project/src/main/java/org/apache/maven/profiles/build/DefaultProfileAdvisor.java b/maven-project/src/main/java/org/apache/maven/profiles/build/DefaultProfileAdvisor.java index 4c01e4f0ac..fe5d7ddbea 100644 --- a/maven-project/src/main/java/org/apache/maven/profiles/build/DefaultProfileAdvisor.java +++ b/maven-project/src/main/java/org/apache/maven/profiles/build/DefaultProfileAdvisor.java @@ -66,11 +66,11 @@ public class DefaultProfileAdvisor private Logger logger; - public List applyActivatedProfiles( Model model, File pomFile, List explicitlyActiveIds, List explicitlyInactiveIds ) + public List applyActivatedProfiles( Model model, File pomFile, List explicitlyActiveIds, List explicitlyInactiveIds, boolean useProfilesXml ) throws ProjectBuildingException { logger.debug( "Building profile manager for model: " + model.getId() + " with pom file: " + pomFile ); - ProfileManager profileManager = buildProfileManager( model, pomFile, explicitlyActiveIds, explicitlyInactiveIds ); + ProfileManager profileManager = buildProfileManager( model, pomFile, explicitlyActiveIds, explicitlyInactiveIds, useProfilesXml ); return applyActivatedProfiles( model, pomFile, profileManager ); } @@ -127,7 +127,7 @@ public class DefaultProfileAdvisor return activeProfiles; } - private ProfileManager buildProfileManager( Model model, File pomFile, List explicitlyActiveIds, List explicitlyInactiveIds ) + private ProfileManager buildProfileManager( Model model, File pomFile, List explicitlyActiveIds, List explicitlyInactiveIds, boolean useProfilesXml ) throws ProjectBuildingException { ProfileManager profileManager = new DefaultProfileManager( container ); @@ -138,7 +138,7 @@ public class DefaultProfileAdvisor profileManager.addProfiles( model.getProfiles() ); - if ( pomFile != null ) + if ( useProfilesXml && ( pomFile != null ) ) { loadExternalProjectProfiles( profileManager, model, pomFile ); } @@ -198,10 +198,11 @@ public class DefaultProfileAdvisor } public LinkedHashSet getArtifactRepositoriesFromActiveProfiles( Model model, File pomFile, - List explicitlyActiveIds, List explicitlyInactiveIds ) + List explicitlyActiveIds, List explicitlyInactiveIds, + boolean useProfilesXml ) throws ProjectBuildingException { - ProfileManager profileManager = buildProfileManager( model, pomFile, explicitlyActiveIds, explicitlyInactiveIds ); + ProfileManager profileManager = buildProfileManager( model, pomFile, explicitlyActiveIds, explicitlyInactiveIds, useProfilesXml ); return getArtifactRepositoriesFromActiveProfiles( profileManager, pomFile, model.getId() ); } diff --git a/maven-project/src/main/java/org/apache/maven/profiles/build/ProfileAdvisor.java b/maven-project/src/main/java/org/apache/maven/profiles/build/ProfileAdvisor.java index 7b19b29e1e..5ff39cbedf 100644 --- a/maven-project/src/main/java/org/apache/maven/profiles/build/ProfileAdvisor.java +++ b/maven-project/src/main/java/org/apache/maven/profiles/build/ProfileAdvisor.java @@ -37,16 +37,28 @@ public interface ProfileAdvisor String ROLE = ProfileAdvisor.class.getName(); - LinkedHashSet getArtifactRepositoriesFromActiveProfiles( ProfileManager profileManager, File pomFile, String modelId ) + LinkedHashSet getArtifactRepositoriesFromActiveProfiles( ProfileManager profileManager, + File pomFile, + String modelId ) throws ProjectBuildingException; - LinkedHashSet getArtifactRepositoriesFromActiveProfiles( Model model, File pomFile, List explicitlyActiveIds, List explicitlyInactiveIds ) + LinkedHashSet getArtifactRepositoriesFromActiveProfiles( Model model, + File pomFile, + List explicitlyActiveIds, + List explicitlyInactiveIds, + boolean useProfilesXml ) throws ProjectBuildingException; - List applyActivatedProfiles( Model model, File pomFile, List explicitlyActiveIds, List explicitlyInactiveIds ) + List applyActivatedProfiles( Model model, + File pomFile, + List explicitlyActiveIds, + List explicitlyInactiveIds, + boolean useProfilesXml ) throws ProjectBuildingException; - List applyActivatedExternalProfiles( Model model, File pomFile, ProfileManager externalProfileManager ) + List applyActivatedExternalProfiles( Model model, + File pomFile, + ProfileManager externalProfileManager ) throws ProjectBuildingException; } 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 073c6268fe..40c18523dc 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 @@ -209,7 +209,7 @@ public class DefaultMavenProjectBuilder Model model = findModelFromRepository( artifact, remoteArtifactRepositories, localRepository ); - return buildInternal( "Artifact [" + artifact + "]", model, localRepository, remoteArtifactRepositories, null, null, false ); + return buildInternal( "Artifact [" + artifact + "]", model, localRepository, remoteArtifactRepositories, null, null, false, false ); } private MavenProject superProject; @@ -403,7 +403,8 @@ public class DefaultMavenProjectBuilder buildArtifactRepositories( getSuperModel() ), projectDescriptor, profileManager, - STRICT_MODEL_PARSING ); + STRICT_MODEL_PARSING, + true ); return project; } @@ -531,7 +532,7 @@ public class DefaultMavenProjectBuilder List parentSearchRepositories, File projectDescriptor, ProfileManager externalProfileManager, - boolean strict ) + boolean strict, boolean validProfilesXmlLocation ) throws ProjectBuildingException { Model superModel = getSuperModel(); @@ -567,7 +568,7 @@ public class DefaultMavenProjectBuilder explicitlyInactive = Collections.EMPTY_LIST; } - superProject.setActiveProfiles( profileAdvisor.applyActivatedProfiles( superModel, projectDescriptor, explicitlyActive, explicitlyInactive ) ); + superProject.setActiveProfiles( profileAdvisor.applyActivatedProfiles( superModel, projectDescriptor, explicitlyActive, explicitlyInactive, validProfilesXmlLocation ) ); //noinspection CollectionDeclaredAsConcreteClass LinkedList lineage = new LinkedList(); @@ -575,7 +576,8 @@ public class DefaultMavenProjectBuilder LinkedHashSet aggregatedRemoteWagonRepositories = collectInitialRepositories( model, superModel, parentSearchRepositories, projectDescriptor, explicitlyActive, - explicitlyInactive ); + explicitlyInactive, + validProfilesXmlLocation ); Model originalModel = ModelUtils.cloneModel( model ); @@ -583,7 +585,7 @@ public class DefaultMavenProjectBuilder try { - project = assembleLineage( model, lineage, localRepository, projectDescriptor, aggregatedRemoteWagonRepositories, externalProfileManager, strict ); + project = assembleLineage( model, lineage, localRepository, projectDescriptor, aggregatedRemoteWagonRepositories, externalProfileManager, strict, validProfilesXmlLocation ); } catch ( InvalidRepositoryException e ) { @@ -704,14 +706,15 @@ public class DefaultMavenProjectBuilder List parentSearchRepositories, File pomFile, List explicitlyActive, - List explicitlyInactive ) + List explicitlyInactive, + boolean validProfilesXmlLocation ) throws ProjectBuildingException { LinkedHashSet collected = new LinkedHashSet(); - collectInitialRepositoriesFromModel( collected, model, pomFile, explicitlyActive, explicitlyInactive ); + collectInitialRepositoriesFromModel( collected, model, pomFile, explicitlyActive, explicitlyInactive, validProfilesXmlLocation ); - collectInitialRepositoriesFromModel( collected, superModel, null, explicitlyActive, explicitlyInactive ); + collectInitialRepositoriesFromModel( collected, superModel, null, explicitlyActive, explicitlyInactive, validProfilesXmlLocation ); if ( ( parentSearchRepositories != null ) && !parentSearchRepositories.isEmpty() ) { @@ -725,10 +728,11 @@ public class DefaultMavenProjectBuilder Model model, File pomFile, List explicitlyActive, - List explicitlyInactive ) + List explicitlyInactive, + boolean validProfilesXmlLocation ) throws ProjectBuildingException { - Set reposFromProfiles = profileAdvisor.getArtifactRepositoriesFromActiveProfiles( model, pomFile, explicitlyActive, explicitlyInactive ); + Set reposFromProfiles = profileAdvisor.getArtifactRepositoriesFromActiveProfiles( model, pomFile, explicitlyActive, explicitlyInactive, validProfilesXmlLocation ); if ( ( reposFromProfiles != null ) && !reposFromProfiles.isEmpty() ) { @@ -896,6 +900,7 @@ public class DefaultMavenProjectBuilder } /** + * @param validProfilesXmlLocation * @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. @@ -906,12 +911,12 @@ public class DefaultMavenProjectBuilder File pomFile, Set aggregatedRemoteWagonRepositories, ProfileManager externalProfileManager, - boolean strict ) + boolean strict, boolean validProfilesXmlLocation ) throws ProjectBuildingException, InvalidRepositoryException { ModelLineage modelLineage = new DefaultModelLineage(); - modelLineage.setOrigin( model, pomFile, new ArrayList( aggregatedRemoteWagonRepositories ) ); + modelLineage.setOrigin( model, pomFile, new ArrayList( aggregatedRemoteWagonRepositories ), validProfilesXmlLocation ); modelLineageBuilder.resumeBuildingModelLineage( modelLineage, localRepository, externalProfileManager, !strict ); @@ -951,7 +956,7 @@ public class DefaultMavenProjectBuilder projectContext.store( buildContextManager ); project.setActiveProfiles( profileAdvisor.applyActivatedProfiles( currentModel, currentPom, explicitlyActive, - explicitlyInactive ) ); + explicitlyInactive, validProfilesXmlLocation ) ); if ( lastProject != null ) { diff --git a/maven-project/src/main/java/org/apache/maven/project/build/model/DefaultModelLineage.java b/maven-project/src/main/java/org/apache/maven/project/build/model/DefaultModelLineage.java index 68760af3b0..702248e67f 100644 --- a/maven-project/src/main/java/org/apache/maven/project/build/model/DefaultModelLineage.java +++ b/maven-project/src/main/java/org/apache/maven/project/build/model/DefaultModelLineage.java @@ -39,14 +39,14 @@ public class DefaultModelLineage /** * @see org.apache.maven.project.build.model.ModelLineage#addParent(org.apache.maven.model.Model, java.io.File, java.util.List) */ - public void addParent( Model model, File pomFile, List artifactRepositories ) + public void addParent( Model model, File pomFile, List artifactRepositories, boolean validProfilesXmlLocation ) { if ( tuples.isEmpty() ) { throw new IllegalStateException( "You must call setOrigin(..) before adding a parent to the lineage." ); } - tuples.add( new ModelLineageTuple( model, pomFile, artifactRepositories ) ); + tuples.add( new ModelLineageTuple( model, pomFile, artifactRepositories, validProfilesXmlLocation ) ); } /** @@ -264,6 +264,18 @@ public class DefaultModelLineage return tuple.model; } + public boolean isDeepestAncestorUsingProfilesXml() + { + if ( tuples.isEmpty() ) + { + return false; + } + + ModelLineageTuple tuple = (ModelLineageTuple) tuples.get( tuples.size() - 1 ); + + return tuple.validProfilesXmlLocation; + } + /** * @see org.apache.maven.project.build.model.ModelLineage#modelIterator() */ @@ -292,14 +304,14 @@ public class DefaultModelLineage }; } - public void setOrigin( Model model, File pomFile, List artifactRepositories ) + public void setOrigin( Model model, File pomFile, List artifactRepositories, boolean validProfilesXmlLocation ) { if ( !tuples.isEmpty() ) { throw new IllegalStateException( "Origin already set; you must use addParent(..) for successive additions to the lineage." ); } - tuples.add( new ModelLineageTuple( model, pomFile, artifactRepositories ) ); + tuples.add( new ModelLineageTuple( model, pomFile, artifactRepositories, validProfilesXmlLocation ) ); } /** @@ -318,16 +330,20 @@ public class DefaultModelLineage private List remoteRepositories; + private final boolean validProfilesXmlLocation; + private ModelLineageTuple( Model model ) { this.model = model; + validProfilesXmlLocation = false; } - private ModelLineageTuple( Model model, File file, List remoteRepositories ) + private ModelLineageTuple( Model model, File file, List remoteRepositories, boolean validProfilesXmlLocation ) { this.model = model; this.file = file; this.remoteRepositories = remoteRepositories; + this.validProfilesXmlLocation = validProfilesXmlLocation; } public boolean equals( Object other ) 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 c9e1730ea6..808fc40221 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 @@ -88,7 +88,7 @@ public class DefaultModelLineageBuilder * @see org.apache.maven.project.build.model.ModelLineageBuilder#buildModelLineage(java.io.File, org.apache.maven.artifact.repository.ArtifactRepository, java.util.List) */ public ModelLineage buildModelLineage( File pom, ArtifactRepository localRepository, List remoteRepositories, - ProfileManager profileManager, boolean allowStubs ) + ProfileManager profileManager, boolean allowStubs, boolean validProfilesXmlLocation ) throws ProjectBuildingException { ProjectBuildCache projectBuildCache = ProjectBuildCache.read( buildContextManager ); @@ -98,20 +98,20 @@ public class DefaultModelLineageBuilder List currentRemoteRepositories = remoteRepositories == null ? new ArrayList() : new ArrayList( remoteRepositories ); - ModelAndFile current = new ModelAndFile( readModel( pom, projectBuildCache ), pom ); + ModelAndFile current = new ModelAndFile( readModel( pom, projectBuildCache ), pom, validProfilesXmlLocation ); do { if ( lineage.size() == 0 ) { - lineage.setOrigin( current.model, current.file, currentRemoteRepositories ); + lineage.setOrigin( current.model, current.file, currentRemoteRepositories, current.validProfilesXmlLocation ); } else { - lineage.addParent( current.model, current.file, currentRemoteRepositories ); + lineage.addParent( current.model, current.file, currentRemoteRepositories, current.validProfilesXmlLocation ); } - currentRemoteRepositories = updateRepositorySet( current.model, currentRemoteRepositories, current.file, profileManager ); + currentRemoteRepositories = updateRepositorySet( current.model, currentRemoteRepositories, current.file, profileManager, current.validProfilesXmlLocation ); current = resolveParentPom( current, currentRemoteRepositories, localRepository, projectBuildCache, allowStubs ); } @@ -138,16 +138,16 @@ public class DefaultModelLineageBuilder currentRemoteRepositories = new ArrayList(); } - ModelAndFile current = new ModelAndFile( lineage.getDeepestAncestorModel(), lineage.getDeepestAncestorFile() ); + ModelAndFile current = new ModelAndFile( lineage.getDeepestAncestorModel(), lineage.getDeepestAncestorFile(), lineage.isDeepestAncestorUsingProfilesXml() ); // use the above information to re-bootstrap the resolution chain... current = resolveParentPom( current, currentRemoteRepositories, localRepository, projectBuildCache, allowStubs ); while ( current != null ) { - lineage.addParent( current.model, current.file, currentRemoteRepositories ); + lineage.addParent( current.model, current.file, currentRemoteRepositories, current.validProfilesXmlLocation ); - currentRemoteRepositories = updateRepositorySet( current.model, currentRemoteRepositories, current.file, profileManager ); + currentRemoteRepositories = updateRepositorySet( current.model, currentRemoteRepositories, current.file, profileManager, current.validProfilesXmlLocation ); current = resolveParentPom( current, currentRemoteRepositories, localRepository, projectBuildCache, allowStubs ); } @@ -225,7 +225,7 @@ public class DefaultModelLineageBuilder * @param profileManager */ private List updateRepositorySet( Model model, List oldArtifactRepositories, File pomFile, - ProfileManager externalProfileManager ) + ProfileManager externalProfileManager, boolean useProfilesXml ) throws ProjectBuildingException { List repositories = model.getRepositories(); @@ -241,7 +241,7 @@ public class DefaultModelLineageBuilder List lastRemoteRepos = oldArtifactRepositories; List remoteRepos = mavenTools.buildArtifactRepositories( repositories ); - loadActiveProfileRepositories( remoteRepos, model, externalProfileManager, projectDir ); + loadActiveProfileRepositories( remoteRepos, model, externalProfileManager, projectDir, useProfilesXml ); artifactRepositories = new LinkedHashSet( remoteRepos.size() + oldArtifactRepositories.size() ); @@ -259,7 +259,7 @@ public class DefaultModelLineageBuilder } private void loadActiveProfileRepositories( List repositories, Model model, ProfileManager profileManager, - File pomFile ) + File pomFile, boolean useProfilesXml ) throws ProjectBuildingException { List explicitlyActive; @@ -280,7 +280,8 @@ public class DefaultModelLineageBuilder profileRepos.addAll( profileAdvisor.getArtifactRepositoriesFromActiveProfiles( model, pomFile, explicitlyActive, - explicitlyInactive ) ); + explicitlyInactive, + useProfilesXml ) ); if ( !profileRepos.isEmpty() ) { @@ -316,11 +317,14 @@ public class DefaultModelLineageBuilder parentPomFile = resolveParentWithRelativePath( modelParent, modelPomFile ); } + boolean isResolved = false; + if ( parentPomFile == null ) { try { parentPomFile = resolveParentFromRepositories( modelParent, localRepository, remoteRepositories, model.getId() ); + isResolved = true; } catch( ProjectBuildingException e ) { @@ -348,7 +352,10 @@ public class DefaultModelLineageBuilder parent.setArtifactId( modelParent.getArtifactId() ); parent.setVersion( modelParent.getVersion() ); - result = new ModelAndFile( parent, parentPomFile ); + // we act as if the POM was resolved from the repository, + // for the purposes of external profiles.xml files... + // that's what the last parameter is about. + result = new ModelAndFile( parent, parentPomFile, false ); } else { @@ -358,7 +365,7 @@ public class DefaultModelLineageBuilder else { Model parent = readModel( parentPomFile ); - result = new ModelAndFile( parent, parentPomFile ); + result = new ModelAndFile( parent, parentPomFile, !isResolved ); } } @@ -477,11 +484,13 @@ public class DefaultModelLineageBuilder { private final Model model; private final File file; + private final boolean validProfilesXmlLocation; - ModelAndFile( Model model, File file ) + ModelAndFile( Model model, File file, boolean validProfilesXmlLocation ) { this.model = model; this.file = file; + this.validProfilesXmlLocation = validProfilesXmlLocation; } } diff --git a/maven-project/src/main/java/org/apache/maven/project/build/model/ModelLineage.java b/maven-project/src/main/java/org/apache/maven/project/build/model/ModelLineage.java index 95f35aa485..721817a78d 100644 --- a/maven-project/src/main/java/org/apache/maven/project/build/model/ModelLineage.java +++ b/maven-project/src/main/java/org/apache/maven/project/build/model/ModelLineage.java @@ -41,6 +41,12 @@ public interface ModelLineage */ Model getDeepestAncestorModel(); + /** + * Retrieve the flag telling whether discovery of a profiles.xml file is appropriate + * for the deepest model in this lineage. + */ + boolean isDeepestAncestorUsingProfilesXml(); + /** * Retrieve the POM file for the deepest ancestor which has been resolved so far in this * lineage. @@ -80,7 +86,7 @@ public interface ModelLineage * * @throws IllegalStateException When the originating POM information has already been set. */ - void setOrigin( Model model, File pomFile, List artifactRepositories ); + void setOrigin( Model model, File pomFile, List artifactRepositories, boolean validProfilesXmlLocation ); /** * Add a parent model, along with its file and the repositories used to resolve it. @@ -88,7 +94,7 @@ public interface ModelLineage * * @throws IllegalStateException When the originating POM information has not yet been set. */ - void addParent( Model model, File pomFile, List artifactRepositories ); + void addParent( Model model, File pomFile, List artifactRepositories, boolean validProfilesXmlLocation ); /** * Retrieve the models in this lineage, with the deepest parent at the zero index, and the current 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 df1fdc2a54..6c29e979e1 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 @@ -54,7 +54,7 @@ public interface ModelLineageBuilder * a parent-POM cannot be resolved. */ ModelLineage buildModelLineage( File pom, ArtifactRepository localRepository, List remoteRepositories, - ProfileManager profileManager, boolean allowStubs ) + ProfileManager profileManager, boolean allowStubs, boolean validProfilesXmlLocation ) throws ProjectBuildingException; /** diff --git a/maven-project/src/test/java/org/apache/maven/project/build/model/AbstractModelLineageTest.java b/maven-project/src/test/java/org/apache/maven/project/build/model/AbstractModelLineageTest.java index ebadc30e14..8722938871 100644 --- a/maven-project/src/test/java/org/apache/maven/project/build/model/AbstractModelLineageTest.java +++ b/maven-project/src/test/java/org/apache/maven/project/build/model/AbstractModelLineageTest.java @@ -45,7 +45,7 @@ public abstract class AbstractModelLineageTest try { - ml.addParent( new Model(), null, null ); + ml.addParent( new Model(), null, null, false ); fail( "Should throw IllegalStateException when setOrigin(..) is not called first." ); } @@ -61,13 +61,13 @@ public abstract class AbstractModelLineageTest assertEquals( 0, ml.size() ); - ml.setOrigin( new Model(), null, null ); + ml.setOrigin( new Model(), null, null, false ); assertEquals( 1, ml.size() ); try { - ml.setOrigin( new Model(), null, null ); + ml.setOrigin( new Model(), null, null, false ); fail( "Should throw IllegalStateException when setOrigin(..) called multiple times." ); } @@ -83,7 +83,7 @@ public abstract class AbstractModelLineageTest assertEquals( 0, ml.size() ); - ml.setOrigin( new Model(), null, null ); + ml.setOrigin( new Model(), null, null, false ); assertEquals( 1, ml.size() ); } @@ -106,7 +106,7 @@ public abstract class AbstractModelLineageTest File fOne = File.createTempFile( "ModelLineageTest.modelLineageIterator-test.", "" ); fOne.deleteOnExit(); - ml.setOrigin( mOne, fOne, null ); + ml.setOrigin( mOne, fOne, null, false ); String gTwo = "group2"; String aTwo = "artifact2"; @@ -120,8 +120,8 @@ public abstract class AbstractModelLineageTest File fTwo = File.createTempFile( "ModelLineageTest.fileIterator-test.", "" ); fTwo.deleteOnExit(); - - ml.addParent( mTwo, fTwo, null ); + + ml.addParent( mTwo, fTwo, null, false ); ModelLineageIterator it = ml.lineageIterator(); @@ -150,7 +150,7 @@ public abstract class AbstractModelLineageTest mOne.setArtifactId( aOne ); mOne.setVersion( vOne ); - ml.setOrigin( mOne, null, null ); + ml.setOrigin( mOne, null, null, false ); String gTwo = "group2"; String aTwo = "artifact2"; @@ -162,7 +162,7 @@ public abstract class AbstractModelLineageTest mOne.setArtifactId( aTwo ); mOne.setVersion( vTwo ); - ml.addParent( mTwo, null, null ); + ml.addParent( mTwo, null, null, false ); Iterator it = ml.modelIterator(); @@ -181,20 +181,20 @@ public abstract class AbstractModelLineageTest File fOne = File.createTempFile( "ModelLineageTest.fileIterator-test.", "" ); fOne.deleteOnExit(); - ml.setOrigin( new Model(), fOne, null ); + ml.setOrigin( new Model(), fOne, null, false ); File fTwo = File.createTempFile( "ModelLineageTest.fileIterator-test.", "" ); fTwo.deleteOnExit(); - ml.addParent( new Model(), fTwo, null ); + ml.addParent( new Model(), fTwo, null, false ); Iterator it = ml.fileIterator(); assertTrue( it.hasNext() ); - assertEquals( fOne, (File) it.next() ); + assertEquals( fOne, it.next() ); assertTrue( it.hasNext() ); - assertEquals( fTwo, (File) it.next() ); + assertEquals( fTwo, it.next() ); } public void testArtifactRepositoryListIterator_ShouldAddTwoParentsAndIterateInFIFOOrder() @@ -205,11 +205,11 @@ public abstract class AbstractModelLineageTest ArtifactRepository arOne = new DefaultArtifactRepository( "", "", layout ); - ml.setOrigin( new Model(), null, Collections.singletonList( arOne ) ); + ml.setOrigin( new Model(), null, Collections.singletonList( arOne ), false ); ArtifactRepository arTwo = new DefaultArtifactRepository( "", "", layout ); - ml.addParent( new Model(), null, Collections.singletonList( arTwo ) ); + ml.addParent( new Model(), null, Collections.singletonList( arTwo ), false ); Iterator it = ml.artifactRepositoryListIterator(); @@ -238,12 +238,12 @@ public abstract class AbstractModelLineageTest mOne.setArtifactId( aOne ); mOne.setVersion( vOne ); - ml.setOrigin( mOne, fOne, null ); + ml.setOrigin( mOne, fOne, null, false ); File fTwo = File.createTempFile( "ModelLineageTest.fileIterator-test.", "" ); fTwo.deleteOnExit(); - ml.addParent( new Model(), fTwo, null ); + ml.addParent( new Model(), fTwo, null, false ); Model retriever = new Model(); @@ -273,11 +273,11 @@ public abstract class AbstractModelLineageTest ArtifactRepository arOne = new DefaultArtifactRepository( "", "", layout ); - ml.setOrigin( mOne, null, Collections.singletonList( arOne ) ); + ml.setOrigin( mOne, null, Collections.singletonList( arOne ), false ); ArtifactRepository arTwo = new DefaultArtifactRepository( "", "", layout ); - ml.addParent( new Model(), null, Collections.singletonList( arTwo ) ); + ml.addParent( new Model(), null, Collections.singletonList( arTwo ), false ); Model retriever = new Model(); @@ -285,7 +285,7 @@ public abstract class AbstractModelLineageTest retriever.setArtifactId( aOne ); retriever.setVersion( vOne ); - assertSame( arOne, ( (List) ml.getArtifactRepositories( retriever ) ).get( 0 ) ); + assertSame( arOne, ( ml.getArtifactRepositories( retriever ) ).get( 0 ) ); } public void testSetOriginAndGetOriginatingModel() @@ -297,7 +297,7 @@ public abstract class AbstractModelLineageTest ModelLineage ml = newModelLineage(); - ml.setOrigin( model, null, null ); + ml.setOrigin( model, null, null, false ); assertEquals( model.getId(), ml.getOriginatingModel().getId() ); } @@ -310,7 +310,7 @@ public abstract class AbstractModelLineageTest File pomFile = File.createTempFile( "ModelLineage.test.", ".pom" ); pomFile.deleteOnExit(); - ml.setOrigin( null, pomFile, null ); + ml.setOrigin( null, pomFile, null, false ); assertEquals( pomFile, ml.getOriginatingPOMFile() ); } @@ -333,7 +333,7 @@ public abstract class AbstractModelLineageTest ArtifactRepository arOne = new DefaultArtifactRepository( "", "", layout ); - ml.setOrigin( mOne, null, Collections.singletonList( arOne ) ); + ml.setOrigin( mOne, null, Collections.singletonList( arOne ), false ); assertSame( arOne, ml.getOriginatingArtifactRepositoryList().get( 0 ) ); } @@ -352,7 +352,7 @@ public abstract class AbstractModelLineageTest mOne.setArtifactId( aOne ); mOne.setVersion( vOne ); - ml.setOrigin( mOne, null, null ); + ml.setOrigin( mOne, null, null, false ); String gTwo = "group2"; String aTwo = "artifact2"; @@ -364,7 +364,7 @@ public abstract class AbstractModelLineageTest mOne.setArtifactId( aTwo ); mOne.setVersion( vTwo ); - ml.addParent( mTwo, null, null ); + ml.addParent( mTwo, null, null, false ); Iterator it = ml.getModelsInDescendingOrder().iterator(); @@ -383,20 +383,20 @@ public abstract class AbstractModelLineageTest File fOne = File.createTempFile( "ModelLineageTest.fileIterator-test.", "" ); fOne.deleteOnExit(); - ml.setOrigin( new Model(), fOne, null ); + ml.setOrigin( new Model(), fOne, null, false ); File fTwo = File.createTempFile( "ModelLineageTest.fileIterator-test.", "" ); fTwo.deleteOnExit(); - ml.addParent( new Model(), fTwo, null ); + ml.addParent( new Model(), fTwo, null, false ); Iterator it = ml.getFilesInDescendingOrder().iterator(); assertTrue( it.hasNext() ); - assertEquals( fTwo, (File) it.next() ); + assertEquals( fTwo, it.next() ); assertTrue( it.hasNext() ); - assertEquals( fOne, (File) it.next() ); + assertEquals( fOne, it.next() ); } public void testGetArtifactRepositoryListsInDescendingOrder_ShouldAddTwoAndRetrieveInLIFOOrder() @@ -407,11 +407,11 @@ public abstract class AbstractModelLineageTest ArtifactRepository arOne = new DefaultArtifactRepository( "", "", layout ); - ml.setOrigin( new Model(), null, Collections.singletonList( arOne ) ); + ml.setOrigin( new Model(), null, Collections.singletonList( arOne ), false ); ArtifactRepository arTwo = new DefaultArtifactRepository( "", "", layout ); - ml.addParent( new Model(), null, Collections.singletonList( arTwo ) ); + ml.addParent( new Model(), null, Collections.singletonList( arTwo ), false ); Iterator it = ml.getArtifactRepositoryListsInDescendingOrder().iterator(); diff --git a/maven-project/src/test/java/org/apache/maven/project/build/model/DefaultModelLineageBuilderTest.java b/maven-project/src/test/java/org/apache/maven/project/build/model/DefaultModelLineageBuilderTest.java index 5bffc04177..cf76c4e37a 100644 --- a/maven-project/src/test/java/org/apache/maven/project/build/model/DefaultModelLineageBuilderTest.java +++ b/maven-project/src/test/java/org/apache/maven/project/build/model/DefaultModelLineageBuilderTest.java @@ -117,7 +117,7 @@ public class DefaultModelLineageBuilderTest } ModelLineage lineage = modelLineageBuilder.buildModelLineage( pomFile, null, null, null, - false ); + false, true ); assertEquals( 1, lineage.size() ); @@ -181,7 +181,7 @@ public class DefaultModelLineageBuilderTest ModelLineage lineage = modelLineageBuilder.buildModelLineage( currentPOM, localRepository, Collections.EMPTY_LIST, null, - false ); + false, true ); assertEquals( 3, lineage.size() ); @@ -230,7 +230,7 @@ public class DefaultModelLineageBuilderTest ModelLineage lineage = modelLineageBuilder.buildModelLineage( currentPOM, localRepository, Collections.EMPTY_LIST, null, - true ); + true, true ); assertEquals( 2, lineage.size() ); @@ -318,7 +318,7 @@ public class DefaultModelLineageBuilderTest currentPOM, localRepository, Collections.singletonList( remoteRepository ), - null, false ); + null, false, true ); assertEquals( 3, lineage.size() ); @@ -379,7 +379,7 @@ public class DefaultModelLineageBuilderTest ModelLineage lineage = modelLineageBuilder.buildModelLineage( currentPOM, localRepository, Collections.EMPTY_LIST, null, - false ); + false, true ); assertEquals( 2, lineage.size() ); @@ -445,7 +445,7 @@ public class DefaultModelLineageBuilderTest ModelLineage lineage = modelLineageBuilder.buildModelLineage( currentPOM, localRepository, Collections.EMPTY_LIST, profileManager, - false ); + false, true ); assertEquals( 2, lineage.size() ); @@ -535,7 +535,7 @@ public class DefaultModelLineageBuilderTest // 7. build the lineage. ModelLineage lineage = modelLineageBuilder.buildModelLineage( currentPOM, null, Collections.EMPTY_LIST, null, - false ); + false, true ); assertEquals( 2, lineage.size() );