Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating custom runtime image dedicated for specific modular application

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?

like image 788
malloc4k Avatar asked Sep 20 '17 20:09

malloc4k


2 Answers

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
like image 126
Naman Avatar answered Oct 22 '22 15:10

Naman


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
like image 21
Nicolai Parlog Avatar answered Oct 22 '22 14:10

Nicolai Parlog