Need of JPMS – Problems before Java 9

We’ll see in this tutorial, why JPMS was needed and what problems did JPMS solved.

Lack of strong encapsulation

Encapsulation can be achieved by using a combination of packages and access modifiers (such as private, protected, or public). When you make a class public, then it is public for everyone. There is no way to prevent this. You can not specify to which other package it is public and restricted for others. Some programmers place such files in packages with .internal name. But anyone can still use these classes as there is no way to restrict this.

With Java 9, public is not so much public. We can explicitly define to which other modules a public class is accessible.

Suppose there is a jar file which contains two packages pack1 and pack2. Suppose pack1 is used for internal purpose and don’t need to be exposed. There is no way to achieve this.

But in Java 9 module system, we can export particular package of a module. Only this exported package can be accessed and used by other modules. The remaining packages of that module are not visible to outside. This results in a strong encapsulation.

No way to check dependencies at execution time – NoClassDefFoundError problem

To specify explicit dependencies Java provides import statements. But these import statements are only for compile time. When you bundle your code in to a jar. There is no way to find if the jar contains all required types. If any required type is missing in jar file during execution, then we get NoClassDefFoundError.

If any dependent jar file is missing then in the middle of execution of our program, we will get NoClassDefFoundError.

In Java 9, we can specify all dependent modules’ information in module-info.java. In Java 9, all such dependencies are validated before execution.

If any module is missing then at the beginning only, JVM will identify and won’t start its execution. Hence there is no chance of raising NoClassDefFoundError in the middle of execution.

Version conflicts

JVM searches for classes in jar files in classpath in left to right direction. If different versions of classes are found in different jar files then JVM ends its search when first class is found. Thought it may not be the right version of class. This version mismatch may result in abnormal behavior of program.
In Java 9, we can specify dependent modules for every module. During execution time only specified modules will be considered.

In Java 9 module system, every module specifies its dependencies. JVM will only consider the required dependencies and their order is not important. Therefore, version conflicts are not raised in Java 9.

JDK’s internal APIs are accessible – a security concern

Since there is no strong encapsulation, JDK’s internal classes (for example, unsupported package sun.misc)are accessible to application developers. Developer may accidently use such types which may create problems with JDK update. If JDK’s internal classes are accessible to developers then it also creates a security concern.

In Java 9, only exported packages by a module are accessible to other modules.

JDK/JRE’s monolith structure

All classes are bundled in rt.jar. When there is requirement to just run a simple “Hello World”, it is considered monolith structure. Even to run a simple program, we need to have rt.jar which is more than 50 MB in size. Small devices have memory constraints, due to this reason Java is not considered suitable for small devices.
With Java 9, there is no rt.jar. You can load only defined dependencies in module. You can also create your custom JRE using JLINKer.

Classpath Hell

Java runtime uses the classpath to locate classes. When you run an application, all classes which are directly or indirectly referenced by the application are loaded at some point in time. The JVM reads the classpath in sequential order to find the right class. If the class is not found, then you will get a run-time exception. Since the classes are loaded lazily, it could be a problem when your application is in production. There is no mechanism for the JVM to verify the classpath and if all the required classes are present in the classpath.

Another scenario with the classpath is when duplicate classes are present in the classpath. If the same class is present in two different JARs or may have different versions, then the JVM will load only the first one found because as soon as the class is found, the search ends.

You can imagine when you have to resolve classpath issues in case of large application where thousands of classes are used. Due to this reason term classpath hell (or JAR hell) is so infamous with the programmers.