A Bright Future For Java and The JVM

Daniel Andres Pelaez Lopez
Globant
Published in
10 min readJul 19, 2020

Java is 25 years old now and what an impressive career it has done, from an embedded language to digital devices like televisions, to support the business core of large companies around the world.

Java 25 years

Java has created a lot of mixed feelings in the technology industry, from how “difficult” it is to learn it to some performance constraints in high throughput systems.

In this post, I will show you a summary of the past, present and future of Java, and why Java will stay relevant for the decades to come, trying to answer the following concerns:

  • Has Java been slow to change and improve to the new contexts?
  • Has Oracle affected Java after he acquired it 10 years ago? Is the Java ecosystem closed by Oracle trademark?
  • Has Java had a good performance for high throughput and demanding businesses?

Let’s get into it.

Java Evolves Faster Than Ever

Evolving fast is important in the technology industry. Every day, new problems and solutions show up, and if your language/framework doesn’t evolve fast, it will be replaced.

At the timing of writing this post, Java has 14 versions, which were released as follows:

JVM history

As you see, Java evolved quite fast from its first 6 versions, releasing a new version every 2 years, when Sun Microsystems was the owner. However, from the 6th version to the 7th version, it took 5 years (a lot of time for the technology industry).

Between those two versions, great (and concern) events happened:

  • In 2006, Sun Microsystems open source the Java Virtual Machine (JVM) specification, creating the OpenJDK community, a free implementation of the JVM. This opened Java to the world, creating a full ecosystem of open source projects and developers around the world. (We will discuss this in detail later).
  • In 2009, Oracle bought Sun Microsystems, creating a lot of concern around the technology industry for the future of Java, and this slowed down the Java evolution. Some developers believed that Oracle would charge for Java use, and that, will kill Java forever.

Oracle released Java slowly, every 3 years, from the 7th version to the 9th version. However, the 8th and 9th versions were game-changers. In the case of Java 8, it included things the industry thought Java would not ever have, like Functional Interfaces, Lambda Expresiones, Streams, and a new Java Time API.

Besides, Java 9 brought Java modules, to allow users to plug and play new features to the JDK easily. For instance, the OpenJDK team creates preview features, so developers can use them in real contexts and give back feedback, before those features are included by default in the JDK. Modules gave Java a push to evolve faster than before.

After Java 9, you see how fast Java has evolved¹, with a release cadence of 6 months, adding new features, previews, and improvements in its core. Java 9 opened the door to the new release cadence strategy, allowing the community to propose new JDK features, using the JEP (JDK Enhancement Proposals) process, creating an ecosystem of innovation that evolves each day.

Now, it is not only about the Java new features and evolution, it is also about 25 years of a technology ecosystem, as we discuss as follows.

Large Java Ecosystem

Oracle owns the Java trademark, however, the ecosystem around Java is huge as some Github statistics show²:

Java Ecosystem

Hundreds of thousands of repositories, commits, issues, created by thousands of developers around the world, focusing the efforts on several fields, from Data Science and Big Data³, to high throughput applications. Developers show that Java is useful to solve any problem, it doesn’t matter the context, performance requirements or business complexity.

Plus, the 2020 Stack Overflow survey⁴ about the Most Popular Technologies for developers around the world, shows how Java by itself is one of the most used:

Stack Overflow survey

As you see, Java is the 4th most popular language in the world, however, there is a trick here, what about the JVM languages⁵? Let’s summarize all of them:

JVM Stack Overflow survey

The impact of Java and the JVM is not only as a language, also, as facilitator of new languages.

Developers use Java, but what about companies? well, companies around the world trust the JVM for its critical systems, like Twitter, which has moved part of the platform to Java, showing that it is possible to create highly scalable and performance systems using the JDK⁶. Twitter has 126 million daily users⁷.

Besides, Netflix, another company using Java intensibily, uses Java from runtime containers, libraries and services, to automated scalable multimedia ingest and encoding, all of them oriented to work on a cloud environment and microservices architecture⁸.

It is not only how large companies use Java, but it is also how they collaborate to improve Java and its ecosystem. For instance, Twitter, as they rely a lot on Java, they started to collaborate over OpenJDK.

Also Netflix, released as open source its core frameworks for Cloud Computing and Microservices architectures based on Java, between them: Hystrix, Eureka, Ribbon, and Archaius. Those later were included on the Spring Cloud Umbrella.

And there is more, to the surprise of the world, Microsoft announced how they will start to collaborate over the OpenJDK too, furthermore, creating tools for Azure to run Java Cloud Native applications, and adding a Java Microsoft Visual Code to the Java toolset⁹.

Besides, Microsoft bought Github.com to support from its core the open-source industry, and guess what? Java source code will be moved from OpenJDK repository to Github.com¹⁰, enduring the Java and Microsoft relationship much more.

Companies and developers, plus open sourcing, have been the perfect mix to create a beautiful ecosystem. Now, which features will the ecosystem bring us next? Let’s see some of the game changers regarding performance and high throughput requirements.

Performance for High Throughput Systems

“Java is slow”, “Java doesn’t work for high throughput systems”, “I cannot use Java in a Cloud Lambda infrastructure, is too slow to start”. Those are just some of the critics we have heard about Java through the years. Some of them are not totally true, and companies like Twitter and Netflix can tell better than me, but, of course, you can always find space to improve, and Java does.

Let’s talk about two game changers for Java performance, Project Loom and Graal.

Project Loom¹¹

Scalability and good use of resources like Threads is a well-known concern for Java applications.

Threads in Java are an object of execution, they allow your program to process requests in a concurrent manner, so, as many threads an application has, as many concurrent tasks, an application can handle.

When you start a web project using Java, you usually choose a web server to deploy that project, for instance, Tomcat is a pretty well known one. By default, Tomcat starts a Thread pool of max 200 threads¹², which means your application in ideal conditions will be able to handle 200 requests per second. That’s enough for an average business application.

However, what if my business application needs to process 10000 requests per second? Well, we just increase the thread pool from 200 to 10000 right? Sadly, in Java, that is not as easy as it sounds.

Java wraps each Thread object to a real thread over the underlying operating system, and the operating system has a limit of real threads it can create, meaning, your Java application cannot grow more than a fixed amount of threads.

With this problem in mind, the Java community found a way to handle a lot of concurrent requests, with few threads. Those are “reactive” libraries.

Reactive libraries are based over the idea that few threads can handle a lot of concurrent requests, if those threads don’t block, for instance, when calling a database, accessing the file system or doing an HTTP request. If they don’t block, they can be reused over and over.

But, this approach brought consequences:

  • The program model changed from imperative to functional programming. From the beginning, Java has been an imperative (“boring”) language, so, changing the programming model has consequences for the language, and for the developers.
  • The Java observability features decrease, as debugging and tracing a reactive model is harder than an imperative one. We needed to add more things to get Java working over this model, without losing error observations and detection.
  • The Java ecosystem uses blocking by nature, that means, you need to adapt the ecosystem to the new model. The last few years, the Java ecosystem has grown the amount of reactive libraries, but 25 years of blocking libraries cannot be rebuilt in 5 years, so, you will need to coexist with blocking libraries in your non blocking reactive application.

Spring Webflux, Project Reactor, Eclipse Vert.x and Akka, are some examples for reactive frameworks, plus, the ecosystem surrounds them, like reactive database drivers and networking.

You might think: “that sounds right, but, what about Project Loom?”

Well, Project Loom “aims to drastically reduce the effort of writing, maintaining, and observing high-throughput concurrent applications that make the best use of available hardware”, and one of the items is how to improve the performance of Java threads in high throughput concurrent applications¹³.

At the time of writing this post, Project Loom defined the concept of Virtual Threads, where: “Virtual threads are just threads, but creating and blocking them is cheap. They are managed by the Java runtime and, unlike the existing platform threads, are not one-to-one wrappers of OS threads, rather, they are implemented in userspace in the JDK”.

Well, seems right again, so what? The key here is “creating and blocking them is cheap”, that means, you not only can create thousands of threads but millions of them, so it is cheap to create and block them.

That opens some questions:

  • Can you imagine removing the Threads concern from the table when you design a system? You will have millions of them.
  • If you can create a lot of threads, will you bother using reactive libraries again?
  • How will reactive frameworks use this as an opportunity? Any change brings opportunities, and I would like to see how reactive libraries adapt to this new context.
  • Will we give up Java functional programming for imperative again? Of course, imperative programming is easier than functional programming, but should we give up with functional?

I don’t have the answers to those questions, but, I am excited about the opportunities.

Graal¹⁴

Java since the beginning was created to be interoperable over different computer architectures and operating systems, which means “Write Once, Run Anywhere”. To allow interoperability, Java code is compiled to bytecode, which is an intermediate step between Java and a binary executable¹⁵.

When you deploy your Java application in a JVM, a second translation happens, from bytecode, to a binary executable, allowing the application to run over the underlying machine. This process is done by the Just In Time compiler (JIT)¹⁶.

However, JIT doesn’t optimize at maximum the binary executable, instead, JIT just creates enough optimized binary to start.

This means, when you start a Java program, that program performs only with enough optimized code. But that’s not all, JIT optimizes the Java program when we start to use the application, which means, any time you invoke or use a Java code in your program, as a client, JIT learns, and optimizes the most used bytecode, the hotspots, improving the performance on the fly, while the Java program runs.

An ongoing learner compiler is an awesome concept, but it has a downside: When your Java application stops, the JIT optimizations are gone, so, JIT will need to learn again everything. The reason for this is because it creates a balance between interoperability and performance.

What if you want the whole optimization power since the beginning? What if you know exactly in which underlying platform your Java program will run? Well, Graal uses these assumptions to improve Java performance applications.

GraalVM allows you to jump from Java code to a binary executable, using ahead-of-time compiler for native images. Ahead of time compiler compiles the program directly from Java code to a binary executable, in contrast to the Just In Time compiler, which means you will have the whole power of the underlying system from the beginning.

You might think: “Hold on, you said the main goal of Java is to be interoperable, so, to create a binary executable, you will need to know which underlying system your Java application will run, and that’s not good”. You are right, but, we are now in the world of containers like Docker, so, when you deploy a Java application over a Docker image, you already know which underlying operative system will be used.

But why is this important? Well, you will get the following:

  • Java runs faster, allowing high throughput. As the Java application don’t need to compile hot spots, those resources are now used by the program itself, besides, the binary executable is totally native, so it uses the whole power of the underlying operative system.
  • Java starts faster, allowing a fast ramp up the first time you start it. This is pretty useful if you have your Java program in a Serverless infrastructure.
  • Less memory footprint. You don’t need to trace the hot spots any more, so those resources are released.

Graal adds a whole set of opportunities for the Java ecosystem and I hope to see them.

Final Thought: Java Developers, Be Proud

Java is dead, long live to Java. Java is more relevant today than ever, moving faster, evolving with the user’s needs in mind, and being supported by a large open-source community, which includes large organizations like Twitter, Netflix and Microsoft.

Java is here and will stay for a long time, enjoy this moment, and be proud to be a Java developer today.

References

  1. https://blogs.oracle.com/java-platform-group/update-and-faq-on-the-java-se-release-cadence
  2. https://github.com/search?q=java&type=Repositories
  3. https://blogs.oracle.com/javamagazine/the-top-25-greatest-java-apps-ever-written
  4. https://insights.stackoverflow.com/survey/2020#technology-programming-scripting-and-markup-languages
  5. https://twitter.com/brunoborges/status/1266063739574382592/photo/1
  6. https://go.java/twitter.html
  7. https://www.vox.com/2019/2/7/18215204/twitter-daily-active-users-dau-snapchat-q4-earnings
  8. https://netflix.github.io/
  9. https://devblogs.microsoft.com/java/java-at-microsoft-from-openjdk-to-azure-spring-cloud/
  10. https://openjdk.java.net/jeps/369
  11. https://wiki.openjdk.java.net/display/loom/Main
  12. https://tomcat.apache.org/tomcat-7.0-doc/config/executor.html
  13. http://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part1.html
  14. https://www.graalvm.org/
  15. https://www.infoq.com/news/2020/05/java-leyden/
  16. https://www.ibm.com/support/knowledgecenter/es/SSYKE2_8.0.0/com.ibm.java.vm.80.doc/docs/jit_overview.html

--

--

Daniel Andres Pelaez Lopez
Globant
Writer for

I am a passionate software engineer navigating through this fantastic industry, searching challenges day to day. Follow me on https://coderstower.com/