About 10 years after Java’s inception in 1996, Sun Microsystems released OpenJDK in 2007, a free and open-source implementation of Java SE. Many companies started to join as contributors.
Even though other JDK builds were available, most of us weren’t even aware of them. But things changed with Oracle’s new licensing model for Java, which came into effect in January 2019.
The Oracle Java SE is now restricted to personal or non-commercial development, testing, prototyping, demonstrating, etc.
Any other scenario requires a monthly subscription.
But don’t worry, Java still is, and will always be free. We just have to choose a different JDK variant.
Reference Implementation (RI)
Using OpenJDK instead of Oracle Java SE doesn’t mean that we have to forgo any features.
Since OpenJDK 7, it’s the official reference implementation of Java SE. And since Java 10, OpenJDK is even responsible for the JDK project, delivering a new release every six months.
On the surface, the different JDK options are identical, because they must adhere to the Java specification. The Java Compatibility Kit (JCK) ensures this, or you can’t call your build JavaSE compatible.
The most significant differences come from supporting tools, default settings, offered support, and security patches.
Free and Open Source JDKs
The free and open-source implementation of Java SE, initiated by Sun. All other JDKs are based on this codebase. Builds are maintained and provided by Oracle.
Starting with Java 11, OpenJDK also includes many of the previous commercial features, like Java Flight Recorder and Java Mission Control, making this build virtually identical to the Oracle JDK builds.
The release cycle is 6 months, to provide smaller, more manageable improvements, that are easier to adopt. But this also means reduced support lifetimes, and only the newest builds are available on their homepage. But many package managers have multiple versions available.
Even though the OpenJDK source code was available, there was a lack of readily available and reproducible builds across multiple platforms. To fix this nuisance, AdoptOpenJDK.net was started by a community of Java User Group (JUG) members, developers, and vendors, in 2017.
It will provide an as-is build from the OpenJDK upstream source. AdoptOpenJDK isn’t an entity supplying and maintaining its own fork or version.
The father of Java, James Gosling, announced Amazon Coretto in his keynote at Devoxx Belgium 2018. Amazon runs its services on this build and decided to open-source its efforts and make it available outside of AWS.
It’s a no-cost, multi-platform, production-ready distribution of OpenJDK.
The release cycle is at least quarterly, including free long-term support. All patches will go upstream to OpenJDK, so the whole ecosystem will profit from them.
Java 8 and 11 are available, with LTS until 2023 and 2024.
Java LTS versions 8 and 11 are available.
Another big Java contributor is Bellsoft, which I frankly never heard of before…
Their JDK is available for multiple platforms, including embedded architectures, like ARM-based systems. Additionally, all builds contain LibericaFX, an OpenFX/JavaFX variant.
Java LTS versions 8 and 11 are available, as is the current version 13. For embedded platforms, LTS versions 8 and 11 are available, too.
Maintained by SAP SE, a German multinational enterprise software corporation. Intended to provide a friendly fork and SAP-supported version for their customers and partners.
New features will be contributed upstream to OpenJDK. If not accepted, it still might be included in SapMachine, and even backported to earlier versions.
Java LTS version 11 is available and supported until 2022/09. Only the latest non-LTS version is available (at the moment of writing Java 14), supported until 2020/09. Older versions are available in the archives.
Zulu is a branded version of the OpenJDK, but free to use, without any restrictions. Optional paid support is offered by the maintainer, Azul Systems.
Java LTS versions 7, 8, and 11 are available, and the two latest non-LTS 13, and 14.
The original commercial Java version, which can’t be used in production for free. To justify the costs, additional tooling is available, as is paid support.
Java LTS versions 8 and 11 are available. Only the latest non-LTS versions.
Which to Choose?
Having choices is great.
But from a high-level point-of-view, it doesn’t really matter much which JDK we choose. All of them are based on the original upstream OpenJDK source and passed the JCK to be compatible with the JavaSE spec.
The real questions we must ask are based on our project requirements:
- Is it free, or do I need to buy a license?
- How long are the builds available?
- Are security patches backported, or do we have to switch to the next version?
- What are the support lifetimes? Are LTS versions available?
- Do we need special optimizations for our application?
- Which JVM do I want or need?
- Can we get paid support if required?
For most use-cases, you can’t go wrong with using an OpenJDK build, either from Oracle, or AdoptOpenJDK. We’ve been using one or the other for quite some time, without any issues.
The other options are a good choice for special cases, like vendor-optimizations, or embedded system-support.
Working with multiple JDKs
Such a variety of options leads to another question: How can I use multiple versions simultaneously?
Thankfully there are multiple tools available to simplify switching between different JDKs.
A command-line tool, available for Linux and macOS, helping to manage
JAVA_HOME on a global and local level.
# ADD JDK $ jenv add <path to JDK> # LIST VERSIONS $ jenv versions # SET DEFAULT $ jenv global <version> # SET LOCAL $ jenv local <version> # SET CURRENT SHELL $ jenv shell <version>
The Software Development Kit Manager is a tool for managing multiple SDKs on most Unix-based systems and is not restricted to just JDKs.
# ADD JDK $ sdk install java <version> # LIST VERSIONS $ sdk list java # SET DEFAULT $ sdk default java <version> # SET LOCAL # There doesn't seem to be a way to set locally # SET CURRENT SHELL $ sdk use <version>
A version manager inspired by the Node Version Manager.
# LIST INSTALLABLE VERSIONS $ jabba ls-remote # ADD JDK $ jabba install <version> # LIST VERSIONS $ jabba ls # SET DEFAULT $ jabba alias default <version> # SET LOCAL $echo <version> .jabbarc # ACTIVATE LOCAL VERSION $ jabba use
Update Java Alternatives
update-java-alternatives helps to switch between installed JDKs.
# LIST VERSIONS $ update-java-alternatives --list # SET VERSION $ update-java-alternatives --set <path to JDK>