In an increasingly complex world, Java takes the right move
The world we live in, is getting more and more complex. A growing number of things, servers and cloud components are connected to each other, more logic is delegated to AI algorithms, end-users increasingly manage their lives from mobile devices.
This evolution is in part due to fast and great advances in software and hardware, but it also puts an increasing pressure on the IT industry. The average IT project becomes more complex, and almost always involves IT processes that are controlled by a different entity (e.g. a ticketing system needs to leverage a third party payment provider).
Due to this increased complexity, many projects are failing. They don’t deliver on time, they have major security or privacy holes, the budget is exceeded, or they simply don’t work.
The best approach to deal with more complex requests, is to reduce complexity in the toolset you use to address the requests. An example of this is the increased popularity of microservices. With the increasingly important requirements that enterprise components need to be agile, modular, scalable and isolated when needed, using a microservices approach instead of a monolith increases the chances a project will become successful.
But not only the patterns have to be modified. The underlying technology stack should be as simple and transparent as possible. It has to be easy for developers to understand what is happening, and why it is happening.
The Java Platform is moving into this direction, with two very important decisions.
First, Jigsaw has been released. The path to the Java Modularisation has been delayed a few times because of technical and less technical discussions, but Java 9 contains the breakup of the Java core classes into modules. For Java, this is pretty disruptive. Backward compatibility is extremely important in the Java world.
With Java 9, things that used to work might not work anymore. The breaking changes are very minimal, but still there is often some work to do when migrating from Java 8 to Java 9.
This drastic change was needed in order for Java to stay relevant in the future. The Java core classes were growing fast with every release. Java can be used for an increasing number of applications, but not all applications require all core components at the same moment. On a Cloud environment, the Java UI APIs are not used. In Mobile or embedded devices, many enterprise oriented APIs are not used and just make the total result bigger.
With the jlink tool, developers can now assemble their own Java Runtime Image that contains the modules they need. Every developer, every project owner can now create an own Java Runtime Image, based on the required set of modules. This is extremely more convenient than the “profiles” we used to have in the past.
By only including modules you need for your project in your Java Runtime Image, you reduce the risk of failing code and it makes it much easier to find out what is going wrong in case something doesn’t work as expected.
The other big item in the Java world is Graal. There are a number of definitions floating around for Graal, but at its core it is a Java API and implementation that allows for high-performant dynamic compiling. While that might sound boring to some, there are a myriad of areas where Graal will make a huge difference.
First of all, the Graal compiler can replace the C2 compiler that currently compiles frequently used Java methods into fast native code. The C2 compiler is the component that makes Java applications very fast — after a relative slow startup. The code for that compiler is part of the hotspot component in the OpenJDK repository, so everyone can see and analyse it. It does a great job, but it is an extremely complex beast that is difficult to maintain and move forward.
Graal, on the other hand, is written in Java, and it is much easier to understand and maintain. It is developed in an open source context, and more and more people are looking into it, and working on it.
Apart from the dynamic runtime compiler, Graal offers a number of other interesting advantages. First, instead of runtime compilation, it is also possible to compile Java bytecode ahead of time (AOT), and have your methods already executing native code when they are called the first time. This offers huge opportunities in two worlds that are often seen as distinct, but that share more than often thought: serverless and mobile. In a serverless platform, where a large number of typically small functions are executed, startup time is key. If a smart compiler can make sure the bytecode is compiled before requests come in, that can save a lot on startup time. And if that is combined with runtime profiling, it is possible to do smart recompilation based on real-usage statistics.
Clearly, in mobile startup time is important as well, but on some platforms it is not even allowed to use runtime compilation, and in that case an AOT is required. At Gluon, we have our own AOT to compile Java bytecode into native iOS code, but we are looking into Graal as well.
Graal is often described as a polyglot runtime for the JVM. One of the Graal subprojects, Truffle, allows to implement other languages and parsers, and have those run on top of Graal. Although those projects are still very young, they already show huge performance gains can be achieved.