Skip to content

radcortez/smallrye-parent

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

badge License smallrye parent?color=green

SmallRye Parent

Define Maven setup for all SmallRye projects.

Multi-Release JARs

Starting with version 13, the SmallRye Parent POM provides a framework for multi-release JAR build and test.

Functional overview

The multi-release JAR support works in two parts: compilation and testing.

Compilation

Compilation works by providing extra executions of the compiler plugin in order to build the additional JAR layers. The base layer is built by the standard default-compile execution. After that, Maven profiles are activated based on the presence of extra layer source directories (e.g. src/main/java9, src/main/java10 etc.). These profiles contain additional executions of the compiler plugin which compile the sources in the layer directory, while putting the output of the previous step on the class path.

Each present layer is in turn compiled with the results of all the previous layers on the classpath in the correct order. The additional layer class files are output under the target/classes directory in the appropriate location for multi-release JAR layers.

In order to select the correct class files for the given Java version, the <release> property is used. This prevents accidental usage of APIs which are only present in later versions than the one being compiled. However there is a limitation to this strategy: Java 9 and later do not provide runtime information for non-standard Java 8 classes such as sun.misc.Unsafe. If your project needs to compile against these classes, you must use the dependency plugin as described below.

Note that by default, building Java 8 sources does not use the <release> property. To enable this feature, create a file (which may be empty) in your project root named build-release-8.

Testing

Testing using maven-surefire-plugin is supported by running the project unit tests on every supported Java version. In order to do so, it is expected that the following system property or properties are set as needed:

  • java8.home: this property must be set to the location of a Java 8 JDK installation

  • java9.home: this property must be set to the location of a Java 9 JDK installation

  • java10.home: this property must be set to the location of a Java 10 JDK installation

  • java11.home: this property must be set to the location of a Java 11 JDK installation

  • java12.home: this property must be set to the location of a Java 12 JDK installation

  • java13.home: this property must be set to the location of a Java 13 JDK installation

In order to simplify development, it is recommended to project maintainers to set these properties in your personal Maven settings.xml file.

Extra unit tests are run for a given platform whenever a newer version than that platform was used to build the project and the appropriate control file is found (see Build control files reference).

Configuration

To configure a multi-release JAR, you need the following pieces of information:

  • The minimum (oldest) version of Java that will be supported by the project

  • The maximum (newest) version of Java for which your project has sources

Step 1: Base layer version

Choose your base layer version. This can be Java 8 or anything later. Configure the version by configuring the release property in the default-compile execution of maven-compiler-plugin:

<plugin>
  <artifactId>maven-compiler-plugin</artifactId>
  <executions>
    <execution>
      <id>default-compile</id>
      <configuration>
        <release>8</release>
      </configuration>
    </execution>
  </executions>
</plugin>

If the build-release-8 property is present in the root of your project, then this step is automatically done for you.

Note that a single-layer Java 8 build does not support the release element because the corresponding javac option is only present in JDK 9 and later.

Step 2: Highest layer version

Configure the jdk.min.version property as described above to match either:

  • The maximum (newest) Java version for which sources exist in your project, or

  • Some Java version higher than that

This is the version of Java that will build all of your layers, so it necessarily must be able to compile every version of Java sources from oldest to newest.

Step 3: Source directories

The sources for your base layer continue to reside in src/main/java and src/test/java.

Additional layers are in directories whose names correspond to the version of Java that is targeted by that directory. For example, sources which are specific to Java 9 and later would be in src/main/java9, whereas sources which are specific to Java 11 and later would be in src/main/java11.

If you have a class that needs an alternative version for a given Java version, you only need to provide the replacement source file in the directory corresponding to the oldest version that supports the alternative source. It is not necessary to copy identical classes into more than one layer; doing so will increase the size of the resultant artifact needlessly.

There are restrictions on these directories. You may only provide sources that correspond to sources that exist in the base layer - that is, it is a violation of the MR JAR specification to provide sources that introduce new APIs only in later Java versions. The JDK does enforce this at run time. In addition, providing additional public members in later versions is generally not recommended.

Missing JDK APIs

If your project relies on APIs which are not in the Java SE specification (for example, classes such as sun.misc which are present in the jdk.unsupported module in Java 9 and later), and your base layer targets Java 8, you must take an additional step.

Since these APIs are not included in the class database that javac uses to compile (even though they are present at run time), stubs of the extra classes must be included but only during compilation.

To automatically perform this step, create a file in your project root named build-include-jdk-misc. The contents of this file do not matter; it can be empty or it can contain text referring to this document.

Using MR JAR functions with GitHub Actions

Using this functionality with GitHub Actions is relatively simple. It entails adding the additional JDK version(s) by way of a setup action, and then passing the location of each additional JDK to the build.

At the time of this writing, the commonly-used actions/setup-java does not provide useful environment variables for multiple JDK installs, so it is recommended to instead use the AdoptOpenJDK/install-jdk action instead.

As an example, for a project that is built on Java 11 but must also be tested against JDK 8, 9, and 10, your build.yml might look something like this:

jobs:
  build:
    runs-on: ubuntu-latest
    name: Build using Maven

    steps:
      - uses: actions/checkout@v2
        name: Checkout

      - uses: AdoptOpenJDK/install-jdk@v1
        name: Set up JDK 11
        with:
          version: 11

      - uses: AdoptOpenJDK/install-jdk@v1
        name: Set up JDK 10
        with:
          version: 10
          targets: 'JAVA_HOME_10'

      - uses: AdoptOpenJDK/install-jdk@v1
        name: Set up JDK 9
        with:
          version: 9
          targets: 'JAVA_HOME_9'

      - uses: AdoptOpenJDK/install-jdk@v1
        name: Set up JDK 8
        with:
          version: 8
          targets: 'JAVA_HOME_8'

      - name: Build
        run: mvn -B verify --file pom.xml -Djava8.home=$JAVA_HOME_8 -Djava9.home=$JAVA_HOME_9 -Djava10.home=$JAVA_HOME_10

Note that this configuration causes the default JAVA_HOME environment to be set to JDK 11.

Build control files reference

File name Purpose Reference

build-release-8

Use the <release> option to set Java 8 for the base layer.

Step 1: Base layer version

build-include-jdk-misc

Include the jdk-misc dependency for Java 8 builds.

Missing JDK APIs

build-test-java8

Run tests for Java 8 when java8.home is set and JDK 9 or later is used.

Testing

build-test-java9

Run tests for Java 9 when java9.home is set and JDK 10 or later is used.

Testing

build-test-java10

Run tests for Java 10 when java10.home is set and JDK 11 or later is used.

Testing

build-test-java11

Run tests for Java 11 when java11.home is set and JDK 12 or later is used.

Testing

build-test-java12

Run tests for Java 12 when java12.home is set and JDK 13 or later is used.

Testing

build-test-java13

Run tests for Java 13 when java13.home is set and JDK 14 or later is used.

Testing

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published