Get Ready for the New Decade of Java Software Development: Java Versions, Distributions, and Platforms

Oct 7th - 2024
By
Belatrix

Back in 1995, a team of engineers from Sun Microsystems was trying to come up with a name for their new software platform and programming language. In a brainstorming session that’s still somewhat shrouded in mystery, they chose the name Java – a nickname for coffee (hence the logo) since, in its early days, coffee mostly originated from the Indonesian island of Java.

Fast forward to today and, just like coffee, Java now comes in many flavors.

There are many JDK distributions to choose from, and new Java versions released much faster than ever before. There are also JVM and garbage collector optimizations, frameworks that simplify the development of Java-based microservices, and an overall drive to make Java competitive in cloud-native environments.

As 2020 marks Java’s 25th birthday, the Java landscape is more diverse and dynamic than ever.

Is Java Still Free?

This is an interesting question that everyone is asking.

Oracle tried to settle this issue once and for all at the Jax London Conference for Java & Software Innovation 2019, which included over 60 sessions, hands-on workshops, and insightful keynotes. It was quite exciting to be in the presence of so many speakers, thinkers, and innovators from the world’s leading tech teams.

Discover some key takeaways from the conference that will bring you up-to-date with what’s happening at the core of the Java platform.

Learn from Pentalog's Kanban Master Vlad Georgescu at Jax London 2019 as he shares his insights on Java versions, team happiness, and fostering healthy business growth in software development.
  • Pentalog’s Kanban Master & Project Director, Vlad Georgescu, shared his inspirational ideas at Jax London 2019. His mission at Pentalog is to create happy teams and grow healthy businesses. Find out how!

Oracle’s announcement in 2018 that public updates for the distributions of Java 8 and 11 will no longer be free of charge caused concern and confusion in the tech community. The fact that Java was free for commercial use gave it an edge over its competitors, and this was suddenly gone.

Or wasn’t it?

Java community leaders quickly responded with an open letter (reassuringly titled Java is still free), in which they explained and advocated for the use of production-ready, free alternatives to the Oracle build.

But how does this type of build happen?

Primarily, it must implement the Java SE specification, generally building upon the OpenJDK source code. Additionally, to be considered a Java SE-compatible implementation, it must pass the TCK (Technology Compatibility Kit) test suite.

For the record, OpenJDK is the free, open-source, reference implementation of Java SE, collectively developed and maintained by Oracle, the OpenJDK and Java communities, Red Hat, Azul Systems, IBM, Apple, SAP, etc. Developers release it under the GNU General Public License (GNU GPL) v2. All of the major JDK distributions out there (including Oracle’s own Java SE) are basically derived from OpenJDK.

Which Java Versions and Distributions Should You Use?

First of all, be aware that there are underlying costs if you decide to use the latest Java versions (11+) of Oracle Java SE in production. To be fair, Oracle justifies its new license model by heavily investing in developing and patching Java. They also still provide their own free-to-use OpenJDK distribution, which has only some minor differences from the paid version, while both have the same applied security patches.

The good news is, there are plenty of alternatives to choose from.

As recommended by the community, a reliable choice is AdoptOpenJDK – a distribution developed in part by the community, free for commercial use, and intended to offer security patches until at least 2022. Due to legal issues with Oracle, it does not run the TCK suite but is thoroughly tested with a suite of functional, integration, security, and performance tests.

Likewise, if production is deployed on RedHat or AWS, their distributions (RedHat / Amazon Corretto) are the natural choice since they’re optimized for the environment in which they are running.

Here are some of the details of the most important Java distributions:

BuildTCKLicenseFree Public UpdatesCommercial SupportLTS
AdoptOpenJDKNoGPLv2 (free to use commercially)Until at least Sep 2023IBM, jClarity (acquired by Microsoft in 2019)Yes
Amazon CorrettoYesGPLv2Until at least June 2023NoYes
Azul ZuluYesGPLv2?AzulYes
Liberica JDKYesGPLv2Until at least 2023BellSoftYes
Oracle Java SEYesOracle Binary Code License Agreement (paid license)NoOracleYes
Oracle OpenJDKYesGPLv2Last update in March 2019NoNo
RedHatYesGPLv2?RedHatYes

Containerized Java

“It runs on my machine

Then we’ll ship your machine

.. and that’s how Docker was born”

Though obviously not true, the joke above captures the idea that containers promise to run anywhere. This is the same principle to which Java also adheres (the slogan “write once, run anywhere” comes to mind) through the design of the JVM. The question is: How well can Java and containers run together anywhere?

Discover the significance of Java versions in the context of Docker, the leading container technology, and how they enhance application deployment and scalability in modern development practices.
  • Docker is currently the premier container technology and has been adopted on a large scale throughout the industry.
  • What exactly are containers?

Although they’ve been around for almost 20 years, containers have revolutionized the way applications are designed, developed, and deployed over the past few years.

From the outside, containers appear to be very similar to virtual machines: they’re isolated, own processes and network interfaces, allow the installation of packages, can be packaged as images, and can be accessed through SSH, etc.

However, their underlying infrastructure is quite different: containers running in a container environment share the same Linux host operating system, while a VM system may run multiple operating systems.

Learn about the differences between container and VM environments in relation to Java versions, highlighting how containers share the same Linux host OS while VMs can run multiple operating systems
  • Container internals

On a deeper level, container infrastructure is actually built upon the Linux kernel features of namespaces and cgroups. The namespaces can provide isolated views of the host system, which translates to the fact that containers can have their own view on processes. Furthermore, cgroups allow the limitation on resources, which means that the containers can be run with hard limits on memory or CPU. This is the point where containers and the JVM may come into conflict.

  • Memory management

The JVM has its own memory model, and by default, will allocate as maximum heap size ¼ of the available physical memory. It’s important to note that up until Java version 8, the Java runtime is container unaware, so even if it runs inside a container, it still views the host’s memory as the available memory.

On the other hand, a Docker container started with a hard limit on memory will kill a process that tries to allocate more memory than that hard limit. Therefore, trying to run a Java application (pre-Java version 9) in a container with a hard limit on memory (with swap disabled) that is lower than ¼ of the host’s physical memory will fail.

  • Bringing Docker and the JVM on the same page

The solution is to either to limit the maximum heap size through the Xmx parameter passed to the JVM through JAVA_OPTIONS, or to use a base Docker image like the one provided Fabric8, which knows how to dynamically adapt to the container restrictions when starting the Java process.

Java version 9 partially solved this problem with some experimental VM options that can be passed when running the container, while Java version 10 brought all the improvements needed to make the JVM container aware, making the allocation of the heap size relative to the memory limit set on the container.

Container Images

Another critical aspect of running applications in containers is the images from which the container instances are started. A general rule about images: It’s best to keep them as small as possible, which will result in faster updates, lower network costs, and fewer components prone to security attacks.

  • You can reduce the image size by basing the image on lightweight Linux distributions such as Alpine, which provides a minimum set of minimized versions of standard UNIX utilities.

A C library installation is mandatory to ensure that Java runs on top of Alpine (or any other distribution) since part of the JDK is written in C/C++.

Usually, this library is the standard glibc implementation, so common Alpine Java images (like the one provided by AdoptOpenJDK, for example) just install the glibc package on top of Alpine. However, as Alpine itself is built upon a different library – musl libc – the image size could be furthered reduced if the JDK is only compiled with this library. This is where OpenJDK’s Portola Project comes into play (as an experimental feature in Java version 13), whose goal is to port the JVM to musl libc.

  • Keep your microservices light. Reducing the image size can, of course, also be achieved with optimizations made on the application’s side. In Java, in particular, it can be accomplished by reducing the number of dependencies or by using the modules feature.

Containers for Integration Testing

Another topic in the context of containers is the use of containers for integration testing. Why do I mention this? Since integration tests can get pretty challenging to write and maintain in complex environments, containers can come to the rescue by providing isolated, lightweight, throwaway, and easy-to-run instances of the components that make up the testing environment – like databases, brokers, web servers, etc.

In Java, this is possible through the TestContainers library, which supports JUnit tests that bring up and automatically tear down Docker containers required during the integration test flow.

Java in the Cloud and Beyond

Cloud-native applications are gradually becoming the industry standard. Serverless architectures are also gaining popularity and support from cloud providers.

Like any other language or framework, Java needs to adapt to these trends. Several recent developments in the Java landscape were triggered by the need to make Java efficient in the cloud environment.

When it comes to running in serverless mode, a particular shortcoming of Java is the cold start. Oracle has addressed this with techniques like modularization, class-data sharing, ahead-of-time compilation, and, most promising, the use of the GraalVM runtime instead of OpenJDK.

Also, memory efficiency is paramount in the cloud, as the cost is generated by memory usage. This has, in turn, prompted the community to come up with optimizations and alternatives for garbage collectors.

Java is Here to Stay!

Challenges aside, Java is definitely a main actor on the cloud stage. The major cloud providers like AWS, Google Cloud, or Oracle Cloud are building part of their own services with Java, offering wide support for Java on their platforms.

As Java – still at the top of the Tiobe Index – prepares for the new decade with exciting new features, we can say that it has come a long way to reach the pinnacle of next-generation software development. No matter what trends emerge, developers and businesses will look to Java as a platform that can create innovative products.

Oct 7th - 2024
More Stories for you
Discover the Builder Design Pattern, a creational design pattern that simplifies the construction of complex objects through incremental steps, illustrated with a real-world example and C# 11 source code available on GitHub.

If It’s Complex, Let’s Call the Builder: Use and Applicability...

Oct 7th - 2024
What is the Builder Creational Design Pattern and why do we need it? In real life, a builder constructs complex things and does this in small steps, piece by piece....
Discover how Claude Instant 1.2 represents a significant advancement in AI technology, enhancing human-machine collaboration and transforming our interactions with AI systems for a more seamless experience.

Claude Instant 1.2: Unveiling a Safer, Better, Faster, and Stronger...

Oct 7th - 2024
Anthropic has recently released the latest version of its AI model, Claude Instant 1.2, which is now available through their API. This new version incorporates the strengths of their flagship...