2

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?

Robert P
  • 9,398
  • 10
  • 58
  • 100
  • There is no resource transformer available which supports multi release jar... you might need to write your own... – khmarbaise Jan 10 '22 at 08:58
  • So the resource-transformer is the problem here? Is there a "copy-as-is" resource transformer which I could use? – Robert P Jan 10 '22 at 09:44

1 Answers1

1

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

Lucas
  • 14,227
  • 9
  • 74
  • 124