What are the main advantages of using the Java 9+ modularization feature?

Asked

Viewed 539 times

11

From Java 9 we have the possibility to modularize our application using the so-called Java Platform Module System

Before Java 9, modularization was done purely through Jars, where we had several libraries, and it was possible to modularize the application with several Jars (for example, create Jars containing only entities, containing utilities, annotations...)

In this way, I raise the following questions::

  1. What an expressive gain we have when using the new module system?
  2. In terms of complexity, how easy is its applicability in large projects that are already running in Java 8 for example?
  3. During library upgrades, we come across conflicts between versions and dependencies. In this modularization scenario, this problem does not become more common?

1 answer

5


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:

  1. you can create classes that you will not expose and use in whichever package of your module
  2. 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:

  1. which modules I rely on? requires
  2. for each required module, I must make available to third parties who import from my module or not? transitive
  3. which packages will I expose programmatically so that it is seen as part of the classpath for other modules? exports
  4. 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:

Browser other questions tagged

You are not signed in. Login or sign up in order to post.