Java Script with GraalVM – or writing software that is directly executable

This is about writing java software that does not need a JVM in order to execute it. For this the GraalVM can be used. In the end it provides a binary that is ways smaller than a full JVM and can directly be executed on the target operating system.

Why should it be used?

Well, good question. There are multiple use cases:

Small java programm

Write a small java program instead of a script and have the full power of the java ecosystem like libraries, tooling, IDEs and testing capabilities.

Use it in a docker image

Instead of using a docker image that contains a java runtime simply build a binary and then put into the image and then run it.

Deliver binary software

Another use case could be that the software should be delivered as a binary that directly can be executed. So simply put e.g. a full Java EE/Jakarta EE or Spring Boot application into this binary and simply run it.

You want to use another language

It is possible to use GraalVM with JavaScript, Python, Ruby, R or e.g. Groovy. Even C or C++ would be possible. But that’s another thing. The focus will on Java.

Pros and Cons

+ No JVM required for running java software
+ Small footprint for usage in docker compared to an image with java installed
+ Fancy way of writing scripts

– Compared to a script quite huge binary
– Precompiled and optimized binary -> The main advantage of the JIT of java cannot be used.
– Hard to analyze problems an by default the java tooling for profiling and analysis of running JVMs is not working

How to use it

Install it

Simply download GraalVM and then unpack it. Now there is the assumption there is a folder called graalvm-ce-java11-20.0.0 in the directory /home/user/Downloads

Then add the /home/user/Downloads/graalvm-ce-java11-20.0.0/bin to the $GRAALVM_HOME variable. E.g. by using

Then run ${GRAALVM_HOME}/bin/gu install native-image. This provides the necessary tool for creating a binary.

Alternatively you can add the binaries to your $PATH and then simply run it.

Write it

Simply download this archive for getting started the fast way.

It contains a java class with the main method. Then there will be jar having that main class in it’s meta data. This will be built with java 11 by using gradle and using the gradle wrapper.

Of course there can added some libraries as dependencies to the build and then include them directly into the resulting jar. This program only outputs Hello World! in order to demonstrate how this works at all.

Build it

Simply build the java with gradle. There is no need to download anything, but of course there must be at least java 11 installed.

Then build the native image via

This generates the binary called shell-java.

Run it

Simply run

That’s it!

Something about the performance

In order to measure the runtime of the Hello World simply run:

This prints the nanoseconds before and after the execution. In this case the execution time is about 9 ms. Ok this is not a highly precise result but it was about that time every time it was executed. This was with java 11. Trying this with java 8 as well and the result was about the same.

Now doing the same with running the jar with java

This is about 300 ms and thus about 30 times slower than the binary!

And something about the size of the binary

Well the binary is 6867104 bytes in size and therefore 6.6 MiB. This is with java 11. Repeating the same with java 8 (ok a little bit old fashioned) and there the size was about 3,4 MiB. The size of the jar is 730 bytes. Decide yourself whether this is good or not.

Sources

GraalVM
GraalVM Community Edition Release Downloads
GraalVM for java 11 and Linux AMD64 architecture
GraalVM Documentation

Leave a Reply

Your email address will not be published.

Time limit is exhausted. Please reload CAPTCHA.