The long-awaited Java 9 has finally been released ahead of JavaOne 2017!
By the way, speaking of Java 9, what is of concern is the module function by jigsaw. I often see how to use the module, but I was personally interested in jlink, so I summarized the results I tried.
Regarding Jigsaw, at least for now, it's not possible to replace a single binary like fat-jar or go language alone.
However, it is possible to generate a JVM for distribution including the application by using the module and jlink, and this time I will explain about it. I will not mention that the module has made it possible to improve the disclosure range and detect dependencies early, so I will talk about this article % B5% E3% 83% BC% E3% 83% 93% E3% 82% B9% E3% 81% 8C% E5% BF% 85% E8% A6% 81% E3% 81% A8% E3% 81% 99 % E3% 82% 8B% E3% 83% A9% E3% 82% A4% E3% 83% 96% E3% 83% A9% E3% 83% AA) I think you should refer to it.
First, prepare the code. Make a sample that the library is called in three layers from the application like the following.
What was made here. I will omit the details because I will not talk about it in particular, but I put module-info.java
in each top directory and write the module settings.
https://github.com/koduki/example-jlink
Next is the build of each module.
Before that, first create a directory for module placement.
$ mkdir modules
Obviously, we will build in order from the one with no dependency.
$ javac -d commons/classes/ -cp commons/src/main/java $(find commons/src/main/java -name "*.java")
$ jar cvf modules/commons.jar -C commons/classes/ .
The build looks basically the same as a normal jar, except that you specify the module directory with the p
option at compile time.
Also, be aware that older versions have the option listed as mp
.
$ javac -d libs/classes/ -cp "libs/src/main/java/" -p modules/ $(find libs/src/main/java -name "*.java")
$ jar cvf modules/libs.jar -C libs/classes/ .
Once the library is built, the main application. However, this is just like the others.
$ javac -d apps/classes/ -cp apps/src/ -p modules $(find apps/src -name "*.java")
$ jar cvf modules/app.jar -C apps/classes/ .
It can be executed in the following form.
$ java -p modules/ -m apps/cn.orz.pascal.app.MyApp
Hello, cn.orz.pascal.common.CommonLib
Hello, cn.orz.pascal.lib.MyLib
Hello, MyApp
Did you confirm the execution? When specifying a module, describe it in the form of module name / class to be executed
with the m
option.
With this alone, I'm not very happy from the distribution point of view, so it's finally time for JLink. With JLink, you can create a JVM with the minimum configuration required for the specified module. This means that you don't have to have a Swing or AWT library in your web app.
In the case of Mac, if you just installed it, the path does not pass, so correspond as follows.
$ export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/
$ alias jlink=${JAVA_HOME}/bin/jlink
Next is the execution of the link by jlink. This time, I also created a launcher that executes ʻapps / cn.orz.pascal.app.MyApp` and compressed the whole with zip.
$ jlink --compress=2 --module-path $JAVA_HOME/jmods:modules --add-modules apps --output dist/my-app --launcher myapp=apps/cn.orz.pascal.app.MyApp
When executed, my-app is created in the dist directory. When executed, it is as follows.
$ ./dist/my-app/bin/myapp
Hello, cn.orz.pascal.common.CommonLib
Hello, cn.orz.pascal.lib.MyLib
Hello, MyApp
Since my-app contains the specified module and the JVM with the minimum configuration, just distribute this directory and it will work as it is even in an environment without a JVM. It's portable!
The capacity is as follows this time. It feels pretty good.
$ du -h dist|tail -n1
24M dist
I tried how to make a JVM for application distribution by jlink. Although it is not packaged, it seems to be a lot easier to distribute to an environment where the JVM is not installed. If it's for server use, wouldn't it be a problem if you package it in Docker?
It is not suitable for distribution in a single binary such as command system, which was realized by go language or java fat-jar, but I think that it can be fully realized if something like electron-packager is made in the future.
Well then, Happy Hacking!
Recommended Posts