Along the previous parts of the tutorial we have talked a lot about GraalVM‘s groundbreaking impact on the JVM, its future and the ecosystem. The question we have left with is: if GraalVM is so awesome, and most of the time, is a drop-in replacement for traditional OpenJDK distribution, should it become the default choice for everyone? Yes, for things like serverless computing, polyglot development with Truffle and building native executable images, GraalVM is the only option, at least for the time being.
Table Of Contents
But what about the typical enterprise applications where, like it or not, the performance is often not a priority? Or, unless you are stuck with application server for good, most of the time bundling a shrunken OpenJDK distribution (thanks to jlink) along with runnable JAR is totally fine. It becomes even more appealing with container images and layered JARs. Yes, at the end the image size is still noticeable and the JVM startup time adds up, but is it that important for your application or service?
The goal of this section of the tutorial is to understand the role of GraalVM for average Java developer working on yet another aging enterprise platform. Let us forget about the cutting edge technologies and focus on unpleasant reality.
In most cases, you should be able to substitute your OpenJDK distribution with the one GraalVM comes with (8 or 11) and your applications or/and services should not even notice. Would you benefit from the GraalVM compiler optimizations? It is very likely so but better measure, do not guess.
By switching to the JVM bundled with GraalVM, your development workflow stays unchanged. You have the same familiar tooling at your disposal, including debuggers and profiles, plus some new ones from GraalVM toolbox.
Everything turns upside down when you adopt native executables. Let us face it, producing native images is very slow and resource intensive. It is unrealistic to rebuild one on every simple change in the code. Also, troubleshooting native image build issues got much better (you could even attach the debugger) but by and large, it is still very painful and time consuming. The same applies to the runtime errors you may encounter while running the native executable but debugging those is a different story.
For production, the things are a bit trickier. The GraalVM compiler is not experimental anymore but still there are chances the bugs may sneak in (you surely do not want to wake up at night because the code generation crashes the JVM).
The native executable comes with limited set of garbage collectors (only Serial GC in community edition) which may not be best option for your particular application or service. The heap dumps generation needs to be baked in as well. The lack of comprehensive monitoring and diagnostic instrumentation (JDK Flight Recorder support is still in development) points to the rough ride ahead.
For an existing applications and services, often bearing “legacy” or “brown field” labels, the benefits of the GraalVM might be somewhat constrained. For example, it is very unluckily you would be able to produce native executables without investing substantial efforts and/or sending tons of patches to the upstream dependencies. On the contrary side, green field applications and services have all the chances to leverage a full spectrum of the GraalVM capabilities by carefully choosing the frameworks and/or libraries to build and depend upon.
For a number of years, the Spring Projects portfolio has been the most popular choice for building JVM-based applications and services. And it still is these days. With recently released Spring Native Beta it made one step closer to being fully compatible with GraalVM’s generation of native images. However, in order to try it out, you may need to update to the latest release baselines. It is worth the goal with or without GraalVM but, depending on your particular situation, could be difficult to pull off.
The Micronaut framework, being GraalVM friendly from the early days, offers a familiar Spring-like experience for the developers looking after cloud-native trends. You may still run into a number of the limitations but the one thing you could be sure of is a first-class GraalVM support.
It the same vein, Microprofile with its focus on microservices is gaining a lot of momentum. The frameworks like Quarkus and Helidon heavily rely on GraalVM platform to bring Microprofile on the edge of cloud computing. But like any new technology, these need learning, practicing and knowing the limitations in order to deliver the productivity boost.
So, should you prefer GraalVM over bare OpenJDK? As always, it may sound boring but the answer is “it depends”. The advantages are clear, especially for certain kinds of application and services, but so do the risks and hurdles.
The one thing that seems to be conclusive: the GraalVM compiler is going to see improvements and learn new optimizations with each release, but innovations on the Java HotSpot VM C2 compiler seems to be stalled. Maturity is king but you have a choice to start experimenting with GraalVM and assess the potential performance gains for your applications and services today.
In the next, final part of the tutorial we are going to talk about some future developments which are happening in GraalVM ecosystem right now and make some wild guesses regarding its future.