1

We are working to upgrade our API from Java 8 to Java 11.

However we need to support Java 8 and Java 11 both at same time because all clients are not ready to move on Java 11.

Is it possible if we can create maven build with Java 8 and Java 11 without duplicate our repository and without any change in pom.xml each time before create build for Java 8 and Java 11?

Generated artifact should have different name to distinguish Java 8 and Java 11 versions something like xyz-jdk8-0.0.1.jar and xyz-jdk11-.0.1.jar

Sushil
  • 327
  • 1
  • 3
  • 20
  • Check this: https://stackoverflow.com/questions/19654557/how-to-set-specific-java-version-to-maven#:~:text=Maven%20uses%20the%20JAVA_HOME%20parameter,(non%2Dwindows)%2F%20mvn. – User9123 Apr 19 '22 at 16:08
  • 1
    Java is backwardly compatible: Jars built using older versions will run in newer JREs. 1) Build in Java 8. 2) Upgrade all runtime envs. 3) Upgrade build server. 4) Upgrade developer env. – Bohemian Apr 19 '22 at 16:08
  • Build with JDK11 and use `--release 8` that will work... using `8` and make maven-enforcer rule to require at minimum to build with JDK11.... – khmarbaise Apr 19 '22 at 16:17
  • I think it should work for me - https://stackoverflow.com/questions/10920142/how-to-configure-maven-to-build-two-versions-of-an-artifact-each-one-for-a-diff – Sushil Apr 20 '22 at 00:07

3 Answers3

2

TL;DR

You don't need that, just build to Java 8 and be happy!


Solving

You can use Maven Build Profiles for this: https://maven.apache.org/guides/introduction/introduction-to-profiles.html

1. Set your properties to Java 11:

<properties>
  <maven.compiler.target>11</maven.compiler.target>
  <maven.compiler.source>11</maven.compiler.source>
  <maven.compiler.release>11</maven.compiler.release>
</properties>

2. Set your final name:

<build>
  <finalName>${project.artifactId}-jdk11-${project.version}</finalName>
</build>

3. Add a profile:

<profile>
  <id>jdk-8</id>
  <properties>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.release>1.8</maven.compiler.release>
  </properties>
  <build>
    <finalName>${project.artifactId}-jdk8-${project.version}</finalName>
  </build>
</profile>

4. Build:

You will need to run 2 builds, one normal, and other activating the JDK 8 profile:

$ mvn ...
$ mvn ... -P jdk-8

Considerations:

  • Always use JDK 11 as it can confidently build Java 8 targets;
  • You don't need target and source properties, but if some plugin fails, put it back.
Claudio Weiler
  • 589
  • 2
  • 15
  • Thanks. One more point I missed to add that api jar should have diffderent name for Java 8 and Java 11 otherwise it will create confusion for users. I think xyz-jdk8-version.jar and xyz-jdk11.version.jar. Let me see if we can do it using profile. – Sushil Apr 19 '22 at 23:48
  • Yes, you can, just mess with finalName: https://maven.apache.org/pom.html. Edited my answer. – Claudio Weiler Apr 20 '22 at 15:08
1

I found a way to do that, which lies somewhat in the middle of Java 8 and Java 11. The main problem with the above solution occurs in case you have (or want to define) a module-info.java that can't be parsed in Java 8.

I started considering a solution with <classifier>s, likewise Claudio Weiler above answer but did not wanted to bother having two separate builds (and even two separate branches because I wanted to manage module-info).

I also noticed that some libraries like the JAXB API or activation API (jakarta.xml.bind:jakarta.xml.bind-api:2.3.3) shows a module-info when you use it in Java 11, but is compatible with Java 8 .

Digging into how the details of how the build of the com.sun.activiation:jakarta.activation library was made, I found the following solution :

  • compile the module-info.java with Java 11
  • compile the rest of your code (including tests) with Java 8. Of course, this has the drawback of not being able to use fully Java 11 features...

You thus need to add the following snippet in the <build> section of your pom.xml:

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <executions>
        <execution>
        <id>default-compile</id>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
            <excludes>
            <exclude>module-info.java</exclude>
            </excludes>
        </configuration>
        </execution>
        <execution>
        <id>module-info-compile</id>
        <goals>
            <goal>compile</goal>
        </goals>
        <configuration>
            <release>11</release>
            <includes>
            <include>module-info.java</include>
            </includes>
        </configuration>
        </execution>
        <execution>
        <id>default-testCompile</id>
        <configuration>
            <release>11</release>
        </configuration>
        </execution>
    </executions>
</plugin>

I hope that helps.

potame
  • 7,597
  • 4
  • 26
  • 33
0

You should:

  • Remove from you POM, if present, maven.compiler.source and maven.compiler.target.
  • Set JAVA_HOME=<<JAVA_8_HOME_FOLDER>>.
  • Build from Java 8 by mvn clean install.
  • Take the Java 8 artifact.
  • Set JAVA_HOME=<<JAVA_11_HOME_FOLDER>>.
  • Build from Java 11 by mvn clean install.
  • Take the Java 11 artifact.
Antonio Petricca
  • 8,891
  • 5
  • 36
  • 74