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

Reply via email to