Cannot build executable jar using maven-jar-plugin when migrating to java 9 modules

458 Views Asked by At

I am introducing java 9 modules to a big project and I am facing an issue when trying to build an executable JAR (on one of the sub module) using the maven-jar-plugin. Here is a small view of my project:

├───my-sub-module
│   ├───pom.xml
│   └───src
│       ├───main
│       │   └───java
│       │       ├───com
│       │       │   └───packages
│       │       │       └───...
│       │       │           
│       │       └───module-info.java (let's say the module name is com.foo.bar)
│       └───test
│           └───java
│               └───com
│                   └───packages
│                       └───benchmark
│                           └───BenchmarkTests.java
└───pom.xml

The plugin configuration in my pom is :

<build>
        <plugins>
            <!-- Build an executable test JAR -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>com.packages.benchmark.BenchmarkTests</mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>test-jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

EDIT When building using mvn clean install I got the following stack-trace:

Caused by: org.codehaus.plexus.archiver.ArchiverException: Could not create modular JAR file. The JDK jar tool exited with 1
    at org.codehaus.plexus.archiver.jar.JarToolModularJarArchiver.postCreateArchive (JarToolModularJarArchiver.java:123)
    at org.codehaus.plexus.archiver.AbstractArchiver.createArchive (AbstractArchiver.java:1066)
    at org.apache.maven.archiver.MavenArchiver.createArchive (MavenArchiver.java:676)
    at org.apache.maven.plugins.jar.AbstractJarMojo.createArchive (AbstractJarMojo.java:276)
    at org.apache.maven.plugins.jar.AbstractJarMojo.execute (AbstractJarMojo.java:307)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:956)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:192)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:566)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)

I also noticed the following message in maven logs:

jar: Package com.package.benchmark missing from ModulePackages class file attribute

Does it mean that my test package should have the same name as in the module packages ?

1

There are 1 best solutions below

0
Laird Nelson On

Leaving aside many of @khmarbaise's excellent points:

The error:

jar: Package com.package.benchmark missing from ModulePackages class file attribute

…comes from the jar --update operation that the Plexus Archiver executes to make your project's .jar file a modular .jar file.

One of the flags the Plexus Archiver passes to jar is --main-class. Because of a line in the Java Virtual Machine Specification, the class name supplied as a value for this argument must be a class from the current module, i.e. the module described by the module-info.class file at the root of the .jar file in question. For perhaps a number of reasons, jar decides that com.packages.benchmark.BenchmarkTests does not belong to this current module.

The "ModulePackages class file attribute" portion of the error message is showing up as a result of jar trying to see what known packages there are in the current module-info.class class file. The ModulePackages attribute of that module-info.class file does not contain com.package.benchmark.

(The Plexus Archiver could probably output a better error message here and even avoid the --update command entirely if it detects a "bad" META-INF/MANIFEST.MF Main-Class attribute, since it has all the same information the jar tool does. See https://github.com/codehaus-plexus/plexus-archiver/issues/310.)