The Fastest Way to get the Version of a Java Installation

Last week, I demonstrated that OpenJDK is faster than GraalVM Java, at least for obtaining the Java version. This even prompted the mighty Thomas Wuerthinger (creator of GraalVM) to react. But the measured ~20ms for the OpenJDK is still too slow for applications like execjar, where it could significantly increase the runtime of short-running CLI tools. In this week’s brief blog post, I’ll show you the fastest way to access the Java version.

The main performance issue is that calling java -version creates a process with a fairly large (around 38MB) maximum resident set size, and using a proper command line parser. But do we actually need to call the java binary to get the version?

TL;DR: I created the java-version tool, which can obtain the Java version in under a millisecond.

Basic Idea

No, we can just realize that most Java installations have a release file that contains the relevant information in a machine-readable format. You can find this file in the main folder of the installation (./release when java is in ./bin).

Continue reading

OpenJDK is faster than GraalVM Java*

Well, we all know that the most crucial feature of the JVM runtime is the -version output. So how does the OpenJDK (in the form of SapMachine) compare with GraalVM? It’s significantly faster. Using hyperfine, we can see that GraalVM 25 CE takes almost twice as long to emit the version number as a regular SapMachine 25 on my MacBook Pro M5:

The slowness of java -version was actually one of the performance issues of the tool I showcased in How to Build an Executable from a JAR using ExecJAR, as it originally used java -version a lot to check the Java version constraint.

Is this relevant? Not really. However, so are most microbenchmarks and benchmarks in general that are taken out of context. You should not generalize small benchmarks, and modern systems are complex.

You can find some bigger, non-version-related benchmarks comparing the different JVMs, for example, at https://ionutbalosin.com/2024/02/jvm-performance-comparison-for-jdk-21/.

Join me next week for a blog post on something different and learn how to check the version of a Java installation even faster in under one millisecond:

P.S.: I just ran some more benchmarks: OpenJDK 25 is 18% faster than OpenJDK 17 and 21 and a whopping 84% faster than OpenJDK 11. Upgrade now!

P.P.S.: As many people (Thomas Wuerthinger, Fabio Niebhaus, Volker Simonis, and multiple of my SapMachine colleagues) pointed out, the differences between OpenJDK and GraalVM are due to the GraalVM initializing the JVM Compiler Interface (JVMCI). The difference between the two becomes negligible when running OpenJDK with enabled JVMCI (initialize the JIT at the beginning):

How to Build an Executable from a JAR using ExecJAR

In my last blog post, I covered a new tool called jstall, which enables you to quickly check on a Java application. Because it was tiresome to always call the tool via java -jar jstall, I looked for a way to create executables directly from JARs, inspired by async-profiler’s build system. And I, of course, went down a rabbit hole. In this blog post, I’ll show you how use execjar to easily create your own executable JARs that you can execute directly on the command line while still being valid JARs.

TL;DR: execjar is a CLI and Maven plugin that enables you to create executables from JARs by just adding a few lines to your Maven file:

<plugin>
  <groupId>me.bechberger</groupId>
  <artifactId>execjar</artifactId>
  <version>0.1.1</version>
  <executions>
    <execution>
      <goals>
        <goal>execjar</goal>
      </goals>
    </execution>
  </executions>
</plugin>

When your project is called jstall, this creates an executable with the same name that you can execute directly via ./jstall.

Important: The resulting executable is compatible only with UNIX (Linux and macOS) environments.

However, before I delve into the in-depth configuration options of my new tool, I’d like to provide some background on its implementation.

Continue reading