From 16c064c4bcd3c715a574bf47810673532b15342c Mon Sep 17 00:00:00 2001 From: John Dennis Casey Date: Wed, 24 Oct 2007 21:14:27 +0000 Subject: [PATCH] Cleaning up extension and plugin realms for a project once the build completes. git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@588029 13f79535-47bb-0310-9956-ffa450edef68 --- build.properties | 2 +- maven-core/pom.xml | 1 + .../java/org/apache/maven/DefaultMaven.java | 101 ++++++++++-------- .../maven/execution/MavenProjectSession.java | 55 ++++++++++ .../apache/maven/execution/MavenSession.java | 13 ++- .../maven/plugin/DefaultPluginManager.java | 25 ++++- .../apache/maven/embedder/MavenEmbedder.java | 15 ++- pom.xml | 2 +- 8 files changed, 159 insertions(+), 55 deletions(-) diff --git a/build.properties b/build.properties index 32b314d6c6..668a721856 100644 --- a/build.properties +++ b/build.properties @@ -16,7 +16,7 @@ # under the License. classworlds.version=1.2-alpha-10 -plexus.version=1.0-alpha-34 +plexus.version=1.0-alpha-35-SNAPSHOT plexus-utils.version=1.4.5 maven-artifact.version=3.0-SNAPSHOT commons-cli.version=1.0 diff --git a/maven-core/pom.xml b/maven-core/pom.xml index 5d888d0d27..c9663eb8c7 100644 --- a/maven-core/pom.xml +++ b/maven-core/pom.xml @@ -88,6 +88,7 @@ under the License. maven-plugin-api 2.1-SNAPSHOT + org.codehaus.plexus plexus-interactivity-api diff --git a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java index 4d9bce353e..13f426006c 100644 --- a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java +++ b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java @@ -192,59 +192,66 @@ public class DefaultMaven dispatcher, projectSessions ); - for ( Iterator i = request.getGoals().iterator(); i.hasNext(); ) - { - String goal = (String) i.next(); - - TaskValidationResult tvr = lifecycleExecutor.isTaskValid( goal, session, reactorManager.getTopLevelProject() ); - - if ( !tvr.isTaskValid() ) - { - result.addBuildFailureException( new InvalidTaskException( tvr ) ); - - return result; - } - } - - getLogger().info( "Scanning for projects..." ); - - if ( reactorManager.hasMultipleProjects() ) - { - getLogger().info( "Reactor build order: " ); - - for ( Iterator i = reactorManager.getSortedProjects().iterator(); i.hasNext(); ) - { - MavenProject project = (MavenProject) i.next(); - - getLogger().info( " " + project.getName() ); - } - } - - initializeBuildContext( request ); - try { - lifecycleExecutor.execute( - session, - reactorManager, - dispatcher ); - } - catch ( LifecycleExecutionException e ) - { - result.addLifecycleExecutionException( e ); + for ( Iterator i = request.getGoals().iterator(); i.hasNext(); ) + { + String goal = (String) i.next(); + + TaskValidationResult tvr = lifecycleExecutor.isTaskValid( goal, session, reactorManager.getTopLevelProject() ); + + if ( !tvr.isTaskValid() ) + { + result.addBuildFailureException( new InvalidTaskException( tvr ) ); + + return result; + } + } + + getLogger().info( "Scanning for projects..." ); + + if ( reactorManager.hasMultipleProjects() ) + { + getLogger().info( "Reactor build order: " ); + + for ( Iterator i = reactorManager.getSortedProjects().iterator(); i.hasNext(); ) + { + MavenProject project = (MavenProject) i.next(); + + getLogger().info( " " + project.getName() ); + } + } + + initializeBuildContext( request ); + + try + { + lifecycleExecutor.execute( + session, + reactorManager, + dispatcher ); + } + catch ( LifecycleExecutionException e ) + { + result.addLifecycleExecutionException( e ); + return result; + } + catch ( BuildFailureException e ) + { + result.addBuildFailureException( e ); + return result; + } + + result.setTopologicallySortedProjects( reactorManager.getSortedProjects() ); + + result.setProject( reactorManager.getTopLevelProject() ); + return result; } - catch ( BuildFailureException e ) + finally { - result.addBuildFailureException( e ); - return result; + session.dispose(); } - - result.setTopologicallySortedProjects( reactorManager.getSortedProjects() ); - - result.setProject( reactorManager.getTopLevelProject() ); - - return result; } /** 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 70cf4bfe77..5f7beffcbb 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 @@ -12,6 +12,7 @@ import org.codehaus.plexus.classworlds.realm.NoSuchRealmException; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; /** @@ -54,6 +55,40 @@ public class MavenProjectSession projectRealm = container.createComponentRealm( projectId, Collections.EMPTY_LIST ); } + public void dispose() + { + for ( Iterator it = componentRealms.values().iterator(); it.hasNext(); ) + { + ClassRealm realm = (ClassRealm) it.next(); + disposeRealm( realm ); + } + + disposeRealm( projectRealm ); + try + { + container.removeComponentRealm( projectRealm ); + } + catch( PlexusContainerException e ) + { + e.printStackTrace(); + } + + componentRealms.clear(); + projectRealm = null; + } + + private void disposeRealm( ClassRealm realm ) + { + try + { + realm.getWorld().disposeRealm( realm.getId() ); + } + catch ( NoSuchRealmException e ) + { + // impossible + } + } + public String getProjectId() { return projectId; @@ -66,12 +101,24 @@ public class MavenProjectSession public boolean containsExtensionRealm( Artifact extensionArtifact ) { + checkDisposed(); + String id = createExtensionRealmId( extensionArtifact ); return componentRealms.containsKey( id ); } + private void checkDisposed() + { + if ( projectRealm == null ) + { + throw new IllegalStateException( "MavenProjectSession for: " + projectId + " with hashcode: " + hashCode() + " has been disposed, and is no longer valid for use." ); + } + } + public boolean containsPluginRealm( Plugin plugin ) { + checkDisposed(); + String realmId = createPluginRealmId( ArtifactUtils.versionlessKey( plugin.getGroupId(), plugin.getArtifactId() ) ); return componentRealms.containsKey( realmId ); @@ -96,6 +143,8 @@ public class MavenProjectSession public ClassRealm createExtensionRealm( Artifact extensionArtifact ) throws DuplicateRealmException { + checkDisposed(); + String realmId = createExtensionRealmId( extensionArtifact ); ClassRealm extRealm = container.getContainerRealm().createChildRealm( realmId ); @@ -124,6 +173,8 @@ public class MavenProjectSession public ClassRealm getPluginRealm( Plugin plugin ) throws NoSuchRealmException { + checkDisposed(); + String realmId = createPluginRealmId( ArtifactUtils.versionlessKey( plugin.getGroupId(), plugin.getArtifactId() ) ); return projectRealm.getWorld().getRealm( realmId ); @@ -133,6 +184,8 @@ public class MavenProjectSession public ClassRealm createPluginRealm( Plugin plugin ) throws DuplicateRealmException { + checkDisposed(); + String realmId = createPluginRealmId( ArtifactUtils.versionlessKey( plugin.getGroupId(), plugin.getArtifactId() ) ); ClassRealm extRealm = projectRealm.createChildRealm( realmId ); @@ -150,6 +203,8 @@ public class MavenProjectSession public ClassRealm getPluginRealm( PluginDescriptor pd ) throws NoSuchRealmException { + checkDisposed(); + String realmId = createPluginRealmId( ArtifactUtils.versionlessKey( pd.getGroupId(), pd.getArtifactId() ) ); ClassRealm extRealm = projectRealm.getWorld().getRealm( realmId ); diff --git a/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java b/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java index d38ea4b4bc..fdfa6e69d5 100644 --- a/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java +++ b/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java @@ -29,6 +29,8 @@ import org.codehaus.plexus.PlexusContainerException; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -68,7 +70,16 @@ public class MavenSession this.reactorManager = reactorManager; - this.projectSessions = projectSessions; + this.projectSessions = projectSessions == null ? new HashMap() : projectSessions; + } + + public void dispose() + { + for ( Iterator it = projectSessions.values().iterator(); it.hasNext(); ) + { + MavenProjectSession session = (MavenProjectSession) it.next(); + session.dispose(); + } } // TODO: Figure out how/when we can shut down all the realms for extensions/plugins connected to each project session... 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 576d70e213..776441077b 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 @@ -664,7 +664,28 @@ public class DefaultPluginManager ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); - ClassRealm pluginRealm = pluginDescriptor.getClassRealm(); + MavenProjectSession projectSession; + try + { + projectSession = session.getProjectSession( project ); + } + catch ( PlexusContainerException e ) + { + throw new PluginManagerException( mojoDescriptor, "Failed to create project-specific session for project: " + project.getId() + + ".", project, e ); + } + + ClassRealm pluginRealm; + try + { + pluginRealm = projectSession.getPluginRealm( pluginDescriptor ); + } + catch ( NoSuchRealmException e ) + { + getLogger().debug( "Plugin realm: " + pluginDescriptor.getId() + " not found in project session for: " + project.getId() + ". Using project realm instead." ); + pluginRealm = projectSession.getProjectRealm(); + } + ClassRealm oldRealm = null; try @@ -707,6 +728,7 @@ public class DefaultPluginManager } finally { + pluginDescriptor.setClassRealm( null ); if ( oldRealm != null ) { container.setLookupRealm( oldRealm ); @@ -810,6 +832,7 @@ public class DefaultPluginManager // lookups that occur in contextualize calls in line with the right realm. ClassRealm oldRealm = container.setLookupRealm( realm ); + pluginDescriptor.setClassRealm( realm ); getLogger().debug( "Looking up mojo " + mojoDescriptor.getRoleHint() + " in realm " diff --git a/maven-embedder/src/main/java/org/apache/maven/embedder/MavenEmbedder.java b/maven-embedder/src/main/java/org/apache/maven/embedder/MavenEmbedder.java index 7194fe8bfe..633a5095e5 100644 --- a/maven-embedder/src/main/java/org/apache/maven/embedder/MavenEmbedder.java +++ b/maven-embedder/src/main/java/org/apache/maven/embedder/MavenEmbedder.java @@ -321,7 +321,14 @@ public class MavenEmbedder MavenSession session = new MavenSession( container, request, null, null, new HashMap() ); - pluginManager.verifyPlugin( plugin, project, session ); + try + { + pluginManager.verifyPlugin( plugin, project, session ); + } + finally + { + session.dispose(); + } } /** protected for tests only.. */ @@ -471,7 +478,7 @@ public class MavenEmbedder Map handlers = findArtifactTypeHandlers( project ); - //TODO: ok this is crappy, now there are active collections so when new artifact handlers + //TODO: ok this is crappy, now there are active collections so when new artifact handlers // enter the system they should be available. artifactHandlerManager.addHandlers( handlers ); @@ -645,8 +652,8 @@ public class MavenEmbedder try { - ContainerConfiguration cc = new DefaultContainerConfiguration() - .addComponentDiscoverer( new MavenPluginDiscoverer() ) + ContainerConfiguration cc = new DefaultContainerConfiguration() + .addComponentDiscoverer( new MavenPluginDiscoverer() ) .addComponentDiscoveryListener( new MavenPluginCollector() ) .setClassWorld( classWorld ).setParentContainer( configuration.getParentContainer() ).setName( "embedder" ); diff --git a/pom.xml b/pom.xml index 042d76bdb3..034a384ea0 100644 --- a/pom.xml +++ b/pom.xml @@ -138,7 +138,7 @@ under the License. maven-embedder - 1.0-alpha-34 + 1.0-alpha-35-SNAPSHOT 1.0-beta-2