What an expressive gain we have when using the new module system?
Here, from what I could read and feel the taste (I couldn’t sip a large sip, only one came on the tip of my tongue) of Jigsaw, are two main advantages:
- you can create classes that you will not expose and use in whichever package of your module
- class search optimization by
classpath
The first part I even felt when trying to put a legacy code to run with Java 12: Oracle now decided to actually hide its intimate implementations.
I don’t know if you remember, but you know the packages sun.java.*
? Well, they were internal packages that should be consumed only by Sun/Oracle’s JRE/JDK. In theory, no program made to run in Java should depend on these packages. What was possible with Jigsaw? Remove them from the path =) Then what happened to a legacy library that I had accessing sun.misc.BASE64Encoder
? Gave ClassNotFoundException
and the system stopped.
Honestly, I thought it was bad? No, incredible as it may seem, I didn’t think it was bad. Just curious. As the code to this library was lost in space/time (and it is a deprecated artifact), it served only as another push to abandon it.
Now, how do you get an improved performance in the search for classpath
?
Let’s go back to the class I no longer had access to, sun.misc.Base64Encoder
. When you are in a module, the first search will be for classes of that module. Then, in the case of the module java.base
(let’s pretend, okay? I don’t know what would be the real module), at some point it was necessary to access the class sun.misc.Base64Encoder
. The processing was inside the module java.base
, then the first thing he does is inquire inside the module who is sun.misc.Base64Encoder
and he finds this class, public.
Now, we are in my implementation. Suppose it is properly ported to Java 9 and tries to access sun.misc.Base64Encoder
. The first thing that the ClassLoader
will try to do is to see, inside the module where I am, if you have any class with that signature. The answer will be no. Then, at that moment, I also walk through all the other modules of classpath
I declare to use (or inherit via transitive
) and see if there’s anyone who provides the package sun.misc
, without going deep into them for further inspections. Maybe one or another library in Java 8- offers some resistance because, by default, they behave as if they were modules with all available packages.
Saw how search time is reduced using modules?
In terms of complexity, how easy is its applicability in large projects that are already running in Java 8 for example?
Can you modulate your program well? If so, the first step will be to provide a module-info.java
with the following information:
- which modules I rely on?
requires
- for each required module, I must make available to third parties who import from my module or not?
transitive
- which packages will I expose programmatically so that it is seen as part of the
classpath
for other modules? exports
- which classes would you like to be accessible via
reflection
, even if it is not "available" to access directly by ClassLoader´?
Opens`
That step of opens
is the most delicate when using a framework that relies heavily on reflections
(like Spring, Hibernate, Mybatis etc).
By defining all this correctly, and making the proper separation of the modules, the rest must flow naturally. I particularly see more Jigsaw application for libraries, but saw no reason to prevent an application from being separated into modules.
Now, these definitions are not trivial to do. Perhaps a reengineering of the original code to hide the implementation by moving it to another package is necessary.
During library upgrades, we come across conflicts between versions and dependencies. In this modularization scenario, this problem does not become more common?
One advantage of this scheme is that it can have several classes with the same name. The only requirement for this is that they are not exported packages. A very well-thought-out library might be able to make proper use of this, but most are lacking with target
for Java 8.
Another point is that this does not exempt dependency management by Maven or Gradle (or what you use for this purpose). So I don’t see how using modules would decrease these upgrade problems (with possible class exceptions with the same signature in two separate modules).
References: