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?
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.
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With