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