Skip to content

Commit

Permalink
[KEYCLOAK-17254] Adaptively add the default modular JVM options
Browse files Browse the repository at this point in the history
to the "javaVmArguments" to start the cache server container with,
if the JVM used to run the cache server is modular (JDK 9+)

Signed-off-by: Jan Lieskovsky <[email protected]>
  • Loading branch information
Jan Lieskovsky authored and mposolda committed Jun 3, 2021
1 parent de8dd59 commit cbd4288
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import static org.hamcrest.Matchers.lessThan;
Expand Down Expand Up @@ -83,7 +85,7 @@ public void beforeTest(@Observes(precedence = -2) Before event) {

//if annotation is present on method
InitialDcState annotation = event.getTestMethod().getAnnotation(InitialDcState.class);

//annotation not present on method, taking it from class
if (annotation == null) {
Class<?> annotatedClass = getNearestSuperclassWithAnnotation(event.getTestClass().getJavaClass(), InitialDcState.class);
Expand Down Expand Up @@ -156,7 +158,7 @@ public void beforeTest(@Observes(precedence = -2) Before event) {
forAllBackendNodesInDc(DC.FIRST, CrossDCTestEnricher::startAuthServerBackendNode);
break;
}

suspendPeriodicTasks();
}

Expand Down Expand Up @@ -266,12 +268,59 @@ private static void assertValidDc(DC dc) throws IllegalStateException {
}
}

/* Code to detect if underlying JVM is modular (AKA JDK 9+) taken over from Wildfly Core code base:
* https://github.com/wildfly/wildfly-core/blob/master/launcher/src/main/java/org/wildfly/core/launcher/Jvm.java#L59
* and turned into a function for easier reuse.
*/
public static boolean isModularJvm() {
boolean modularJvm = false;
final String javaSpecVersion = System.getProperty("java.specification.version");
if (javaSpecVersion != null) {
final Matcher matcher = Pattern.compile("^(?:1\\.)?(\\d+)$").matcher(javaSpecVersion);
if (matcher.find()) modularJvm = Integer.parseInt(matcher.group(1)) >= 9;
}
return modularJvm;
}

public static void startCacheServer(DC dc) {
if (AuthServerTestEnricher.CACHE_SERVER_LIFECYCLE_SKIP) return;

if (!containerController.get().isStarted(getCacheServer(dc).getQualifier())) {
log.infof("--DC: Starting %s", getCacheServer(dc).getQualifier());
containerController.get().start(getCacheServer(dc).getQualifier());
// Original config of the cache server container as a map
Map<String, String> containerConfig = getCacheServer(dc).getProperties();

// Start cache server with default modular JVM options set if JDK is modular (JDK 9+)
final String defaultModularJvmOptions = System.getProperty("default.modular.jvm.options");
final String originalJvmArguments = getCacheServer(dc).getProperties().get("javaVmArguments");
/* When JVM used to launch the cache server container is modular, add the default
* modular JVM options to the configuration of the cache server container if
* these aren't present there yet.
*
* See the definition of the 'default.modular.jvm.options' property for details.
*/
if (!originalJvmArguments.contains(defaultModularJvmOptions)) {
if(isModularJvm() && defaultModularJvmOptions != null) {
log.infof("Modular JVM detected. Adding default modular JVM '%s' options to the cache server container's configuration.", defaultModularJvmOptions);
final String lineSeparator = System.getProperty("line.separator");
final String adjustedJvmArguments = originalJvmArguments.replace(lineSeparator, " ") + defaultModularJvmOptions + lineSeparator;

/* Since next time the cache server container might get started using a non-modular
* JVM again, don't store the default modular JVM options into the cache server container's
* configuration permanently (not to need to remove them again later).
*
* Rather, instead of that, retrieve the original cache server container's configuration
* as a map, add the default modular JVM options there, and one-time way start the cache server
* using this custom temporary configuration.
*/
containerConfig.put("javaVmArguments", adjustedJvmArguments);
}
}
/* Finally start the cache server container:
* - Either using the original container config (case of a non-modular JVM),
* - Or using the updated container config (case of a modular JVM)
*/
containerController.get().start(getCacheServer(dc).getQualifier(), containerConfig);
log.infof("--DC: Started %s", getCacheServer(dc).getQualifier());
}
}
Expand Down
37 changes: 29 additions & 8 deletions testsuite/integration-arquillian/tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,25 @@
<cache.server.2.management.port>12000</cache.server.2.management.port>
<cache.server.console.output>true</cache.server.console.output>

<!--
~ Definition of default JVM parameters for all modular JDKs. See:
~
~ https://github.com/wildfly/wildfly-core/blob/master/core-feature-pack/common/src/main/resources/content/bin/common.sh#L19 and
~ https://github.com/wildfly/wildfly-core/blob/master/launcher/src/main/java/org/wildfly/core/launcher/AbstractCommandBuilder.java#L58
~
~ for details. The explanation / purpose of adding a particular modular option is as follows:
~ * add-exports=java.desktop/sun.awt=ALL-UNNAMED Needed by the iiop-openjdk subsystem
~ * add-opens=java.base/java.lang=ALL-UNNAMED Needed if Hibernate applications use Javassist
~ * add-opens=java.base/java.lang.invoke=ALL-UNNAMED Needed by the MicroProfile REST Client subsystem
~ * add-opens=java.base/java.io=ALL-UNNAMED Needed by JBoss Marshalling
~ * add-opens=java.base/java.security=ALL-UNNAMED Needed by WildFly Security Manager
~ * add-opens=java.base/java.util=ALL-UNNAMED Needed for marshalling of enum maps
~ * add-opens=java.management/javax.management=ALL-UNNAMED EE integration with sar mbeans requires deep reflection in javax.management
~ * add-opens=java.naming/javax.naming=ALL-UNNAMED InitialContext proxy generation requires deep reflection in javax.naming
~ * add-modules=java.se Needed for backward compatibility with jboss-modules older than jboss-modules 1.9.1.Final
-->
<default.modular.jvm.options>--add-exports=java.desktop/sun.awt=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=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.management/javax.management=ALL-UNNAMED --add-opens=java.naming/javax.naming=ALL-UNNAMED --add-modules=java.se</default.modular.jvm.options>

<dependency.keystore.root>${project.build.directory}/dependency/keystore</dependency.keystore.root>
<dependency.truststore>${dependency.keystore.root}/keycloak.truststore</dependency.truststore>
<dependency.truststore.password>secret</dependency.truststore.password>
Expand Down Expand Up @@ -561,6 +580,8 @@
<cli.log.output>${cli.log.output}</cli.log.output>
<test.intermittent>${test.intermittent}</test.intermittent>

<default.modular.jvm.options>${default.modular.jvm.options}</default.modular.jvm.options>

<dependency.keystore.root>${dependency.keystore.root}</dependency.keystore.root>
<dependency.truststore>${dependency.truststore}</dependency.truststore>
<dependency.truststore.password>${dependency.truststore.password}</dependency.truststore.password>
Expand Down Expand Up @@ -1341,7 +1362,7 @@
<systemPropertyVariables>
<run.h2>true</run.h2>
<docker.database.skip>${docker.database.skip}</docker.database.skip>

<auth.server.jboss>false</auth.server.jboss>

<auth.server.backend1.home>${auth.server.backend1.home}</auth.server.backend1.home>
Expand Down Expand Up @@ -1615,10 +1636,10 @@
<version>${appium.client.version}</version>
</dependency>

<!--
<!--
httpclient and httpcore are here to ensure we use the same version
as in keycloak/pom.xml and to prevent the other versions beeing present
on classpath during tests (as a transitive dependencies e.g.).
as in keycloak/pom.xml and to prevent the other versions beeing present
on classpath during tests (as a transitive dependencies e.g.).
There has beeen issues due to this.
-->
<dependency>
Expand Down Expand Up @@ -1876,16 +1897,16 @@
</profile>

<profile>
<id>java11-auth-server</id> <!-- a temporary workaround; TODO remove this once Java 11 is officially supported by Arquillian -->
<id>java11-auth-server</id>
<properties>
<auth.server.jvm.args.extra>--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-modules=java.se</auth.server.jvm.args.extra>
<auth.server.jvm.args.extra>${default.modular.jvm.options}</auth.server.jvm.args.extra>
</properties>
</profile>

<profile>
<id>java11-app-server</id> <!-- a temporary workaround; TODO remove this once Java 11 is officially supported by Arquillian -->
<id>java11-app-server</id>
<properties>
<app.server.jvm.args.extra>--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-modules=java.se</app.server.jvm.args.extra>
<app.server.jvm.args.extra>${default.modular.jvm.options}</app.server.jvm.args.extra>
</properties>
</profile>

Expand Down

0 comments on commit cbd4288

Please sign in to comment.