Is there a way to add maven dependencies when using maven-jlink-plugin?

I am using this Github project to access the new modular features in Java 9. I would like to add dependencies to the project and be able to create my own image. However, when I try to add a new dependency to pom.xml and add the require statement to module-info.java, I get the following error from maven-jlink-plugin:

Error: module-info.class not found for joda.time module 

I am trying to use this as a proof of concept that I can deploy images using the new binding phase, but naturally I need to have external dependencies and I need to use maven (work restriction).

Changes to mod-jar / pom.xml

 ... <dependencies> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>2.9.9</version> </dependency> </dependencies> ... 

modbank / module-info.java

 module com.soebes.nine.jar { requires java.base; requires joda.time; exports com.soebes.example.nine.jar; } 

Logs:

 [INFO] --- maven-jlink-plugin:3.0.0-alpha-1:jlink (default-jlink) @ mod-jlink --- [INFO] Toolchain in maven-jlink-plugin: jlink [ /Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home/bin/jlink ] [INFO] The following dependencies will be linked into the runtime image: [INFO] -> module: com.soebes.nine.one ( /Users/sebastianrestrepo/Projects/jdk9-jlink-jmod-example/maven-example/mod-1/target/jmods/com.soebes.nine.one.jmod ) [INFO] -> module: com.soebes.nine.two ( /Users/sebastianrestrepo/Projects/jdk9-jlink-jmod-example/maven-example/mod-2/target/jmods/com.soebes.nine.two.jmod ) [INFO] -> module: com.soebes.nine.jar ( /Users/sebastianrestrepo/Projects/jdk9-jlink-jmod-example/maven-example/mod-jar/target/com.soebes.nine.jar-1.0-SNAPSHOT.jar ) [INFO] -> module: joda.time ( /Users/sebastianrestrepo/.m2/repository/joda-time/joda-time/2.9.9/joda-time-2.9.9.jar ) [ERROR] Error: module-info.class not found for joda.time module [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary: [INFO] [INFO] parent ............................................. SUCCESS [ 1.460 s] [INFO] com.soebes.nine.one ................................ SUCCESS [ 2.022 s] [INFO] com.soebes.nine.two ................................ SUCCESS [ 1.392 s] [INFO] com.soebes.nine.jar ................................ SUCCESS [ 1.388 s] [INFO] mod-jlink .......................................... FAILURE [ 1.061 s] [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 7.911 s [INFO] Finished at: 2017-11-03T15:27:35-04:00 [INFO] Final Memory: 26M/981M [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.apache.maven.plugins:maven-jlink-plugin:3.0.0-alpha-1:jlink (default-jlink) on project mod-jlink: 

I would really appreciate any help. Thanks.

+6
java maven jodatime java-9 jlink
source share
4 answers

This is not like the plugin I consider . The joda.time module in your case seems like an automatic module.

The jlink tool does not support binding automatic modules , because they can rely on arbitrary contents of the class path, which contradicts the idea of ​​a stand-alone Java runtime.

So there are two ways to fix this: -

  • (you do not own a bank). Temporarily go on to create module-info.java [you can use the jdeps tool for it] and update the jar [using the jar tool] with the appropriate compiled class, as in Java 9 projects.

  • (you have a dependency). Transfer the jar directly to Java 9, where it will consist of module-info.class itself after compilation and packaging.

+10
source share

You can use the ModiTect Maven plug-in to add a module descriptor to the JAR and create a modular image at runtime with this module.

Disclaimer: I am the author of ModiTect.

+1
source share

My jlink-jpackager-maven-plugin, which is based on the maven-jlink-plugin with many native extensions, can do this.

The JLink-JPackager Maven plugin is designed to create modular runtime images via jlink with JDK 9 and above or embedded packages via jpackage with JDK 12 and above.

Although the jlink and jpackage tools have some limitations regarding the use of non-modular jar files and automatic jar module files, the JLink-JPackager Maven plugin can create ZIP files for modular runtime images or package installers with Java Runtime and mixed real and automatic modules and non-Modular cans.

This is done by analyzing the dependencies of the java module of all maven dependencies using the jdeps java tool and changing the command line parameters for jlink, jpackage and the java executable based on the results.

As a result of the execution of Java, it contains all the dependencies of the Java system modules of all real modules, all automatic modules and all Non-Modular JAR files that are put on the way to classes.

For jlink runtime jars that are automatic jar or non-modular jar, they are copied to the folder created by jlink after jlink is executed and before creating the resulting ZIP file.

For jpackage runtime jar files , which are automatic jar files or non-modular jar files, they are copied to the folder used with the jpackage --input parameter before jpackage is executed.

For jlink execution mode, a startup script is generated by a template engine that contains the necessary command line parameters for placing automatic jar files on the module path and non-modular jar files on the class path.

For jpackage execution mode , the --arguments parameter for jpackage is modified so that automatic jars are placed in the module path, and non-modular jars are placed in the class path.

For more information, see the plugins usage page .

0
source share

Let me try to explain the technical basis of this:

joda-time in version 2.9.9, as indicated in the question, is a non-modular jar, it does not contain module-info.class and does not declare itself an automatic module using Automatic-Module-Name: in its META-INF / MANIFEST.MF

Classes in a real module cannot call classes on the classpath, so you cannot use "require jode.time" in your info module with this version.

Automated modules can use classes on ClassPath. To use classes from a non-modular flask in a real module, you can use a wrapper, which itself is an automatic module.

There is currently version 2.10.1 joda-time, which is an automatic module and declares "Automatic-Module-Name: org.joda.time", so you can use "require org.joda.time" in your real module with this new version.

Now the new jlink tool cannot work directly with non-modular banks or automatic banks, and the maven-jlink plugin is now just a maven wrapper around the jlink tool, translating its configuration parameters into arguments for the jlink tool.

To create a custom Java runtime for projects that use mixed maven dependencies with real modules, automatic modules and non-modular banks, you must know all the dependencies of the system modules of your real modules, automatic modules and non-modular banks and use them. the --add-modules option to communicate with them.

To build system module dependencies, you can use the new jdeps tool with the option --print-module-deps or --list-deps depending on the version of JDK used.

If you use maven for your project, you can automate this task by creating or using the maven plugin, which will do it for you.

0
source share

All Articles