Author: bentmann
Date: Sat Aug  1 21:54:18 2009
New Revision: 799936

URL: http://svn.apache.org/viewvc?rev=799936&view=rev
Log:
o Centralized class realm creation

Added:
    
maven/components/trunk/maven-core/src/main/java/org/apache/maven/classrealm/   
(with props)
    
maven/components/trunk/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmManager.java
   (with props)
    
maven/components/trunk/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java
   (with props)
Modified:
    
maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java
    
maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingHelper.java

Propchange: 
maven/components/trunk/maven-core/src/main/java/org/apache/maven/classrealm/
------------------------------------------------------------------------------
    bugtraq:label = Enter issue ID:

Propchange: 
maven/components/trunk/maven-core/src/main/java/org/apache/maven/classrealm/
------------------------------------------------------------------------------
    bugtraq:message = Issue id: %BUGID%

Propchange: 
maven/components/trunk/maven-core/src/main/java/org/apache/maven/classrealm/
------------------------------------------------------------------------------
    bugtraq:number = false

Propchange: 
maven/components/trunk/maven-core/src/main/java/org/apache/maven/classrealm/
------------------------------------------------------------------------------
    bugtraq:url = http://jira.codehaus.org/browse/%BUGID%

Added: 
maven/components/trunk/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmManager.java
URL: 
http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmManager.java?rev=799936&view=auto
==============================================================================
--- 
maven/components/trunk/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmManager.java
 (added)
+++ 
maven/components/trunk/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmManager.java
 Sat Aug  1 21:54:18 2009
@@ -0,0 +1,52 @@
+package org.apache.maven.classrealm;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+
+/**
+ * Manages the class realms used by Maven. <strong>Warning:</strong> This is 
an internal utility interface that is only
+ * public for technical reasons, it is not part of the public API. In 
particular, this interface can be changed or
+ * deleted without prior notice.
+ * 
+ * @author Benjamin Bentmann
+ */
+public interface ClassRealmManager
+{
+
+    /**
+     * Creates a new class realm for the specified project and its build 
extensions.
+     * 
+     * @param model The model of the project for which to create a realm, must 
not be {...@code null}.
+     * @return The new project realm, never {...@code null}.
+     */
+    ClassRealm createProjectRealm( Model model );
+
+    /**
+     * Creates a new class realm for the specified plugin.
+     * 
+     * @param plugin The plugin for which to create a realm, must not be 
{...@code null}.
+     * @return The new plugin realm, never {...@code null}.
+     */
+    ClassRealm createPluginRealm( Plugin plugin );
+
+}

Propchange: 
maven/components/trunk/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
maven/components/trunk/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmManager.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: 
maven/components/trunk/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java
URL: 
http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java?rev=799936&view=auto
==============================================================================
--- 
maven/components/trunk/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java
 (added)
+++ 
maven/components/trunk/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java
 Sat Aug  1 21:54:18 2009
@@ -0,0 +1,238 @@
+package org.apache.maven.classrealm;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Random;
+
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.codehaus.plexus.MutablePlexusContainer;
+import org.codehaus.plexus.PlexusContainer;
+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;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+
+/**
+ * Manages the class realms used by Maven. <strong>Warning:</strong> This is 
an internal utility class that is only
+ * public for technical reasons, it is not part of the public API. In 
particular, this interface can be changed or
+ * deleted without prior notice.
+ * 
+ * @author Benjamin Bentmann
+ */
+...@component( role = ClassRealmManager.class )
+public class DefaultClassRealmManager
+    implements ClassRealmManager
+{
+
+    @Requirement
+    private Logger logger;
+
+    @Requirement
+    protected PlexusContainer container;
+
+    private ClassWorld getClassWorld()
+    {
+        return ( (MutablePlexusContainer) container ).getClassWorld();
+    }
+
+    private ClassRealm createRealm( String baseRealmId )
+    {
+        ClassWorld world = getClassWorld();
+
+        String realmId = baseRealmId;
+
+        Random random = new Random();
+
+        synchronized ( world )
+        {
+            ClassRealm classRealm;
+
+            while ( true )
+            {
+                try
+                {
+                    classRealm = world.newRealm( realmId );
+
+                    if ( logger.isDebugEnabled() )
+                    {
+                        logger.debug( "Created new class realm " + realmId );
+                    }
+
+                    break;
+                }
+                catch ( DuplicateRealmException e )
+                {
+                    realmId = baseRealmId + '-' + random.nextInt();
+                }
+            }
+
+            classRealm.setParentRealm( getApiRealm() );
+
+            importXpp3Dom( classRealm );
+
+            return classRealm;
+        }
+    }
+
+    /**
+     * Gets the class realm that holds the Maven API classes that we intend to 
share with plugins and extensions. The
+     * API realm is basically a subset of the core realm and hides internal 
utility/implementation classes from
+     * plugins/extensions.
+     * 
+     * @return The class realm for the Maven API, never {...@code null}.
+     */
+    private ClassRealm getApiRealm()
+    {
+        return container.getContainerRealm();
+
+// TODO: MNG-4273, currently non-functional because the core artifact filter 
wipes out transitive plugin dependencies
+//       like plexus-utils, too. We need to filter the result set of the 
plugin artifacts, not the graph.
+//
+//        ClassWorld world = getClassWorld();
+//
+//        String realmId = "maven.api";
+//
+//        ClassRealm apiRealm;
+//
+//        synchronized ( world )
+//        {
+//            apiRealm = world.getClassRealm( realmId );
+//
+//            if ( apiRealm == null )
+//            {
+//                try
+//                {
+//                    apiRealm = world.newRealm( realmId );
+//                }
+//                catch ( DuplicateRealmException e )
+//                {
+//                    throw new IllegalStateException( "Failed to create API 
realm " + realmId, e );
+//                }
+//
+//                String coreRealmId = container.getContainerRealm().getId();
+//                try
+//                {
+//                    // components.xml
+//                    apiRealm.importFrom( coreRealmId, "META-INF/plexus" );
+//
+//                    // maven-*
+//                    apiRealm.importFrom( coreRealmId, "org.apache.maven." );
+//
+//                    // plexus-classworlds
+//                    apiRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.classworlds" );
+//
+//                    // plexus-container, plexus-component-annotations
+//                    apiRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.component" );
+//                    apiRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.configuration" );
+//                    apiRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.container" );
+//                    apiRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.context" );
+//                    apiRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.lifecycle" );
+//                    apiRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.logging" );
+//                    apiRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.personality" );
+//                    apiRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.ComponentRegistry" );
+//                    apiRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.ContainerConfiguration" );
+//                    apiRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.DefaultComponentRegistry" );
+//                    apiRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.DefaultContainerConfiguration" );
+//                    apiRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.DefaultPlexusContainer" );
+//                    apiRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.DuplicateChildContainerException" );
+//                    apiRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.MutablePlexusContainer" );
+//                    apiRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.PlexusConstants" );
+//                    apiRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.PlexusContainer" );
+//                    apiRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.PlexusContainerException" );
+//                }
+//                catch ( NoSuchRealmException e )
+//                {
+//                    throw new IllegalStateException( e );
+//                }
+//
+//                try
+//                {
+//                    container.discoverComponents( apiRealm );
+//                }
+//                catch ( Exception e )
+//                {
+//                    throw new IllegalStateException( "Failed to discover 
components in API realm " + realmId, e );
+//                }
+//            }
+//        }
+//
+//        return apiRealm;
+    }
+
+    /**
+     * Imports Xpp3Dom and associated types into the specified realm. Unlike 
the other archives that constitute the API
+     * realm, plexus-utils is not excluded from the plugin/project realm, yet 
we must ensure this class is loaded from
+     * the API realm and not from the plugin/project realm.
+     * 
+     * @param importingRealm The realm into which to import Xpp3Dom, must not 
be {...@code null}.
+     */
+    private void importXpp3Dom( ClassRealm importingRealm )
+    {
+        String coreRealmId = container.getContainerRealm().getId();
+        try
+        {
+            importingRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.util.xml.Xpp3Dom" );
+            importingRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.util.xml.pull.XmlPullParser" );
+            importingRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.util.xml.pull.XmlPullParserException" );
+            importingRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.util.xml.pull.XmlSerializer" );
+        }
+        catch ( NoSuchRealmException e )
+        {
+            throw new IllegalStateException( e );
+        }
+    }
+
+    public ClassRealm createProjectRealm( Model model )
+    {
+        if ( model == null )
+        {
+            throw new IllegalArgumentException( "model missing" );
+        }
+
+        return createRealm( getKey( model ) );
+    }
+
+    private String getKey( Model model )
+    {
+        return "project>" + model.getGroupId() + ":" + model.getArtifactId() + 
":" + model.getVersion();
+    }
+
+    public ClassRealm createPluginRealm( Plugin plugin )
+    {
+        if ( plugin == null )
+        {
+            throw new IllegalArgumentException( "plugin missing" );
+        }
+
+        return createRealm( getKey( plugin ) );
+    }
+
+    private String getKey( Plugin plugin )
+    {
+        String version = ArtifactUtils.toSnapshotVersion( plugin.getVersion() 
);
+        return "plugin>" + plugin.getGroupId() + ":" + plugin.getArtifactId() 
+ ":" + version;
+    }
+
+}

Propchange: 
maven/components/trunk/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
maven/components/trunk/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: 
maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java
URL: 
http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java?rev=799936&r1=799935&r2=799936&view=diff
==============================================================================
--- 
maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java
 (original)
+++ 
maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java
 Sat Aug  1 21:54:18 2009
@@ -41,6 +41,7 @@
 import org.apache.maven.artifact.resolver.ResolutionErrorHandler;
 import org.apache.maven.artifact.resolver.filter.AndArtifactFilter;
 import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
+import org.apache.maven.classrealm.ClassRealmManager;
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.model.Dependency;
 import org.apache.maven.model.Plugin;
@@ -51,12 +52,8 @@
 import org.apache.maven.project.DuplicateArtifactAttachmentException;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.repository.RepositorySystem;
-import org.codehaus.plexus.MutablePlexusContainer;
 import org.codehaus.plexus.PlexusContainer;
-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;
 import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.component.annotations.Requirement;
 import 
org.codehaus.plexus.component.composition.CycleDetectedInComponentGraphException;
@@ -92,6 +89,9 @@
     protected PlexusContainer container;
 
     @Requirement
+    private ClassRealmManager classRealmManager;
+
+    @Requirement
     protected ArtifactFilterManager coreArtifactFilterManager;
 
     @Requirement
@@ -450,45 +450,8 @@
      * Creates ClassRealm with unique id for the given plugin
      */
     private ClassRealm createPluginRealm( Plugin plugin ) 
-        throws PluginManagerException
     {
-        ClassWorld world = ((MutablePlexusContainer) 
container).getClassWorld();
-
-        String baseRealmId = constructPluginKey( plugin );
-        String realmId = baseRealmId;
-
-        synchronized ( world )
-        {
-            for ( int i = 0; i < 100; i++ )
-            {
-                try
-                {
-                    ClassRealm pluginRealm = world.newRealm( realmId );
-                    pluginRealm.setParentRealm( container.getContainerRealm() 
);
-
-                    String coreRealmId = container.getContainerRealm().getId();
-                    try
-                    {
-                        pluginRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.util.xml.Xpp3Dom" );
-                        pluginRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.util.xml.pull.XmlPullParser" );
-                        pluginRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.util.xml.pull.XmlPullParserException" );
-                        pluginRealm.importFrom( coreRealmId, 
"org.codehaus.plexus.util.xml.pull.XmlSerializer" );
-                    }
-                    catch ( NoSuchRealmException e )
-                    {
-                        throw new IllegalStateException( e );
-                    }
-
-                    return pluginRealm;
-                }
-                catch ( DuplicateRealmException e )
-                {
-                    realmId = baseRealmId + "-" + i;
-                }
-            }
-        }
-
-        throw new PluginManagerException( plugin, "Could not create ClassRealm 
for plugin " + baseRealmId, (Throwable) null );
+        return classRealmManager.createPluginRealm( plugin );
     }
 
     private Mojo getConfiguredMojo( MavenSession session, MavenProject 
project, MojoExecution mojoExecution, ClassRealm pluginRealm )

Modified: 
maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingHelper.java
URL: 
http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingHelper.java?rev=799936&r1=799935&r2=799936&view=diff
==============================================================================
--- 
maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingHelper.java
 (original)
+++ 
maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingHelper.java
 Sat Aug  1 21:54:18 2009
@@ -33,6 +33,7 @@
 import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
 import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
 import org.apache.maven.artifact.resolver.ResolutionErrorHandler;
+import org.apache.maven.classrealm.ClassRealmManager;
 import org.apache.maven.model.Build;
 import org.apache.maven.model.Dependency;
 import org.apache.maven.model.Extension;
@@ -40,17 +41,16 @@
 import org.apache.maven.model.Plugin;
 import org.apache.maven.model.Repository;
 import org.apache.maven.repository.RepositorySystem;
-import org.codehaus.plexus.MutablePlexusContainer;
 import org.codehaus.plexus.PlexusContainer;
-import org.codehaus.plexus.classworlds.ClassWorld;
 import org.codehaus.plexus.classworlds.realm.ClassRealm;
-import org.codehaus.plexus.classworlds.realm.DuplicateRealmException;
 import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.component.annotations.Requirement;
 import org.codehaus.plexus.logging.Logger;
 
 /**
- * Assists the project builder.
+ * Assists the project builder. <strong>Warning:</strong> This is an internal 
utility class that is only public for
+ * technical reasons, it is not part of the public API. In particular, this 
interface can be changed or deleted without
+ * prior notice.
  * 
  * @author Benjamin Bentmann
  */
@@ -66,6 +66,9 @@
     private PlexusContainer container;
 
     @Requirement
+    private ClassRealmManager classRealmManager;
+
+    @Requirement
     private RepositorySystem repositorySystem;
 
     @Requirement
@@ -125,32 +128,7 @@
             return projectRealm;
         }
 
-        String realmId = model.getGroupId() + ':' + model.getArtifactId() + 
':' + model.getVersion();
-
-        if ( logger.isDebugEnabled() )
-        {
-            logger.debug( "Creating project realm " + realmId );
-        }
-
-        ClassWorld world = ( (MutablePlexusContainer) container 
).getClassWorld();
-
-        synchronized ( world )
-        {
-            projectRealm = world.getClassRealm( realmId );
-
-            if ( projectRealm == null )
-            {
-                try
-                {
-                    projectRealm = world.newRealm( realmId );
-                    projectRealm.setParentRealm( container.getContainerRealm() 
);
-                }
-                catch ( DuplicateRealmException e )
-                {
-                    throw new IllegalStateException( "Failed to create project 
realm " + realmId, e );
-                }
-            }
-        }
+        projectRealm = classRealmManager.createProjectRealm( model );
 
         for ( Extension extension : build.getExtensions() )
         {
@@ -180,7 +158,8 @@
         }
         catch ( Exception e )
         {
-            throw new IllegalStateException( "Failed to discover components in 
project realm " + realmId, e );
+            throw new IllegalStateException( "Failed to discover components in 
project realm " + projectRealm.getId(),
+                                             e );
         }
 
         return projectRealm;


Reply via email to