Broadleaf Microservices
  • v1.0.0-latest-prod

Upgrading to Java 17 (since 1.8.1)

Since release train 1.8.1, Broadleaf officially supports Java version 17. This is an optional upgrade, and you may continue to use Java 11. If you decide to stay with Java 11, you can ignore the contents of this document, as no changes are required of you. However, if you do wish to adopt Java 17, there are several adjustments to be made in your project.

New JVM Options

A new set of VM options are required to be passed to the JVM for any execution of Broadleaf microservices under Java 17. These new options are:

--add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED\
--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED\
--add-opens=java.base/sun.nio.ch=ALL-UNNAMED\
--add-opens=java.management/com.sun.jmx.mbeanserver=ALL-UNNAMED\
--add-opens=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED\
--add-opens=java.base/sun.reflect.generics.reflectiveObjects=ALL-UNNAMED\
--add-opens=java.base/java.io=ALL-UNNAMED\
--add-opens=java.base/java.nio=ALL-UNNAMED\
--add-opens=java.base/java.util=ALL-UNNAMED\
--add-opens=java.base/java.lang=ALL-UNNAMED\
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED\
--add-opens=java.base/java.lang.invoke=ALL-UNNAMED\
--add-opens=java.base/java.time=ALL-UNNAMED\
--add-opens=java.base/java.time.format=ALL-UNNAMED

These options primarily serve to assist with Apache Ignite requirements and Kryo requirements during ModelMapper cache generation and ingestion under Java 17. At a minimum, these options should be added to your Dockerfile configuration to account for runtime requirements under JVM 17. Optionally, if you would like to take advantage of Java 17 language updates and local Java 17 testing, then your builds and maven spring-boot plugin support will need to be updated as well.

Required For Java 17 - Dockerfile Config

You will need to update any Dockerfile generating an image for a Broadleaf-based microservice. You will need to make sure you are basing your image on a Java 17 version, as well as include the additional JVM options in your entrypoint command.

Optional - Maven Surefire, Failsafe, and Spring-Boot Plugin Config

It is recommended to set a maven property for these options in your root pom.xml, and then re-use the property as needed for configuration.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <properties>
        ...
        <java.17.options>--add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED
            --add-opens=java.base/jdk.internal.misc=ALL-UNNAMED
            --add-opens=java.base/sun.nio.ch=ALL-UNNAMED
            --add-opens=java.management/com.sun.jmx.mbeanserver=ALL-UNNAMED
            --add-opens=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED
            --add-opens=java.base/sun.reflect.generics.reflectiveObjects=ALL-UNNAMED
            --add-opens=java.base/java.io=ALL-UNNAMED
            --add-opens=java.base/java.nio=ALL-UNNAMED
            --add-opens=java.base/java.util=ALL-UNNAMED
            --add-opens=java.base/java.lang=ALL-UNNAMED
            --add-opens=java.base/java.lang.reflect=ALL-UNNAMED
            --add-opens=java.base/java.lang.invoke=ALL-UNNAMED
            --add-opens=java.base/java.time=ALL-UNNAMED
            --add-opens=java.base/java.time.format=ALL-UNNAMED</java.17.options>
        ...
    </properties>

    <build>
        ...
        <pluginManagement>
            <plugins>
                ...
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>${maven-surefire-plugin.version}</version>
                    <configuration>
                        <argLine>
                            ${java.17.options}
                            -Djdk.net.URLClassPath.disableClassPathURLCheck=true
                            -Xmx1500m
                        </argLine>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-failsafe-plugin</artifactId>
                    <version>${maven-surefire-plugin.version}</version>
                    <configuration>
                        <argLine>
                            ${java.17.options}
                            -Djdk.net.URLClassPath.disableClassPathURLCheck=true
                            -Xmx1500m
                        </argLine>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    ...
                    <configuration>
                        ...
                        <jvmArguments>
                        ${java.17.options}
                        -Xdebug
                        -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=${debug.port}
                        </jvmArguments>
                        ...
                    </configuration>
                    ...
                </plugin>
                ...
            </plugins>
        </pluginManagement>
        ...
    </build>
</project>

Optional - Force Java 17 language level compilation

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<properties>
        ...
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        ...
    </properties>
</project>
Note
If you use the maven.compiler.release property, you should make sure to set it to 17 as well.

Caveats

  • Release train 1.8.1 (and beyond) includes several new versions of dependencies for Java 17 compatibility. You should make sure you’re consuming this release train version before attempting to adopt Java 17.

  • If you update your build environment to use Java 17, you may find some tests fail for some timestamp comparisons based on Java Instance precision. This has been observed when using HSQL in an integration test under JVM 17. In such cases, you may need to manually truncate nanoseconds in your test to fix the failing comparison. Note, this is a test concern - we do not anticipate any need to migrate data in your database for timestamp precision.

  • As with any change of this type, you should test your configuration in your target environment(s) for confirmation of compatibility.