RFR - 8132734: java.util.jar.* changes to support multi-release jar files

Steve Drach steve.drach at oracle.com
Thu Jan 28 21:31:12 UTC 2016

>  78  * <p>Class loaders that utilize {@code JarFile} to load classes from the
>  79  * contents of {@code JarFile} entries should construct the {@code JarFile}
>  80  * by invoking the {@link JarFile#JarFile(File, boolean, int, Release)}
>  81  * constructor with the value {@code Release.RUNTIME} assigned to the last
>  82  * argument.  This assures that classes compatible with the major
>  83  * version of the running JVM are loaded from multi-release jar files.
> What should be the expected result in scenario that the "multi-release" jar
> file actually puts all latest version entries in the base and early version entries
> in the "versions/n" directory? For example, in jdk 10, someone generates
> a mr-jar file with all classes for jdk 10 at root, but a set of jdk9 implementation/
> version entries under "versions/9" (assume we don't have class major version
> compatible issue, both compiled with early version of javac). Those jdk9 version
> classes will always get picked, even open with "Relese.VERSION_10”?

There really is no way to compel a jar file creator to make a valid multi-release jar file, and there is no way to check a multi-release jar file to assure it’s valid.  While one might be tempted to use the class file version as an indicator of what release it belongs to, that is not necessarily accurate or meaningful.  Likewise, resource files can not be partitioned into release version based on content.  While the new jar tool will have the capability to assure versioned classes have the same public api as base entry classes and that identical classes aren’t stored in both the base and versioned sections, it too depends on the input being correctly classified by the jar tool user.  Garbage in, garbage out.

>  59  * "META-INF/versions" directory.  The versioned entries are partitioned by the
>  60  * major version of Java platform releases, starting with release 9.  A
>  61  * versioned entry, with a version {@code n}, {@code 8 < n}, in the
>  62  * "META-INF/versions/{n}" directory overrides the base entry as well as any
>  63  * entry with a version number {@code i} where {@code 8 < i < n}.
> So the "versions/{n} always overrides the "base entry", as actually we don't
> have any info regarding the "version" of those base entries. Maybe I'm missing
> something here?

You are not missing anything.  If one constructs a JarFile with a Release other than Release.BASE, a base entry will be overridden by a versioned entry if one is found.

The bottom line is that the creator of a multi-release jar file must take responsibility for creating a valid multi-release jar.  Jar tool will help point out some inconsistencies but can’t actually determine if an entry has been assigned to the right release version.  And, of course, one does not need jar tool to construct a multi-release jar file — see jdk/test/lib/testlibrary/java/util/jar/CreateMultiReleaseTestJars.java

> -Sherman
> On 01/28/2016 11:09 AM, Xueming Shen wrote:
>> Steve,
>> What's the purpose of having a dedicated "JarFile.runtimeVersioned"? Based on
>> its only usages at ln#356 and #381, it appears, shouldn't getVersion() simply
>> returns Release.valueOf(version)?
>> sherman
>> On 01/27/2016 03:37 PM, Steve Drach wrote:
>>>> I'm still wondering about the phrase "root entry" as it continues to give the impression (to me anyway) that it's a resource in the root directory. I think "root" works in the JEP because it deals with simple resources like A.class and B.class that are in the root directory but it's confusing when there resources with a slash in the name. Add to this is the META-INF/versions/<n>  directories which are roots for the version specific resources. I think part of     the confusion is that the first mention of "root entry" is in the second paragraph where it has "overrides the unversioned root entry" without defining what it means. In summary, I'm wondering whether you would be up for change the terminology so that "root entry" isn't in the javadoc?
>>> I’ve released a new webrev, http://cr.openjdk.java.net/~sdrach/8132734/webrev.04/index.html<http://cr.openjdk.java.net/~sdrach/8132734/webrev.04/index.html>  that addresses the above issue.

More information about the core-libs-dev mailing list