maven-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Marc Philipp (Jira)" <j...@apache.org>
Subject [jira] [Created] (MNG-6906) Whether a core extension can access classes exported by another core extension should not depend on how it is registered
Date Fri, 15 May 2020 15:34:00 GMT
Marc Philipp created MNG-6906:
---------------------------------

             Summary: 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


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.3.4#803005)

Mime
View raw message