This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven.git


The following commit(s) were added to refs/heads/master by this push:
     new 415eaf31d [MNG-7160] Ability to customize core extensions classloaders 
(#616)
415eaf31d is described below

commit 415eaf31de407efcbf61166afd8cf4e86cdafe11
Author: Guillaume Nodet <[email protected]>
AuthorDate: Wed Jun 15 10:43:17 2022 +0200

    [MNG-7160] Ability to customize core extensions classloaders (#616)
---
 .../apache/maven/DefaultArtifactFilterManager.java |  6 +--
 .../maven/classrealm/DefaultClassRealmManager.java |  8 ++--
 .../extension/internal/CoreExportsProvider.java    | 22 +++++-----
 maven-embedder/pom.xml                             |  2 +-
 .../internal/BootstrapCoreExtensionManager.java    | 49 +++++++++++++++++++---
 maven-embedder/src/main/mdo/core-extensions.mdo    |  8 ++++
 6 files changed, 70 insertions(+), 25 deletions(-)

diff --git 
a/maven-core/src/main/java/org/apache/maven/DefaultArtifactFilterManager.java 
b/maven-core/src/main/java/org/apache/maven/DefaultArtifactFilterManager.java
index a746846a8..810baaef3 100644
--- 
a/maven-core/src/main/java/org/apache/maven/DefaultArtifactFilterManager.java
+++ 
b/maven-core/src/main/java/org/apache/maven/DefaultArtifactFilterManager.java
@@ -29,7 +29,7 @@ import javax.inject.Singleton;
 
 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
 import org.apache.maven.artifact.resolver.filter.ExclusionSetFilter;
-import org.apache.maven.extension.internal.CoreExportsProvider;
+import org.apache.maven.extension.internal.CoreExports;
 
 /**
  * @author Jason van Zyl
@@ -50,10 +50,10 @@ public class DefaultArtifactFilterManager
 
     @Inject
     public DefaultArtifactFilterManager( List<ArtifactFilterManagerDelegate> 
delegates,
-                                         CoreExportsProvider coreExports )
+                                         CoreExports coreExports )
     {
         this.delegates = delegates;
-        this.coreArtifacts = coreExports.get().getExportedArtifacts();
+        this.coreArtifacts = coreExports.getExportedArtifacts();
     }
 
     private synchronized Set<String> getExcludedArtifacts()
diff --git 
a/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java
 
b/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java
index b9e8d22d6..50e0e3c6f 100644
--- 
a/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java
+++ 
b/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java
@@ -37,7 +37,7 @@ import javax.inject.Singleton;
 
 import org.apache.maven.artifact.ArtifactUtils;
 import org.apache.maven.classrealm.ClassRealmRequest.RealmType;
-import org.apache.maven.extension.internal.CoreExportsProvider;
+import org.apache.maven.extension.internal.CoreExports;
 import org.apache.maven.model.Model;
 import org.apache.maven.model.Plugin;
 import org.codehaus.plexus.MutablePlexusContainer;
@@ -94,19 +94,19 @@ public class DefaultClassRealmManager
     @Inject
     public DefaultClassRealmManager( PlexusContainer container,
                                      List<ClassRealmManagerDelegate> delegates,
-                                     CoreExportsProvider exports )
+                                     CoreExports exports )
     {
         this.world = ( (MutablePlexusContainer) container ).getClassWorld();
         this.containerRealm = container.getContainerRealm();
         this.delegates = delegates;
 
-        Map<String, ClassLoader> foreignImports = 
exports.get().getExportedPackages();
+        Map<String, ClassLoader> foreignImports = 
exports.getExportedPackages();
 
         this.mavenApiRealm =
             createRealm( API_REALMID, RealmType.Core, null /* parent */, null 
/* parentImports */,
                          foreignImports, null /* artifacts */ );
 
-        this.providedArtifacts = exports.get().getExportedArtifacts();
+        this.providedArtifacts = exports.getExportedArtifacts();
     }
 
     private ClassRealm newRealm( String id )
diff --git 
a/maven-core/src/main/java/org/apache/maven/extension/internal/CoreExportsProvider.java
 
b/maven-core/src/main/java/org/apache/maven/extension/internal/CoreExportsProvider.java
index 3e6f9f7b6..b1a30fe3c 100644
--- 
a/maven-core/src/main/java/org/apache/maven/extension/internal/CoreExportsProvider.java
+++ 
b/maven-core/src/main/java/org/apache/maven/extension/internal/CoreExportsProvider.java
@@ -19,34 +19,34 @@ package org.apache.maven.extension.internal;
  * under the License.
  */
 
+import java.util.Objects;
+
 import javax.inject.Inject;
 import javax.inject.Named;
+import javax.inject.Provider;
 import javax.inject.Singleton;
 
 import org.codehaus.plexus.PlexusContainer;
-import org.eclipse.sisu.Nullable;
 
 /**
  * CoreExportsProvider
  */
 @Named
 @Singleton
-public class CoreExportsProvider
+public class CoreExportsProvider implements Provider<CoreExports>
 {
 
     private final CoreExports exports;
 
     @Inject
-    public CoreExportsProvider( PlexusContainer container, @Nullable 
CoreExports exports )
+    public CoreExportsProvider( PlexusContainer container )
+    {
+        this( new CoreExports( CoreExtensionEntry.discoverFrom( 
container.getContainerRealm() ) ) );
+    }
+
+    public CoreExportsProvider( CoreExports exports )
     {
-        if ( exports == null )
-        {
-            this.exports = new CoreExports( CoreExtensionEntry.discoverFrom( 
container.getContainerRealm() ) );
-        }
-        else
-        {
-            this.exports = exports;
-        }
+        this.exports = Objects.requireNonNull( exports );
     }
 
     public CoreExports get()
diff --git a/maven-embedder/pom.xml b/maven-embedder/pom.xml
index a40eccac4..842f86823 100644
--- a/maven-embedder/pom.xml
+++ b/maven-embedder/pom.xml
@@ -175,7 +175,7 @@ under the License.
         <groupId>org.codehaus.modello</groupId>
         <artifactId>modello-maven-plugin</artifactId>
         <configuration>
-          <version>1.0.0</version>
+          <version>1.1.0</version>
           <models>
             <model>src/main/mdo/core-extensions.mdo</model>
           </models>
diff --git 
a/maven-embedder/src/main/java/org/apache/maven/cli/internal/BootstrapCoreExtensionManager.java
 
b/maven-embedder/src/main/java/org/apache/maven/cli/internal/BootstrapCoreExtensionManager.java
index 74570eb38..f3583e224 100644
--- 
a/maven-embedder/src/main/java/org/apache/maven/cli/internal/BootstrapCoreExtensionManager.java
+++ 
b/maven-embedder/src/main/java/org/apache/maven/cli/internal/BootstrapCoreExtensionManager.java
@@ -31,6 +31,7 @@ import javax.inject.Named;
 import org.apache.maven.RepositoryUtils;
 import org.apache.maven.cli.internal.extension.model.CoreExtension;
 import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.extension.internal.CoreExports;
 import org.apache.maven.extension.internal.CoreExtensionEntry;
 import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory;
 import org.apache.maven.model.Plugin;
@@ -60,12 +61,18 @@ import org.slf4j.LoggerFactory;
 @Named
 public class BootstrapCoreExtensionManager
 {
+    public static final String STRATEGY_PARENT_FIRST = "parent-first";
+    public static final String STRATEGY_PLUGIN = "plugin";
+    public static final String STRATEGY_SELF_FIRST = "self-first";
+
     private final Logger log = LoggerFactory.getLogger( getClass() );
 
     private final DefaultPluginDependenciesResolver pluginDependenciesResolver;
 
     private final DefaultRepositorySystemSessionFactory 
repositorySystemSessionFactory;
 
+    private final CoreExports coreExports;
+
     private final ClassWorld classWorld;
 
     private final ClassRealm parentRealm;
@@ -73,10 +80,12 @@ public class BootstrapCoreExtensionManager
     @Inject
     public BootstrapCoreExtensionManager( DefaultPluginDependenciesResolver 
pluginDependenciesResolver,
                                           
DefaultRepositorySystemSessionFactory repositorySystemSessionFactory,
+                                          CoreExports coreExports,
                                           PlexusContainer container )
     {
         this.pluginDependenciesResolver = pluginDependenciesResolver;
         this.repositorySystemSessionFactory = repositorySystemSessionFactory;
+        this.coreExports = coreExports;
         this.classWorld = ( (DefaultPlexusContainer) container 
).getClassWorld();
         this.parentRealm = container.getContainerRealm();
     }
@@ -121,14 +130,42 @@ public class BootstrapCoreExtensionManager
     {
         String realmId =
             "coreExtension>" + extension.getGroupId() + ":" + 
extension.getArtifactId() + ":" + extension.getVersion();
-        ClassRealm realm = classWorld.newRealm( realmId, null );
-        log.debug( "Populating class realm " + realm.getId() );
-        realm.setParentRealm( parentRealm );
+        final ClassRealm realm = classWorld.newRealm( realmId, null );
+        Set<String> providedArtifacts = Collections.emptySet();
+        String classLoadingStrategy = extension.getClassLoadingStrategy();
+        if ( STRATEGY_PARENT_FIRST.equals( classLoadingStrategy ) )
+        {
+            realm.importFrom( parentRealm, "" );
+        }
+        else if ( STRATEGY_PLUGIN.equals( classLoadingStrategy ) )
+        {
+            coreExports.getExportedPackages().forEach( ( p, cl ) -> 
realm.importFrom( cl, p ) );
+            providedArtifacts = coreExports.getExportedArtifacts();
+        }
+        else if ( STRATEGY_SELF_FIRST.equals( classLoadingStrategy ) )
+        {
+            realm.setParentRealm( parentRealm );
+        }
+        else
+        {
+            throw new IllegalArgumentException( "Unsupported class-loading 
strategy '"
+                    + classLoadingStrategy + "'. Supported values are: " + 
STRATEGY_PARENT_FIRST
+                    + ", " + STRATEGY_PLUGIN + " and " + STRATEGY_SELF_FIRST );
+        }
+        log.debug( "Populating class realm {}", realm.getId() );
         for ( Artifact artifact : artifacts )
         {
-            File file = artifact.getFile();
-            log.debug( "  Included " + file );
-            realm.addURL( file.toURI().toURL() );
+            String id = artifact.getGroupId() + ":" + artifact.getArtifactId();
+            if ( providedArtifacts.contains( id ) )
+            {
+                log.debug( "  Excluded {}", id );
+            }
+            else
+            {
+                File file = artifact.getFile();
+                log.debug( "  Included {} located at {}", id, file );
+                realm.addURL( file.toURI().toURL() );
+            }
         }
         return CoreExtensionEntry.discoverFrom( realm, Collections.singleton( 
artifacts.get( 0 ).getFile() ) );
     }
diff --git a/maven-embedder/src/main/mdo/core-extensions.mdo 
b/maven-embedder/src/main/mdo/core-extensions.mdo
index 8a74aabb5..968258d21 100644
--- a/maven-embedder/src/main/mdo/core-extensions.mdo
+++ b/maven-embedder/src/main/mdo/core-extensions.mdo
@@ -82,6 +82,14 @@
           <required>true</required>
           <type>String</type>
         </field>
+        <field>
+          <name>classLoadingStrategy</name>
+          <description>The class loading strategy: 'self-first' (the default), 
'parent-first' (loads classes from the parent, then from the extension) or 
'plugin' (follows the rules from extensions defined as plugins).</description>
+          <version>1.1.0+</version>
+          <defaultValue>self-first</defaultValue>
+          <required>false</required>
+          <type>String</type>
+        </field>
       </fields>
       <codeSegments>
         <codeSegment>

Reply via email to