With Java 9, a new tool called jlink was introduced. It combines modules and builds an all-in runtime image. On the one hand, the whole 32 bit ARM JDK can be run on a PLCnext Control. But with jlink and modules it is possible to reduce the resources needed for your Java application. It creates a bundle with just the necessary parts of the JDK needed for your application.
Prerequisites
- JDK for your host system
- JDK for the controller
The binaries of OpenJDK for a lot of platforms can be found e.g. on AdoptOpenJDK. For this tutorial, we chose the Linux arm32 jdk-12.0.2+10 for the controller and its pendant for a Windows x64 host system. We are using the following location of the JDKs:
C:
---Java
|
+---jdk-12.0.2
| ...
|
---jdk-12-ARM-32bit
...
Create an application module
In this example we are just printing a Hello World on the console. To use jlink we have to put this small application into a module. My starting point on the terminal is a folder called “HelloWorld” and a src folder with the following structure.
HelloWorld
---src
---de.plcnext.hello
| module-info.java
|
---de
---plcnext
---hello
HelloWorld.java
This is our small code example in the HelloWorld.java file:
package de.plcnext.hello;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello PLCnext world!");
}
}
And the module-info.java is needed to create the module:
module de.pxc.hello { }
After creating the source folder we compile our project. For this we use the following command on the terminal.
C:Javajdk-12.0.2binjavac.exe -d .modulesde.plcnext.hello .srcde.plcnext.hellodeplcnexthelloHelloWorld.java .srcde.plcnext.hellomodule-info.java
A modules folder and java classes are created:
HelloWorld
---modules
---de.plcnext.hello
| module-info.class
|
---de
---plcnext
---hello
HelloWorld.class
To test our module on the host system, we can run it with the following command:
C:Javajdk-12.0.2binjava.exe --module-path .modules -m de.plcnext.hello/de.plcnext.hello.HelloWorld
This should output Hello PLCnext world!
.
How to use jlink
Now we want to get this onto our device without the whole 300MB JDK. For this we are using jlink without any additional parameters in the first step. But at first we need one more information, which additional modules are needed. This we will find out by analyzing our module with jdeps.
C:Javajdk-12.0.2binjdeps.exe --module-path ".modules" --add-modules "de.plcnext.hello"
This tells us, we need java.base
additionally to our module. As module-path
we pick the path to our application and the path to the jmods of our target platform JDK. In this case C:Javajdk-12-ARM-32bitjmods
.
Now our jlink call looks like this:
C:Javajdk-12.0.2binjlink.exe --module-path ".modules;C:Javajdk-12-ARM-32bitjmods" --add-modules "de.plcnext.hello,java.base" --output HelloWorldjre
HINT: Pay attention to the separators of the
module-path
andadd-modules
values these are dependent to the terminal you use.
The result is a HelloWorldjre
folder with only about 45MB. We copy this to our controller. In case of this example to /opt/plcnext/projects/java/
. We need to make the “java” file in the HelloWorldjre binary folder executable via chmod +x java
and start our module
./java -m de.plcnext.hello/de.plcnext.hello.HelloWorld
It should run the application and output like before Hello PLCnext world!
. By using some additional parameters of jlink you can strip down the package even more (in this example down to 28MB) by using --strip-debug
, --no-header-files
, --no-man-pages
and --compress=2
. Where are compression safes the most but could harm the performance at the end.
Leave a Reply
You must be logged in to post a comment.