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>