Creating a native executable in Windows with GraalVM
Tags: java, graalvm, windows, tutorial
Published: 2019-06-12 00:33:00

[GraalVM](https://www.graalvm.org/) is pretty awesome for [a lot of reasons](https://www.graalvm.org/docs/why-graal/). But the one that has me most hyped is the ability to create native executables from Java bytecode. This isn't like ExcelsiorJET (R.I.P.), which makes you include a large runtime, nor is it like [Launch4J](http://launch4j.sourceforge.net/) and Oracle's `javapackager` tool, both of which create a dummy executables that points to your `.jar` and a packaged JRE.

GraalVM makes *real* native executables without a packaged runtime.

Unfortunately, GraalVM's `native-image`, and indeed its entire support for Windows, is in early adopter status. There are some error messages that aren't accurate, some bugs, and some features missing.

But it does work, more-or-less.

## Things to know before you get started

There's about a 8.5 MB minimum file size for a bare bones `hello world` java application. That's kind of a lot, but also a lot less than including the entire JRE.

Some other articles or guides recommend installing [Git for Windows](https://git-scm.com/downloads) and [Python 2.7](https://www.python.org/downloads/release/python-2713/), but I'm like 99% sure that's for building GraalVM before running. 

All the Swing and JavaFX applications I've tried haven't been able to build in the Windows version of `native-image` in 19.0.0.

The [Image Generation Options](https://www.graalvm.org/docs/reference-manual/aot-compilation/#image-generation-options) page is a good resource for troubleshooting, you may have to place some of your classes into the `--initialize-at-run-time=<comma separated list of class/package names>` option.

## Steps to run GraalVM 19.0.0's `native-image` in Windows

1. Uninstall any `Visual C++ 2010 Redistributable`s
1. Get the Windows version of GraalVM 19.0.0: <https://github.com/oracle/graal/releases/tag/vm-19.0.0>
1. Extract it somewhere easy to find
1. Get the Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO): <https://www.microsoft.com/en-us/download/details.aspx?id=8442>
1. Mount the image, open `F:\Setup\SDKSetup.exe` directly
1. A default install should be perfect
1. **Run the Windows SDK 7.1 Command Prompt** by going to `Start` > `Microsoft Windows SDK v7.1` > `Windows SDK 7.1 Command Prompt`
1. Run one of these commands based on if you have a `.jar` or a `.class`:
```
\path\to\graalvm-ce-19.0.0\bin\native-image -jar \path\to\helloworld.jar --no-fallback
```
or
```
\path\to\graalvm-ce-19.0.0\bin\native-image \path\to\helloworld.class --no-fallback
```

The `*.exp`, `*.lib`, and `*.pdb` files seem to be artifacts of the build process, they're not required for distribution.

But that's it, your `.exe` is made! 

## Update: As of GraalVM 19.3.0, still no support for Swing nor JavaFX.

For GraalVM 19.3.0 on Windows with the new support for Java 11, you'll need `Visual Studio 2017 Community Edition` instead of the `Microsoft Windows SDK for Windows 7`, which you can [get here](https://my.visualstudio.com/Downloads?q=visual%20studio%202017&wt.mc_id=o~msft~vscom~older-downloads) with a free Visual Studio Dev Essentials account. Instead of running the `Windows SDK 7.1 Command Prompt`, you'll of course run `x64 Native Tools Command Prompt for VS 2017` as your command line in `Start` > `Visual Studio 2017`.

Gluon is [working on](https://gluonhq.com/gluon-substrate-and-graalvm-native-image-with-javafx-support/) providing JavaFX support for 19.3.0 - it already has it for macOS and Linux, and Windows should be coming soon.

Finally, if you do distribute an exe made with native-image on windows, you will need to include `vcruntime140.dll` with it, which is about 84kb.