JEP 238: Multi-Version JAR Files

Peter Levart peter.levart at gmail.com
Sat Feb 14 19:54:54 UTC 2015


On 02/12/2015 09:52 PM, Paul Sandoz wrote:
> Hi
>
> In connection with the JEP there is also a design document to help the discussion:
>
>    http://cr.openjdk.java.net/~psandoz/jdk9/MultiVersionJar-8u60-9-design.md
>

Hi Paul,

Thinking about this proposal, I can't escape the feeling that the design 
favors JDK as the only target for which multi-version jars exist. The 
"versions" in the jar are just target JDK versions. Admittedly JDK is 
the most important "library" out there, but jar is a general format. So 
perhaps at the jar level, the facility could be more general. I'm 
thinking about profiles...

For example, taking a layout example from JEP and translating to the 
profiles idea:

jar root
   - A.class
   - B.class
   - C.class
   - D.class
   - META-INF
      - MANIFEST.MF
      - profiles
         - jdk8
            - A.class
            - B.class
         - jdk9
            - A.class


With additional metadata in MANIFEST.MF:

Profile-JDK9: jdk9 jdk8
Profile-JDK8: jdk8


A list (ordered) of profile names is associated with each jar file or 
expanded directory at runtime. The default list of profile names (if not 
specified on classpath) consists of just the platfrom profile name 
("JDK9" or "JDK8"), but additional profile names could be encoded as 
part of each classpath element.

For example, let's say I want to distribute a multi-profile library jar 
that depends on JDK7, JDK8 and JDK9 as platform and on guava 17 and 18. 
I could pack it as:

jar root
   - A.class
   - B.class
   - C.class
   - D.class
   - META-INF
      - MANIFEST.MF
      - profiles
         - jdk8
            - A.class
            - B.class
         - jdk9
            - A.class
         - guava18
            - C.class
         - jdk9-guava18
            - C.class

MANIFEST.MF:

Profile-JDK9: jdk9-guava18(GUAVA18) jdk9 jdk8
Profile-JDK8: jdk8
Profile-GUAVA18: guava18


Some example usages:

$JDK8_HOME/bin/java -cp guava-18.jar:mylib.jar?profile=+GUAVA18

...in this example, the list of profile names associated with mylib.jar 
is: (JDK8, GUAVA18), which yields the following search order inside 
mylib.jar:

- META-INF/profiles/jdk8
- META-INF/profiles/guava18
- jar root


$JDK9_HOME/bin/java -cp guava-18.jar:mylib.jar?profile=+GUAVA18

...in this example, the list of profile names associated with mylib.jar 
is : (JDK9, GUAVA18), which yields the following search order inside 
mylib.jar:

- META-INF/profiles/jdk9-guava18 - this is a conditional entry, included 
only when all profile names in brackets are also associated with the jar
- META-INF/profiles/jdk9
- META-INF/profiles/jdk8
- META-INF/profiles/guava18
- jar root


$JDK9_HOME/bin/java -cp guava-17.jar:mylib.jar

...in this example, the list of profile names associated with mylib.jar 
is : (JDK9), which yields the following search order inside mylib.jar:

- META-INF/profiles/jdk9
- META-INF/profiles/jdk8
- jar root


The "additional" profile names could be encoded in file: URL(s) as the 
the URL "query", for example:

file:/path/to/my.jar?pfofile=+GUAVA18

...so they are part of URL class-path in URLClassLoader.


The JarFile and JarInputStream would have to be extended to support 
specifying a list of profile names in addition to current arguments.

This is not much different from proposed JEP. It just adds a layer of 
resolving of the internal jar file paths through a list of profile names 
as opposed to hard-coding the layout. I know this complicates tooling 
support. In particular the additional options for "jar" tool, but 
verification part which validates that the exposed public API is same 
for all combinations of profiles would not be much more complicated.

The profiles idea is inspired loosely on Maven profiles.


Too complicated?


Regards, Peter




More information about the core-libs-dev mailing list