Week 79 — Which options are there for packaging Java applications as native executables?
Question of the Week #79
Which options are there for packaging Java applications as native executables?
3 Replies
Before creating a native executable, one should have a JAR file with the application to package.
Assume a simple main class in a file
SimpleMain.java
:
It is possible to compile that class and create a runnable JAR file as follows:
This should create a JAR file SimpleApplication.jar
in the directory jarDir
containing SimpleMain.class
that runs the SimpleMain
class when being used with java -jar
.
Running java -jar jarDir/SimpleApplication.jar
should print Hello World
.
Once a JAR with the application is obtained, it is possible to create an installer that installs a JRE with the JAR using jpackage
. The --input
argument specifies a directory that should be included in the installation, --main-jar
refers to the JAR with the main class (which should be located in the input directory) and --main-class
refers to the fully-qualified name of the main class. It is also possible to specify a name using --name
or use other options for configuring various things about the application.
By default, the jpackage
command creates an installer for the current platform (like msi
, dmg
or deb
).
After installing, the application should be available on the system.
As most applications don't need all JDK modules, it's possible to explicitly specify the modules to include in the installer using --add-modules
:
The module java.base
is required for all applications and jdk.zipfs
is necessary for handling JAR files.
The modules required by an application can be looked up using the jdeps
command:
If the application is has a module-info.java
, it is also possible to create the installer from the modulepath:
where MODULE_PATH
refers to the modulepath (either with JARs or with directories containing the class files) and MODULE_NAME
should be replaced with the name of the module.Another option to package a Java application is using the
native-image
tool provided by GraalVM.
Instead of creating an installer, this will create a native executable with the application compiled for a specific platform.
Once the JAR is created, a native executable of it can be created using the command
where jarDir/SimpleApplication.jar
is the JAR containing the application.
Alternatively, it is also possible to from a directory with the .class
files or multiple JAR files by specifying the class path:
or by specifying the modulepath if the application is modular:
If reflection, JNI, resources, proxy classes or similar things are used, these need to be specified as arguments to native-image
. See also https://discord.com/channels/648956210850299986/1099004918007865404 for more information on that.📖 Sample answer from dan1st
there is GraalVM Native Image, Excelsior JET, Launch4jJWrapper, Packr, Install4j
Submission from chandrashekhar_