Java 9's other new enhancements, Part 4: Multi-release JAR files

Multiple, Java-release-specific versions of class/resource files can now coexist in the same JAR file

Page 2 of 2

MRJI requires two command-line arguments. The first argument identifies a multi-release JAR file and the second argument is the name of a versioned class file (including the .class file extension). In other words, the second argument identifies a content root class file with an alternative version that's also stored.

Assuming that Java 9 is current, compile Listing 4 (javac MRJI.java). Assuming that you previously created a pid.jar file, run this application as follows:

java MRJI pid.jar Util.class

I observe the following output from my pid.jar file:

Base version: 8
Runtime version: 9
Version: 9
Multi-release JAR file: true

META-INF/
META-INF/MANIFEST.MF
PrintPID.class
Util.class
META-INF/versions/9/Util.class

2017-03-22T00:19:30

Base version: 8
Runtime version: 9
Version: 9
Multi-release JAR file: true

META-INF/
META-INF/MANIFEST.MF
PrintPID.class
Util.class
META-INF/versions/9/Util.class

2017-03-22T00:19:36

Whether or not I use the new JarFile constructor, the same base version, runtime version, version, and multi-release JAR file query values are output. However, when I don't use the new constructor, the content root's Util.class file is accessed. With the new constructor, the versioned Util.class file is accessed.

Because both Util.class files have the same name, I invoke java.util.jar.JarEntry's LocalDateTime getTimeLocal() method to return the named entry's last modification time in local date-time format. The time value is 00:19:30 for the content root entry and 00:19:36 for the versioned entry, as shown by running jar tvf pid.jar:

  0 Wed Mar 22 00:20:24 CDT 2017 META-INF/
107 Wed Mar 22 00:20:24 CDT 2017 META-INF/MANIFEST.MF
568 Wed Mar 22 00:19:30 CDT 2017 PrintPID.class
740 Wed Mar 22 00:19:30 CDT 2017 Util.class
488 Wed Mar 22 00:19:36 CDT 2017 META-INF/versions/9/Util.class

Suppose you change Runtime.Version.parse("9") to Runtime.Version.parse("8") in Listing 4's main() method and recompile the source code. When you run the application as previously shown, you'll observe that the final output line changes from 2017-03-22T00:19:36 to 2017-03-22T00:19:30. Because the maximum version number used for searching versioned entries is 8, and because there is no 8 directory, which isn't supported by the multi-release JAR file specification (9 is the minimum version), the runtime can only return the content root's Util.class entry, whose last modification time happens to be 2017-03-22T00:19:30.

Conclusion

JEP 238 also discusses modular multi-release JAR files (multi-release JAR files that store module descriptors [module-info.class files] in their root locations). Because I'm not covering modules in this series, I'm not discussing multi-release JAR files in a module context. Check out JEP 238: Multi-Release JAR Files for more information on this topic.

download
Get the source code for this post's applications. Created by Jeff Friesen for JavaWorld

The following software was used to develop the post's code:

  • 64-bit JDK 9ea+154

The post's code was tested on the following platform(s):

  • JVM on 64-bit Windows 8.1
| 1 2 Page 2