JPMS : Java Platform Module System
JPMS: JPMS i.e. Java Platform Module System is a new feature which is introduced in Java 9. With the help of the Java module system, we can package our Java application and our Java packages into Java modules. By the help of the Java module, we can specify which of the packages of the module should be visible to other Java modules. A Java module must also specify which other Java modules is requires to do its job.
The Java Platform Module System is also sometimes referred to as Java Jigsaw or Project Jigsaw depending. Jigsaw was the internally used project name during development. Later Jigsaw changed name to Java Platform Module System. The main intent of developing JPMS is to make the JRE more modular i.e. have smaller jars which are optional and/or we can download/upgrade only the functionality as per need.
JPMS/Project Jigsaw is going to address few major problems:
- ClassPath/JAR Hell
- Massive Monolithic JDK
- Version conflicts
- Security Problems
Let’s see each one of them in detail.
- ClassPath/JAR Hell: Java searches for classes and packages on the classpath at the run time. Suppose we created one application and the application requires some class files from few jar files and we added that jars inside the classpath. At the compile time, compiler will not check that the required class files are present inside the jar or not. It will run the application and at the run time it will goto the classpath and check that required classes are there inside the jar files or not. If it is there then our application will execute fine. But for any reason if any one of the class file is not present inside the jar then it will throw NoClassDefFound error. We are following this approach before Java 9 introduced and with this approach at the run time there are chances to get NoClassDefFound error, which is not good.
With the help of Java module system, we can package our Java application and our Java packages into Java modules. Apart from .class files, a Java module contains one more file i.e. module-info.Java file. Each Java module needs a Java module descriptor named module-info.Java which has to be located in the corresponding module root directory. Creating a module is relatively simple, however. A module is typically just a jar file that has a module-info.class file at the root – known as a modular jar file. Using a modular jar file involves adding the jar file to the modulepath instead of the classpath. In module-info.Java, we can mention all the dependencies/which modules are needed at the run time. Now at the compile time with the help of module-info.Java, compiler will get to know that what are classes needed to run the application and at the compilation time only compiler will check that the corresponding classes/packages are present inside the module or not. If the required classes are present then the code will compile successfully otherwise it will throw compilation errors at the compile time only. This is how Java module system resolve the classPath/JAR Hell problem.
- Massive Monolithic JDK: Monolithic means formed of a single large block of stone. The big monolithic nature of JDK causes several problems. It doesn’t fit on small devices. Small devices do not have necessarily the memory to hold all of the JDK, especially, when the application only uses small part of it.
To run the above code, we need few classes like String, System, Object etc. But we have to hold the entire JDK even if we are not using the entire jar of JDK not even 10% of it. With this approach to run even 1KB of file, we need to have minimum 60MB of rt.jar file. We can resolve this issue with JPMS. Jigsaw breaks up the JDK itself into many modules e.g. Java.sql contains the familiar SQL classes, Java.io contains the familiar IO classes etc. As per requirement, we can use appropriate module. No need to use the entire JDK.
- Version conflicts:
Here we have 4 jar files inside classpath. Suppose JAR 4 requires a .class file with name xyz of JAR 3 and JAR 2 also contains the .class file with the name xyz. Now JVM will search for xyz class file from left to right and it will get the .class file named with xyz from JAR 2. Now the JVM will assign xyz.class file of JAR 2 inside JAR 4. But JAR 4 requires xyz.class file of JAR 3. Here we will get version conflict. With the help of JPMS, we can specify that we want a .class file of a particular JAR file. We have to specify inside module-info.Java like below:
- Security Problems: Assume we have a JAR and inside that jar we have 2 packages.
Both packages are public in nature. At some point, we might decide that our team should use geeks package and not use geeksImpl directly. However, there is no way to enforce that on the classpath. In JPMS/Jigsaw, a module contains a module-info.Java file which allows us to explicitly state what is public to other modules.