Java Tutorial

Java Control Statements

Object Oriented Programming

Java Built-in Classes

Java File Handling

Java Error & Exceptions

Java Multithreading

Java Synchronization

Java Networking

Java Collections

Java Interfaces

Java Data Structures

Java Collections Algorithms

Advanced Java

Java Miscellaneous

Java APIs & Frameworks

Java Class References

Java Useful Resources

Java - Multi-Release Jar Files



Multi-release JAR feature was introduced in Java 9. It allows to use of multiple versions of a class pertaining to multiple versions of Java. For example, many third-party libraries or frameworks use Java. As Java as a language is continuously evolving and with every major release, many new features are getting added to the language. As third-party libraries/frameworks have to rewrite their code base in order to accommodate new features, teams are highly reluctant to use the new features. It acts as a hindrance to them to move to the new versions of Java.

In order to counter this problem of maintenance of multiple source codes of the same file or platform-specific version of a file, the Multirelease JAR feature was introduced. Consider the following example:

A typical jar file has all the classes at the root level.

jar root
   - Calculator.class
   - Util.class
   - Math.class
   - Service.class

If we've Java 9 feature specific Util class then that jar cannot be used in JRE 8 or lower.

In multi-release Jar, the format has been enhanced to have different versions of Java classes or resources that can be maintained and used as per the platform. In JAR, a file MANIFEST.MF file has an entry Multi-Release: true in its main section. META-INF directory also contains a versions subdirectory whose subdirectories (starting with 9 for Java 9 ) store version-specific classes and resource files.

Using MANIFEST.MF, we can specific Java 9 or higher version-specific classes in separate locations as shown below:

Java Multi-Release Jar Files Directory Structure

jar root
   - Calculator.class
   - Util.class
   - Math.class
   - Service.class
   META-INF
      - versions
      - 9
         - Util.class
         - Math.class
      - 10
         - Util.class
         - Math.class

Now if JRE is not support Multi-release jar, then it will choose the root level classes to load and execute otherwise, version specific classes will be loaded. For example, if above jar is used in Java 8, then root level Util.class will be used. If same jar is executed by Java 9, then java 9 version specific class will be picked and so on. This way, third party libraries/frameworks can support new features without changing their source codes which was written targeting the lower versions.

Creating and Using Multi-Release Jar Files in Java

In this example, we'll be creating and using a multi-release jar to have two versions of Tester.java file, one for jdk 7 and one for jdk 9 and run it on different jdk versions.

The following are the steps for creating and using multi-release jar files in Java -

Step 1: Create Java 7 Specific Java Class

Let's create a Java class that may have Java 7 specific code and features which is not available prior to Java 9. In this example, we're simply printing a message just to showcase the usage of this feature.

Create a folder c:/test/java7/com/tutorialspoint. Create Tester.java with following content −

Tester.java

This is a simple code where we're printing a Java 7 specific message when program is executed.

package com.tutorialspoint;

public class Tester {
   public static void main(String[] args) {
      System.out.println("Inside java 7");
   }
}

Step 2: Create Java 9 Specific Java Class

Let's create a Java class that may have code specific to Java 9 enhancements and features which is not available prior to Java 9. In this example, we're simply printing a message just to showcase the usage of this feature.

Create a folder c:/test/java9/com/tutorialspoint. Create Tester.java with following content −

Tester.java

This is also similar code as above where we're printing a Java 9 specific message when program is executed.

package com.tutorialspoint;

public class Tester {
   public static void main(String[] args) {
      System.out.println("Inside java 9");
   }
}

In order to use multi-release jar feature, we must ensure that signature of both class should be same. Public interface like method signatures should be same in both the classes.

Step 3: Compile with Target Versions

C:\test > javac --release 9 java9/com/tutorialspoint/Tester.java

C:\JAVA > javac --release 7 java7/com/tutorialspoint/Tester.java

Step 4: Create a Multi-Release JAR

C:\JAVA > jar -c -f test.jar -C java7 . --release 9 -C java9.
Warning: entry META-INF/versions/9/com/tutorialspoint/Tester.java, 
   multiple resources with same name

Step 5: Run the JAR with JDK 7

C:\JAVA > java -cp test.jar com.tutorialspoint.Tester
Inside Java 7

Step 6: Run the JAR JDK 9

C:\JAVA > java -cp test.jar com.tutorialspoint.Tester
Inside Java 9

Conclusion

We can see, that with multi-release Jar feature, we can create multiple version of a class without having backwards compatibility issues. We've showcased that same command can be used to execute a class. Based on the JRE version listed in META-INF file, the corresponding class is picked. In case of lower JRE version which is not supporting Multi-Release jar, the root level classes are picked instead of version specific classes. And lastly, the signature of public methods of the versioned classes should be same so this functionality can work perfectly.

Advertisements