[
https://issues.apache.org/jira/browse/MNG-6906?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17690822#comment-17690822
]
Michael Osipov commented on MNG-6906:
-------------------------------------
[~gnodet], something for you?
> Whether a core extension can access classes exported by another core
> extension should not depend on how it is registered
> ------------------------------------------------------------------------------------------------------------------------
>
> Key: MNG-6906
> URL: https://issues.apache.org/jira/browse/MNG-6906
> Project: Maven
> Issue Type: Bug
> Components: Class Loading
> Reporter: Marc Philipp
> Priority: Major
>
> We have a Maven core extension
> (https://search.maven.org/artifact/com.gradle/gradle-enterprise-maven-extension/1.5/jar)
> that declares two packages as exported in its
> {{META-INF/maven/extension.xml}}:
> {code}
> <?xml version="1.0" encoding="UTF-8"?>
> <extension>
> <exportedPackages>
> <exportedPackage>com.gradle.maven.extension.api.scan</exportedPackage>
> <exportedPackage>com.gradle.maven.mojo</exportedPackage>
> </exportedPackages>
> <exportedArtifacts>
>
> <exportedArtifact>com.gradle:gradle-enterprise-maven-extension</exportedArtifact>
> </exportedArtifacts>
> </extension>
> {code}
> The first package ({{com.gradle.maven.extension.api.scan}}) contains a
> {{BuildScanApi}} interface for which the extension registers a component in
> an {{EventSpy}} at runtime.
> We would now like to consume that component in another core extension (let's
> call it consuming-extension) that has a {{provided}} dependency to
> {{com.gradle:gradle-enterprise-maven-extension}} like this:
> {code}
> BuildScanApi buildScan = (BuildScanApi)
> session.lookup("com.gradle.maven.extension.api.scan.BuildScanApi");
> {code}
> However, whether that works depends on how the core extensions are
> registered. Relevant for us are the following registration locations:
> {{<maven-home>/lib/ext}}, {{-Dmaven.ext.class.path}}, and
> {{.mvn/extensions.xml}}.
> ||consuming-extension||gradle-enterprise-maven-extension||Result||
> |{{<maven-home>/lib/ext}}|{{<maven-home>/lib/ext}}|(/)|
> |{{.mvn/extensions.xml}}|{{<maven-home>/lib/ext}}|(/)|
> |{{-Dmaven.ext.class.path}}|{{<maven-home>/lib/ext}}|(/)|
> |{{<maven-home>/lib/ext}}|{{.mvn/extensions.xml}}|(x)
> {{NoClassDefFoundError}}|
> |{{.mvn/extensions.xml}}|{{.mvn/extensions.xml}}|(x) {{NoClassDefFoundError}}|
> |{{-Dmaven.ext.class.path}}|{{.mvn/extensions.xml}}|(/)|
> |{{<maven-home>/lib/ext}}|{{-Dmaven.ext.class.path}}|(x)
> {{NoClassDefFoundError}}|
> |{{.mvn/extensions.xml}}|{{-Dmaven.ext.class.path}}|(x)
> {{NoClassDefFoundError}}|
> |{{-Dmaven.ext.class.path}}|{{-Dmaven.ext.class.path}}|(/)|
> With this workaround, I was able to get it working in all cases:
> {code}
> ClassRealm extensionRealm = (ClassRealm) this.getClass().getClassLoader();
> if (!"maven.ext".equals(extensionRealm.getId())) {
> extensionRealm.getWorld().getRealms().stream()
> .filter(realm ->
> realm.getId().startsWith("coreExtension>com.gradle:gradle-enterprise-maven-extension:")
> || realm.getId().equals("maven.ext"))
> .max(comparing((ClassRealm realm) -> realm.getId().length()))
> .ifPresent(realm -> {
> try {
> extensionRealm.importFrom(realm.getId(),
> "com.gradle.maven.extension.api.scan");
> } catch (Exception e) {
> throw new RuntimeException("Could not import package from realm", e);
> }
> });
> }
> {code}
> Please let me know if I have misunderstood the intention of declaring
> exported packages in {{extension.xml}}. I was unable to find documentation on
> it, unfortunately.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)