This project shows examples of creating native images for picocli-based Java command line applications that can run as standalone executables on Windows, Linux and MacOS without requiring a JVM to be installed.
This project uses Maven, see the picocli-native-image-demo project for an example that uses Gradle.
The Windows executables created with the Java 8 version of GraalVM depend on the msvcr100.dll
native library.
Windows executables created with the Java 11 version of GraalVM depend on the VCRUNTIME140.dll
native library.
You will have to distribute these DLLs with your application, or tell your users to download and install the Microsoft Visual C++ 2015 Redistributable Update 3 RC to get the VCRUNTIME140.dll
for Java 11-based native images, or Microsoft Visual C++ 2010 SP1 Redistributable Package (x64) to get the msvcr100.dll
for Java 8-based native images.
This project uses JUnit 5 for testing. It has a unit test that is run before the JAR file is created, and an integration test that is run after the native image is generated.
The integration test is tagged with @org.junit.jupiter.api.Tag("native-image")
,
and this tag is used in the Maven Surefire and Maven Failsafe plugins to ensure that only the unit tests run before the JAR is created,
and only the integration tests are run after the native image has been generated.
GraalVM does not have cross-compile support for native images yet, so at the moment you need to compile on Windows to get a Windows executable, compile on Linux to get a Linux executable, and on MacOS to get a MacOS executable.
This project shows how to do this with TravisCI. The current setup creates Linux, MacOS and Windows executables on TravisCI.
This project provides a install-graal.sh
script to install GraalVM for Linux,
and a install-graal.cmd
Windows version.
The Windows version will also attempt install the Windows Compiler Toolchain for the selected Java version via chocolatey if it does not exist.
The install script will cache the download and installation in ~/.m2/caches/info.picocli.graal
, so that subsequent invocations can reuse the previously downloaded GraalVM installation.
The script will set the JAVA_HOME
variable to the GraalVM installation directory.
Always run the install-graal
script before running the mvnw clean verify
build with Maven.
An alternative for Unix-based systems is to use the bash-based SDKMAN! to install and manage the GraalVM installation.
Windows Git Bash users may need to download zip
, which is not included by Windows Git Bash by default.
To resolve this, go to https://sourceforge.net/projects/gnuwin32/files/ and find zip in the list.
Download zip-3.0-bin.zip
and extract zip.exe in the bin folder. Copy it to c:\Program Files\Git\usr\bin.
Now run the SDKMan install script again.
The setup for your Continuous Integration environment needs to have a JDK, and the toolchain to compile C/C++ code.
For compilation native-image
depends on the local toolchain, so on Linux and MacOS we need glibc-devel
, zlib-devel
(header files for the C library and zlib) and gcc
to be available on our system. The below is not required with GitHub Actions, since these are already available:
On Linux: sudo dnf install gcc glibc-devel zlib-devel
or sudo apt-get install build-essential libz-dev
.
On macOS, execute xcode-select --install
.
Note
|
It turns out to be surprisingly difficult to get the below toolchain set up in the various CI build environments. I recommend using the setup for Java 11 instead. Many CI build environments already have visualstudio2017-workload-vctools set up, so all that is needed is to activate the environment. |
To build native images using the Java 8 version of GraalVM, you need the Microsoft Windows SDK for Windows 7 and .NET Framework 4 as well as the C compilers from KB2519277. You can install these using chocolatey:
choco install windows-sdk-7.1 kb2519277
Then (from the cmd
prompt), activate the sdk-7.1 environment:
call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd"
This starts a new Command Prompt, with the sdk-7.1 environment enabled. All subsequent commands must be run in this Command Prompt window.
To build native images using the Java 11 version of GraalVM (19.3.0 and greater), install the Visual C++ Build Tools Workload for Visual Studio 2017 Build Tools using chocolatey:
choco install visualstudio2017-workload-vctools
After installation, set up the environment from the cmd
prompt with this command:
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat"
Then run native-image
in that Command Prompt window.
The Graal team publishes
a Maven plugin called native-image-maven-plugin
that can invoke the native-image
generation tool.
This project uses this plugin for generating a native image.
The native-image-maven-plugin
Maven plugin is not as powerful as the Palantir Gradle-Graal plugin,
in that it requires GraalVM to be installed; it cannot download and install GraalVM for you.
This project provides install-graal
scripts that take care of the GraalVM installation.
Always run the install-graal
script before running the mvnw clean verify
build with Maven.
The script will set the JAVA_HOME
variable to the GraalVM installation directory.
On Windows, this script will activate the sdk-7.1 environment.
You can pass additional arguments to the underlying native-image
generator command with the buildArgs
system property.
On Linux, you may want to run the maven build with:
./mvnw -DbuildArgs=--no-server clean verify