Creating custom runtime image dedicated for specific modular application

1.6k Views Asked by At

Let's say I'm developing a modular application that consists of 2 modules: com.spacey.explorer that depends on com.spacey.rocket module. I have their modular JAR files in some bin directory.

And I want to prepare lightweight JRE to run it. So obviously, I use the jlink tool:

$ jlink --module-path /opt/jdk-9/jmods:../bin --add-modules com.spacey.explorer --output ~/custom-jre3

Now when I list modules in my JRE I get the following:

$ java --list-modules 
com.spacey.explorer
com.spacey.rocket
java.base@9

That is, my application modules are bundled into JRE. But if I wanted to build a JRE that has just JDK-originated modules that are sufficient to run my application and keep my application modules separate, I have to know what my JDK dependencies are (in the example this is just java.base) and specify them explicitly like:

$ jlink --module-path /opt/jdk-9/jmods --add-modules java.base --output ~/custom-jre3

Is there any way to make jlink do this for me ? Or any tool that would figure out those JDK-originated dependencies for me?

2

There are 2 best solutions below

0
On BEST ANSWER

You can use the jdeps tool. The option that could help is:

jdeps --list-deps <path>

Lists the dependences and use of JDK internal APIs.

where <path> can be a pathname to a .class file, a directory, a JAR file.

Note: Use jdeps -help to list out all the option and their syntax. You can use


For example, I gave a try to a jar file in my machines .m2 folder, which would be treated as an unnamed module like:

jdeps --list-deps /.m2/repository/org/apache/commons/commons-lang3/3.6/commons-lang3-3.6.jar

Output::

java.base
java.desktop
unnamed module: /.m2/repository/org/apache/commons/commons-lang3/3.6/commons-lang3-3.6.jar

You can also make use of the

jdeps --jdk-internals --class-path <path> <path>

Finds class-level dependences on JDK internal APIs. By default, it analyzes all classes on --class-path and input files unless -include option is specified.


Update November 1,2017

There is future revision change to make use of the same with jlink as :

jlink --module-path jmods --add-modules $(jdeps --print-module-deps myapp.jar) --output image
0
On

To create a runtime image with jlink you need to specify the root modules with --add-modules - starting with these modules, jlink will build a module graph and include all resolved modules in the new image. You have used --add-modules com.spacey.explorer, so jlink includes com.spacey.explorer and all its dependencies.

To instead only include the JDK modules com.spacey.explorer depends on, you first need to determine those, for example with jdeps (see also nullpointer's answer). Once you know those modules, you can define them as root modules with --add-modules.

In your example:

$ jlink 
    --module-path /opt/jdk-9/jmods
    --add-modules java.base
    --output ~/custom-jre-for-explorer

If there were more modules than just java.base, say java.sql, the command would look as follows:

$ jlink 
    --module-path /opt/jdk-9/jmods
    --add-modules java.base,java.sql
    --output ~/custom-jre-for-explorer