Most of the talk about Java 9 has been about the new module system. Two decades after its creation, the Java runtime has finally become modular. A modular approach not only makes dependency management easier, but it also makes applications more efficient as unused modules don’t need to be loaded.
The NetBeans Platform predates Java 9 and has been using its own module system for years. With INTViewer being a desktop application built on top of the NetBeans Platform, I have come to like this system and I’d like to talk about 3 aspects in which it is far superior to the Java 9 module system for my use cases.
One of the core aspects of both the NetBeans Platform and the Java 9 module system is that modules are identified uniquely by a root package name. Where they differ is that the Java 9 module system doesn’t allow two modules to have classes under the same root package name. The logic behind this is that the Java runtime can’t quickly resolve where to find each class if the rules to find the matching module are complex or even ambiguous. Java 9 doesn’t allow so-called “split packages.”
The NetBeans Platform doesn’t have this restriction, and over the 10 years that I have worked on INTViewer, this has helped us tremendously building INTViewer as a modular platform. Many times, we found ourselves realizing that one module was “too big” and needed to be split. If we had to follow the “no split packages” rule, we would have had to change the package of some classes, breaking class-level backward compatibility.
This “stable class-level API” is a very important concern for us. With customers and vendors building their own applications on top of INTViewer, we can’t afford to change the public API at each release. Our customers wouldn’t allow it: they can’t refactor their code so often. When we do need to split a module, customers are generally okay with changing the coarse-grained dependencies of their app; adding a new module to their dependencies is easy and doesn’t require any code change.
It’s a simple feature, but very powerful. When INTViewer starts, the NetBeans Platform verifies every plugin before it gets loaded. If one of them relies on another module that is not present, this plugin doesn’t load. Similarly, if a plugin requires a module to be up-to-date and the NetBeans Platform finds that this requirement is not met, this plugin won’t load. Practically, this prevents mixing plugin versions. A plugin built for INTViewer 5.2 won’t load in INTViewer 5.1. The NetBeans Platform gives immediate feedback to the person performing the plugin installation.
The Java 9 module system doesn’t support module versioning. The versioning concern is left to the dependency-resolution systems like Maven. But these systems perform checks at compile time, not when the application is used.
Mixing Library Versions
This is not a trick we use often, but it’s a lifesaver when we have to. When our customers build their own plugins, they typically leverage .jar files built by other entities. We do, too, and in a typical Java application, there is only one class loader to load all these .jar files. If two versions of the same library are present, the resolution of class names is ambiguous and the application fails in strange ways. The Java 9 module system doesn’t provide a direct way to address this concern.
The NetBeans Platform uses its own class loaders. To simplify, each module has its own. Each class loader only needs to deal with a well-defined set of dependencies, and other class loaders are not affected by these dependencies.
For example, we have two optional plugins making use of the JAXB library, a popular building block to read XML files. One of them is the VTK plugin, a plugin to visualize 3D models. Another one is the Reservoir plugin, a plugin to visualize RESQML datasets. These two plugins can coexist in the same INTViewer deployment without problems, and they don’t even need to have the same version of JAXB.
In a classic Java application, a choice would have to be made: which version of JAXB is “the right one,” and the module using the “wrong version” would have to be updated. The NetBeans Platform makes it really easy to deal with these version conflicts. As a result, INTViewer customers are not faced with refactoring their code for each release just because another unrelated module needed a more recent version of a specific library.
INT has greatly benefited from the NetBeans Platform. Its module system is both powerful and easy to use. It has allowed us to provide, release after release, a painless way to maintain INTViewer plugins, for ourselves and for our customers.