Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 900433 - java-pkg-simple.eclass: Support building multi-release JAR files [JEP 238]
Summary: java-pkg-simple.eclass: Support building multi-release JAR files [JEP 238]
Status: CONFIRMED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Eclasses (show other bugs)
Hardware: All Linux
: Normal normal
Assignee: Java team
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-03-08 22:15 UTC by Yuan Liao (Leo3418)
Modified: 2023-03-08 22:21 UTC (History)
0 users

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Yuan Liao (Leo3418) 2023-03-08 22:15:44 UTC
Many Java projects have adopted the *multi-release JAR file* standard (introduced by JEP 238 <https://openjdk.org/jeps/238>) to:
- Maintain compatibility with older Java major releases
- Leverage new features in the latest Java releases
- Avoid delivering multiple JAR files just for different Java major releases

For example, a multi-release JAR file can target Java 8 as the minimal supported release and, at the same time, include class files that are only compatible with Java 9 and above.  In this case, the class files compatible with only Java 9+ will not be loaded on Java 8.  Thus, users can switch between Java 8 and 9+ and reuse the same JAR file, instead of download a different JAR file for different Java major releases.

The multi-release JAR file standard is specified in the JAR File Specification:
https://docs.oracle.com/en/java/javase/17/docs/specs/jar/jar.html#multi-release-jar-files

java-pkg-simple.eclass should provide the functionality to create a multi-release JAR file, so ebuilds for Java projects whose upstream delivers multi-release JAR files can be easily created.
Comment 1 Yuan Liao (Leo3418) 2023-03-08 22:21:43 UTC
Extra Information That May Be Useful to This Functionality's Implementation


Summary of the multi-release JAR file standard:

- Definitions:

  - Multi-release JAR file:
    A JAR file in which the META-INF/MANIFEST.MF file bears the line:
        Multi-Release: true

  - Versioned directory:
    A 'META-INF/versions/<N>' directory in a multi-release JAR file,
    where <N> is the Java major release number (9, 10, 11, ..., 17, ...) that
    files under this directory target.

- Requirements:

  - "The public API exported by the classes in a multi-release JAR file must be
    exactly the same across versions".
    
    Interpretation: This eliminates the possibility where a class that is part
    of a public API is only available on certain latest Java major releases and
    not on older releases.  The public API's implementation may alter between
    different Java major releases to utilize the releases' latest features, but
    the API's interface may not.


The 'jar' tool itself naturally supports building a multi-release JAR file
<https://docs.oracle.com/en/java/javase/17/docs/specs/man/jar.html>:

    --release VERSION
        Creates a multirelease JAR file. Places all files specified after the
        option into a versioned directory of the JAR file named
        META-INF/versions/VERSION/, where VERSION must be must be a positive
        integer whose value is 9 or greater.

        At run time, where more than one version of a class exists in the JAR,
        the JDK will use the first one it finds, searching initially in the
        directory tree whose VERSION number matches the JDK's major version
        number. It will then look in directories with successively lower
        VERSION numbers, and finally look in the root of the JAR.

The same page also provides an example invocation of 'jar' that builds a
multi-release JAR file under the "Examples of jar Command Syntax" section.


Build systems like Maven and Gradle have been supporting building multi-release
JAR files already:
- Maven: https://maven.apache.org/plugins/maven-compiler-plugin/multirelease.html
- Gradle: https://blog.gradle.org/mrjars#how-to-create-a-multi-release-jar-with-gradle