Java Multi-Release JAR Files: Version Compatibility Across Java Versions
Discover the Java Multi-Release JAR feature, introduced in Java 9, which allows developers to include multiple versions of a class within a single JAR file. This feature enables compatibility across different Java versions, making it valuable for third-party libraries and frameworks that support multiple Java environments.
Java Multi-Release Jar Files
The Multi-release JAR feature was introduced in Java 9. It allows you to use multiple versions of a class depending on the Java version. This feature is particularly useful for third-party libraries or frameworks that need to maintain compatibility across different Java versions.
Why Multi-Release JAR Files?
As Java continues to evolve, new features are added with each major release. However, third-party libraries often face challenges when updating their code to support these new features. The multi-release JAR feature addresses the problem of maintaining multiple source codes for the same file by allowing platform-specific versions within a single JAR file.
Typical JAR Structure
In a typical JAR file, all classes reside at the root level:
Structure
jar root
- Calculator.class
- Util.class
- Math.class
- Service.class
However, if you have a Java 9-specific Util
class, that JAR file would not be usable in JRE 8 or lower. This is where the multi-release JAR comes in handy.
Multi-Release JAR Structure
In multi-release JAR files, a MANIFEST.MF
file contains the entry Multi-Release: true
, and the META-INF/versions
directory holds Java version-specific classes:
Structure
jar root
- Calculator.class
- Util.class
- Math.class
- Service.class
META-INF
- versions
- 9
- Util.class
- Math.class
- 10
- Util.class
- Math.class
If the JRE doesn’t support multi-release JAR files, it will load the root-level classes. Otherwise, it will load the version-specific classes. For instance, in Java 8, the root-level Util.class
is loaded, but in Java 9, the Java 9-specific Util.class
is loaded.
Creating and Using Multi-Release JAR Files
Follow these steps to create and use a multi-release JAR file with Java 7 and Java 9-specific classes.
Step 1: Create Java 7 Specific Class
Create a folder c:/test/java7/com/tutorialsarena
and create a file named Tester.java
with the following content:
Tester.java (Java 7)
package com.tutorialsarena;
public class Tester {
public static void main(String[] args) {
System.out.println("Inside Java 7");
}
}
Step 2: Create Java 9 Specific Class
Create a folder c:/test/java9/com/tutorialsarena
and create a file named Tester.java
with the following content:
Tester.java (Java 9)
package com.tutorialsarena;
public class Tester {
public static void main(String[] args) {
System.out.println("Inside Java 9");
}
}
Step 3: Compile with Target Versions
Compile the Java 7 and Java 9 specific classes:
Compilation
C:\test > javac --release 7 java7/com/tutorialsarena/Tester.java
C:\test > javac --release 9 java9/com/tutorialsarena/Tester.java
Step 4: Create the Multi-Release JAR
Create the multi-release JAR using the following command:
Create JAR
C:\test > jar -c -f test.jar -C java7 . --release 9 -C java9 .
Step 5: Run the JAR with JDK 7
Run the JAR on JDK 7 to execute the Java 7-specific class:
Run JAR (JDK 7)
C:\test > java -cp test.jar com.tutorialsarena.Tester
Output
Inside Java 7
Step 6: Run the JAR with JDK 9
Run the JAR on JDK 9 to execute the Java 9-specific class:
Run JAR (JDK 9)
C:\test > java -cp test.jar com.tutorialsarena.Tester
Output
Inside Java 9
Conclusion
With the multi-release JAR feature, you can maintain different versions of classes within a single JAR file, without worrying about backward compatibility. This approach simplifies the codebase and allows frameworks to use new Java features without rewriting older code. The key requirement is that the public interface and method signatures remain the same across different versions of the class.