Maven Shade does not include "META-INF/versions" of multi-release dependency

2k Views Asked by At

In our project, we create a "skinny" jar, which only includes our own application code and we use maven shade plugin to create the JARs for the dependencies we need to run the application. Maven shade is used to package multiple dependencies into the same jar. For example all jetty dependencies are packaged into one bigger jetty-full.jar.
Now we are facing an issue with the org.graalvm.js dependency. It depends on truffle-api which itself is a multi-release jar and includes classes for java 11 under META-INF/versions/11. As we are using Java 11, we need those classes but for some reason they are excluded by the maven shade plugin.
Here is the code of the related pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <artifactId>project-dependencies</artifactId>
    <groupId>org.example</groupId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>graal-full</artifactId>

  <properties>
    <graalvm.version>21.3.0</graalvm.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.graalvm.js</groupId>
      <artifactId>js</artifactId>
      <version>${graalvm.version}</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.graalvm.js</groupId>
      <artifactId>js-scriptengine</artifactId>
      <version>${graalvm.version}</version>
    </dependency>
  </dependencies>

  <build>
    <finalName>${project.artifactId}</finalName>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <configuration>
          <transformers>
            <transformer
                implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
          </transformers>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

The META-INF of the resulting jar only contains the following folders and files:

  • upgrade
  • services
  • native-image
  • maven
  • MANIFEST.MF (File)

The versions folder is missing.
I am now using copy-dependency plugin instead to copy the single files and there the META-INF contains versions/11 folder with the needed Java 11 class.
Am I missing something or why is the META-INF/versions excluded from the shaded jar?

1

There are 1 best solutions below

0
On

This appears to be something of a duplicate, and it appears that you can set Multi-Release:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>3.2.1</version>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>shade</goal>
      </goals>
      <configuration>
        <transformers>
          <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
            <manifestEntries>
              <Main-Class>foo.bar.Generate</Main-Class>
              <Multi-Release>true</Multi-Release>
            </manifestEntries>
          </transformer>
          <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
        </transformers>
      </configuration>
    </execution>
  </executions>
</plugin>

Even though it is not documented