Skip to content

Latest commit

 

History

History
131 lines (78 loc) · 6.93 KB

README.adoc

File metadata and controls

131 lines (78 loc) · 6.93 KB

Building native CLI apps in Java with picocli and GraalVM

Appveyor Build Status GitHub Action Build Status Travis Build Status

Examples for creating GraalVM native images for picocli-based applications

Caution
Below is work in progress
exe picocli on graalvm

Introduction

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 Gradle, see picocli-native-image-maven-demo for a Maven build example.

Artifacts

CheckSum

The main project builds a checksum executable. This is a picocli-based command line application. On Windows it uses Jansi to show colors on the console and the picocli-jansi-graalvm library to enable the Jansi library for GraalVM native applications.

HTTPS

There is also a https subproject that builds a demo native executable with https-client and https-server subcommands to demonstrate HTTPS TSL client and server applications. The server uses a self-signed certificate.

The https subproject also demonstrates that it is possible to build native TSL applications with GraalVM that work without the libsunec.so or sunec.dll library.

This can be achieved by specifying a -J-Djava.security.properties=/full/path/to/java.security.overrides option when building the native image. The specified java.security.overrides file contains an entry for security.provider.3 with a non-existing value. This disables the SunEC elliptical curve encryption provider, which would have required the libsunec.so or sunec.dll native library.

Windows Note

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.

Testing Native Images

This project uses JUnit 5 for testing. It has unit tests that can be run before the JAR file is created, and integration tests that can only be run after the native image is generated.

The integration tests are tagged with @org.junit.jupiter.api.Tag("native-image").

The Gradle build is configured to create the native image before running any of the tests.

Cross Compilation

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 a Continuous Integration setup, using GitHub Actions, AppVeyor and TravisCI. The current setup creates Linux and MacOS executables with GitHub Actions, and a Windows executable on AppVeyor and TravisCI.

Install Compiler Toolchain

The setup for your Continuous Integration environment needs to have a JDK, and the toolchain to compile C/C++ code.

Linux and MacOS Compiler Toolchain

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.

Windows Compiler Toolchain for Java 8

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.

Windows Compiler Toolchain for Java 11

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\Community\VC\Auxiliary\Build\vcvars64.bat"

Then run native-image in that Command Prompt window.