10

I'd like to create a Java 9 runtime image that contains 3rd party jars. I have made a simple Java project (let's call this Example) to call a utility jar (let's call this ExampleUtil.jar). Example contains the module-info.java in the src directory and runs fine in Eclipse (I had added ExampleUtil.jar as a module dependency).

If I call:

jlink -v
    --module-path "C:\Program Files\Java\jdk-9.0.4\jmods";C:\Temp
    --add-modules com.example.steven
    --output C:\Temp\image.steven
    --launcher launch=com.example.steven/com.example.steven`

...I get the error message:

Error: module-info.class not found for ExampleUtil module

Is there a way to create a runtime image using jars that aren't modules?

Lii
  • 11,553
  • 8
  • 64
  • 88
Steven Hung
  • 176
  • 1
  • 5

2 Answers2

21

No, jlink requires all included modules to be explicit, meaning they need to have a module descriptor. Here's what the documentation says about the jlink's module path:

The path where the jlink tool discovers observable modules. These modules can be modular JAR files, JMOD files, or exploded modules.

Note the absence of "plain JARs" (i.e. JARs without descriptor).

You can upgrade existing third-party JARs to modular JARs, though (with some effort). The steps are:

Alternatively, you can use a tool like ModiTect that does these things for you.

Nicolai Parlog
  • 47,972
  • 24
  • 125
  • 255
  • 29
    Wow... this makes jlink from hard to use to useless for the foreseeable future. – Pablo Fernandez Apr 07 '18 at 09:36
  • Well one way to go around this is to create a new Modular Project called "Commons" or something like that. Then put all the source files (that come from legacy jars) into that project and then "Import" that project as a dependency to your actual project. This means, once those jars have been updated to include support for modules, then remove the sources and add the jar. – trilogy Jun 18 '19 at 17:09
1

jlink directly can not do this. The trick is to call jdeps on all external libs to collect their system module dependencies and than modify the parameters to jlink accordingly. Generating a module-info.java will not always work to solve the problem but you can use jdeps to see what system modules you need and than create a custom Java Runtime with jlink which includes all these system dependencies and put the external libs on the classpath or module path dependening on if they are non-modular jars or automatic module jars.

You can use something like a special maven plugin to automate that task.

bei
  • 21
  • 3
  • Adding a module-info.java manually or automatically might break the usability of the jar because some things work differently when a class is on the module-path and not on the classpath. – bei Feb 06 '19 at 06:16