Although Java 9 is not the latest JDK release (to be more specific, it was released back in 2017), it was the biggest update in the history of the JDK. Despite that, most Java programmers hardly mention its most significant feature — the Java Platform Module System.
This is primarily because most business applications still use Java 8. For now, it has demonstrated stability and newer releases need time to spread across the IT world.
That’s why I decided to write this article. In the future, if you facing this technology, you will be able to get a flying start.
Since Java 9, there has been a new release every six months. Before that, there was only one release once the planned features were complete.
One of the biggest changes in Java, ever.
It affects the followings:
There are a few reasons why modularizing was necessary.
The Java JDK is over 20 years old, and it was one big file. It was hardly maintainable. Everything was chained together and they would like to work down this technical debt to make it maintainable again.
Along with the modularized JDK, developers should modularize their applications as well. Although, it is important to note that modularization is optional!
If you switch to Java 9, you can keep using Java as you used to, or you can switch to the module system and start to modularize your application and make it more maintainable.
Although you will still run on modularized JDK, this can still affect your code!
This is how the new Java platform looks like.
They divided JDK into more than 90 separate modules. Each module encapsulates its own piece of functionality of the Java runtime library. The picture above represents the dependencies between the modules.
The most important one is the *java.base *module. It represents the most basic classes of the language, like streams, strings, and objects. Since this module is essential, all other modules depend on this library.
Here, we see a more complex graph about the different libraries and how they connect to each other. The ones with names starting with *java *indicate that these are part of the Java SE specifications.
In the dependency graph above, you can also see two modules in blue; these do not start with java but jdk. These are JDK-specific.
You may notice that all arrows are pointing down. This means that there are no circular dependencies. Hence, it has very clean modularization.
Let’s see some examples:
*Corba *is ancient technology, and it’s still part of the JDK. However, it is isolated into its module. This means that unless your application has a dependency on java.corba, this old technology won’t get in.
Another module in this graph you may be more familiar: Java.desktop. It contains all the swing GUI toolkits of the Java platform. Hence, your application doesn’t need any of these GUI dependencies; and you do not need to reference the java.desktop module.
That’s a one we didn’t touch upon yet. This is due that the fact a module can explicitly expose some of the packages and strongly encapsulate other packages. As I mentioned earlier, there are many internal implementations in classes in the JDK that need to be public because it is used among different packages, but at the same time, they should not be used outside of JDK. These later ones are encapsulated.
If you start, make modularized applications on top of the Modularized JDK. You do not need to scan and load all the classes that the *rt.jar *contains, which you cannot avoid before you can only include the necessary modules.
Having clearly separate modules also helps deprecation. The idea is that, at some point, a module can be marked as deprecated. Every application that uses that module should look to another solution. After that, in the next major release, it can be removed from the JDK.
It is already happening because in Java 9, the *java.corba *module has been marked as deprecated.
The deprecation example is true from the other way as well. It is much easier to ship new features to the language. They can add incubator modules, and if it is stable, it can be converted to a real module with the next major release.
There is an example as well as the *jdk.incubator.httpclient *module.
Now, we see the new modularized JDK, but a big question remains: What exactly is a module?
A module has a name; it has a distinct identity; it has **groups **related code. Furthermore, it fully self-contained, which means that it needs to contain everything to do its functions. If it hasn’t, it must reference another module from the library.
The below image shows how a module builds up.
This structure is described in the module-info.java.
module java.base {
exports java.lang;
exports java.util;
exports java.io;
//etc.
}
We do not see any external module dependencies here because *java.base *do not reference any.
Let us see another example.
The *java.sql *references to two other modules, these are marked in our descriptor.
As you may have noticed, we have three new keywords in this context.
These keywords are live in the context of the module, so you do not need to be aware of them in your application code.
If you have Java 9 > installed, you can list out all modules that are currently in the JDK by the *java –list-modules *keyword typed in your operating system console.
Another good function is that you can get a definition overview of every module independently with the *java –describe-module *keyword.
Hope you enjoyed my article. Here, I described the Java Platform Module System and what Java 9 brought to the language. This was the most major update to the JDK in the last 20 years.
In my upcoming articles, I would like to mention some other features of Java 9 and also introduce the most recent versions of the JDK —10, 11, and 12.
#java