Khunatorn - stock.adobe.com

Tip

Problems with Java modules still plague developers

The Java Platform Module System promised to fix the missteps of the past. Unfortunately, it has repeated the problems that plagued OSGi and JBoss Modules.

Famous philosopher George Santayana once said, "Those who cannot remember the past are condemned to repeat it." In the case of the Java Platform Module System (JPMS), the past has most certainly repeated itself.

As a rank-and-file Java developer, I view the Java module system as a failure. JPMS does what it says on the tin -- it's something Java needed -- but it repeats the failures of the Open Service Gateway Initiative (OSGi) ecosystem that's been around nearly as long as Java itself.

OSGi is a system for modular components that contains a few specifications: one for the components themselves (what they can do, their lifecycle, how they declare dependencies), and another for a container in which those components run.

It sounds like a familiar pattern, doesn't it?

Java modules explained

JPMS borrows from module systems like OSGi and JBoss Modules, which is both good and bad. It's good because it means it uses real-world experience to define itself. However, it's bad because it repeats the same mistakes.

The main thing JPMS adds to the prior specifications is built-in JVM support, whereas OSGi and JBoss Modules rely on a container abstraction. In these systems, developers need to run an application -- like Karaf, Equinox or Felix -- and tell the container to deploy modules, similar to a Jakarta EE application.

With JPMS, however, because it's part of the JVM, you have a simple implementation path. First, developers can compile the modules (properly, one hopes), then tell the JVM how to resolve the modules and what entry point to use to run the modules.

Wait -- those are the same steps.

JPMS vs. OSGi vs. JBoss Modules

JPMS is a necessary part of improving development. However, it suffers from the same major problem that plagues OSGi.

What did OSGi get wrong? Seeing as JBoss Modules and JPMS came to be after OSGi -- with much of the same core goals -- it tells us that the objectives are fine. But why is OSGi so insufficient that we must keep reinventing it?

JPMS will always be like OSGi and JBoss Modules before it: a great idea that gets ignored when real work needs to be done.

The container requirement is a problem JPMS solves because it's no longer dependent on an external application. The OSGi containers are workable, but they're still extra things.

This is where a specification helps everyone. A product compliant with a specification is required to behave in ways consistent with the specification, and deployments don't have to wonder if something might work or not. And if they need a feature of a specific container, they can compensate for that at runtime.

What OSGi does isn't wrong, either. Again, the modular deployment structure is something that both JBoss Modules and JPMS have replicated, although in different ways.

The problem with Java modules

What OSGi failed to address, and the mistake JPMS has repeated, is tooling.

To be clear, there are tools for OSGi: bnd is one of the most popular tools and even supports JPMS. However, even bnd suggests that developers use an IDE to develop with, such as Eclipse. It uses a project.bnd file to control the dependencies, like how JPMS uses a module-info.java.

JPMS tools and support

Now we're back at the beginning of the cycle where everything old is new again. There are plugins for Maven and Gradle to invoke bnd, and because module-info.java is an actual source file, it is part of the compilation process in a way that a project.bnd file is not.

However, using JPMS is still largely a matter of trial and error, even though it does some things better than the older systems. The ecosystem support hasn't caught up. The Java tooling is just not there to aid library developers to consistently and elegantly support modules. As a result, using a library from Java's ecosystem -- arguably its greatest strength -- relies on hoping that modules are supported, and that the module support was done properly.

You don't want to hope something works when your productivity is on the line. You want it to work, and that means there are lots of developers who'll try JPMS for their projects and fall back to the old non-modular system pretty early because the modules aren't supported properly yet for the libraries we use.

Until JPMS addresses that -- and so far we've seen little hope on the horizon for such concerns -- JPMS will always be like OSGi and JBoss Modules before it: a great idea that gets ignored when real work needs to be done.

Dig Deeper on Core Java APIs and programming techniques