Java Platform Module System Settings (JPMS) for Using Red Hat JBoss EAP on Java SE 17

Updated

Overview

Red Hat JBoss Enterprise Application Platform 7.4 Update 7 and later support Java SE 17; see [7]. One of the key differences between Java SE 17 and previous Java versions supported by EAP is strict enforcement of the code visibility rules the Java Platform Module System (JPMS) introduced in Java SE 9. In this article we discuss the JPMS settings used by default by an EAP process, how to adjust those settings if needed, and what settings might be appropriate for EAP client applications running on SE 17.

JPMS and Java 17

In Java SE 9 the JDK introduced the Java Platform Module System (JPMS)[1], an effort to improve the modularization of Java applications. Key aspects of this were the modularization of the JDK itself[2], and work to use JPMS to restrict application code access to JDK internals.[3] Prior to Java 16, applications could still access JDK internals without being explicitly configured to do so, with the JVM writing warnings to standard IO if this was done. But beginning with Java 16, the JVM no longer allows access to JDK internals unless the JVM has been specifically configured to allow this when it is launched.[4]

Along with the removal of the java.security.acl package and the requirement that brings to move to a purely Elytron-based security configuration[5], the JVM's strict enforcement of access to its internals is likely to be the most notable thing EAP users observe when moving from SE 11 to SE 17. However, EAP comes with out-of-the-box JPMS settings to provide its own code with necessary access, and if deployment code needs additional access, the EAP launch can be configured to allow that.

Note that EAP itself is not modularized using JPMS, i.e. it runs in what JPMS calls "classpath mode". EAP uses the JBoss Modules library to provide modularization of container and deployment code. However code in a classpath mode process still needs to comply with the JPMS requirements when using the Java SE APIs.

Standard JPMS Settings used by an EAP Server

The JPMS settings used by EAP come in two varieties: 'add-exports' and 'add-opens'. An 'add-exports' setting makes a package in a JDK module visible to the server and deployment code. An 'add-opens' setting allows reflective access to classes in a JDK module package. (EAP does a lot of reflection in order to implement things like dependency injection.)

When running on Java 11 or Java 17, an EAP process launched using one of our standard launch scripts (e.g. standalone.sh), a domain mode server or an EAP bootable jar all start with the following JPMS settings:

  • --add-exports=java.base/sun.nio.ch=ALL-UNNAMED
  • --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED
  • --add-exports=jdk.unsupported/sun.reflect=ALL-UNNAMED
  • --add-exports=java.desktop/sun.awt=ALL-UNNAMED
  • --add-exports=java.naming/com.sun.jndi.ldap=ALL-UNNAMED
  • --add-opens=java.base/java.lang=ALL-UNNAMED
  • --add-opens=java.base/java.lang.invoke=ALL-UNNAMED
  • --add-opens=java.base/java.lang.reflect=ALL-UNNAMED
  • --add-opens=java.base/java.io=ALL-UNNAMED
  • --add-opens=java.base/java.security=ALL-UNNAMED
  • --add-opens=java.base/java.util=ALL-UNNAMED
  • --add-opens=java.base/java.util.concurrent=ALL-UNNAMED
  • --add-opens=java.management/javax.management=ALL-UNNAMED
  • --add-opens=java.naming/javax.naming=ALL-UNNAMED

See comments in the $JBOSS_HOME/bin/common.sh script for information on why some of these settings are needed. Note that future EAP updates may add additional default settings if a need is identified.

The format of one of these arguments is:

--<type_of_argument>=<jpms_module_name>/<package_name>=<modules_to_which_package_is_exported_or_opened>

EAP and deployment code runs in 'unnamed' JPMS modules, so the value for 'modules_to_which_package_is_exported_or_opened' is ALL_UNNAMED.

Note that the 'package_name' value does not include subpackages.

Server-side JPMS Configuration

If testing reveals that your deployment code needs visibility to or the ability to reflect upon additional JDK packages, you can include additional 'add-exports' or 'add-opens' in the args passed to the java command. How you do this depends on how you are launching the JVM.

(Note that the examples below show adding visibility to a non-existent JDK package 'example.package'. The JVM will fail to start with such a setting; if you want to experiment with this you will need to substitute a real package name.)

Traditional Standalone Server

For a traditional standalone server, you can add additional JPMS settings by editing the standalone.conf, standalone.conf.bat or standalone.conf.ps1 file in the $JBOSS_HOME/bin dir. Add the desired settings to the value of the JAVA_OPTS variable. For example you could add a new line to the file:

JAVA_OPTS="$JAVA_OPTS --add-exports=java.base/example.package=ALL-UNNAMED"

Domain Mode Server

A domain mode server running on Java 11 or Java 17 will by default have the same JPMS settings applied as are applied to a standalone server. If you want additional settings applied to a particular server or set of servers, you can do this by adding a java-option configuration to a domain.xml or host.xml JVM management resource associated with the server. For example if you had a 'production_jvm' JVM configuration used by the servers in a server-group 'groupA', you could add a JPMS setting via a CLI command:

/server-group=groupA/jvm=production_jvm:list-add(name=jvm-options, value="--add-exports=java.base/example.package=ALL-UNNAMED")

See [6] for more information on configuring the JVM for domain mode servers.

CLI Embedded Server

An EAP CLI process will start with the same default set of JPMS settings as a standalone server. If you need to add additional exports or opens so your deployment can run in an embedded server inside the CLI process, then the CLI launch will need to include those settings.

If you are launching the CLI via a 'jboss-cli' script in the bin dir, export the JAVA_OPTS environment variable with the desired setting before launching the CLI:

 export JAVA_OPTS="$JAVA_OPTS --add-exports=java.base/example.package=ALL-UNNAMED"
 bin/jboss-cli.sh

If instead you are using the jboss-cli-client.jar, simply add the desired JPMS setting as an argument to java.

java --add-exports=java.base/example.package=ALL-UNNAMED -jar jboss-cli-client.jar

EAP Clients on Java 17

The JPMS settings needed by a client application that remotely connects to an EAP server would depend on what that application does. However, we have examined common use cases and the requirements of the client libraries EAP provides (e.g. $JBOSS_HOME/bin/client/jboss-client.jar) and the following are a reasonable set.

  • --add-exports=java.desktop/sun.awt=ALL-UNNAMED
  • --add-exports=java.naming/com.sun.jndi.ldap=ALL-UNNAMED
  • --add-opens=java.base/java.io=ALL-UNNAMED
  • --add-opens=java.base/java.lang=ALL-UNNAMED
  • --add-opens=java.base/java.lang.invoke=ALL-UNNAMED
  • --add-opens=java.base/java.lang.reflect=ALL-UNNAMED
  • --add-opens=java.base/java.security=ALL-UNNAMED
  • --add-opens=java.base/java.util=ALL-UNNAMED
  • --add-opens=java.base/java.util.concurrent=ALL-UNNAMED
  • --add-opens=java.management/javax.management=ALL-UNNAMED
  • --add-opens=java.naming/javax.naming=ALL-UNNAMED

EAP 8+ Clients on Java 17

EAP 8.0+ also requires these two JPMS settings:

--add-exports=jdk.naming.dns/com.sun.jndi.dns=ALL-UNNAMED
--add-opens=java.base/java.net=ALL-UNNAMED

Best practice is to thoroughly test your application on Java 17 and based on that testing add any necessary additional JPMS settings to your VM arguments.

Resources

[1] <Content from openjdk.java.net is not included.https://openjdk.java.net/jeps/261>
[2] <Content from openjdk.java.net is not included.https://openjdk.java.net/jeps/200>
[3] <Content from openjdk.java.net is not included.https://openjdk.java.net/jeps/260>
[4] <Content from openjdk.java.net is not included.https://openjdk.java.net/jeps/396>
[5] <https://access.redhat.com/articles/6956863>
[6] <https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.4/html-single/configuration_guide/index#jvm_settings_managed_domain>
[7] <https://access.redhat.com/articles/6961884>

Category
Components
Article Type