diff --git a/.github/workflows/wildfly-ci.yml b/.github/workflows/wildfly-ci.yml index 68f0adc..7f00ace 100644 --- a/.github/workflows/wildfly-ci.yml +++ b/.github/workflows/wildfly-ci.yml @@ -29,7 +29,7 @@ jobs: fail-fast: false matrix: os: [ 'ubuntu-latest' , 'windows-latest' ] - java: ['17', '21', '24-ea'] + java: ['17', '21'] steps: - uses: actions/checkout@v4 diff --git a/pom.xml b/pom.xml index 5a05324..d3482dc 100644 --- a/pom.xml +++ b/pom.xml @@ -286,6 +286,7 @@ + true diff --git a/src/main/java/org/wildfly/core/launcher/CliCommandBuilder.java b/src/main/java/org/wildfly/core/launcher/CliCommandBuilder.java index 20f0ce3..5952d66 100644 --- a/src/main/java/org/wildfly/core/launcher/CliCommandBuilder.java +++ b/src/main/java/org/wildfly/core/launcher/CliCommandBuilder.java @@ -654,12 +654,10 @@ public Path getJavaHome() { public List buildArguments() { final List cmd = new ArrayList<>(getJavaOptions()); if (modularLauncher) { - if (environment.getJvm().isModular()) { - cmd.addAll(JBossModulesCommandBuilder.DEFAULT_MODULAR_VM_ARGUMENTS); - for (final String optionalModularArgument : JBossModulesCommandBuilder.OPTIONAL_DEFAULT_MODULAR_VM_ARGUMENTS) { - if (Jvm.isPackageAvailable(environment.getJvm().getPath(), optionalModularArgument)) { - cmd.add(optionalModularArgument); - } + cmd.addAll(JBossModulesCommandBuilder.DEFAULT_MODULAR_VM_ARGUMENTS); + for (final String optionalModularArgument : JBossModulesCommandBuilder.OPTIONAL_DEFAULT_MODULAR_VM_ARGUMENTS) { + if (Jvm.isPackageAvailable(environment.getJvm().getPath(), optionalModularArgument)) { + cmd.add(optionalModularArgument); } } } diff --git a/src/main/java/org/wildfly/core/launcher/DomainCommandBuilder.java b/src/main/java/org/wildfly/core/launcher/DomainCommandBuilder.java index b95f4bd..f4e5539 100644 --- a/src/main/java/org/wildfly/core/launcher/DomainCommandBuilder.java +++ b/src/main/java/org/wildfly/core/launcher/DomainCommandBuilder.java @@ -709,12 +709,10 @@ public List buildArguments() { // PROCESS_CONTROLLER_JAVA_OPTS cmd.addAll(processControllerJavaOpts.asList()); - if (environment.getJvm().isModular()) { - cmd.addAll(DEFAULT_MODULAR_VM_ARGUMENTS); - for (final String optionalModularArgument : OPTIONAL_DEFAULT_MODULAR_VM_ARGUMENTS) { - if (Jvm.isPackageAvailable(environment.getJvm().getPath(), optionalModularArgument)) { - cmd.add(optionalModularArgument); - } + cmd.addAll(DEFAULT_MODULAR_VM_ARGUMENTS); + for (final String optionalModularArgument : OPTIONAL_DEFAULT_MODULAR_VM_ARGUMENTS) { + if (Jvm.isPackageAvailable(environment.getJvm().getPath(), optionalModularArgument)) { + cmd.add(optionalModularArgument); } } if (environment.getJvm().enhancedSecurityManagerAvailable()) { @@ -745,12 +743,10 @@ public List buildArguments() { // HOST_CONTROLLER_JAVA_OPTS cmd.addAll(hostControllerJavaOpts.asList()); - if (hostControllerJvm.isModular()) { - cmd.addAll(DEFAULT_MODULAR_VM_ARGUMENTS); - for (final String optionalModularArgument : OPTIONAL_DEFAULT_MODULAR_VM_ARGUMENTS) { - if (Jvm.isPackageAvailable(environment.getJvm().getPath(), optionalModularArgument)) { - cmd.add(optionalModularArgument); - } + cmd.addAll(DEFAULT_MODULAR_VM_ARGUMENTS); + for (final String optionalModularArgument : OPTIONAL_DEFAULT_MODULAR_VM_ARGUMENTS) { + if (Jvm.isPackageAvailable(environment.getJvm().getPath(), optionalModularArgument)) { + cmd.add(optionalModularArgument); } } if (hostControllerJvm.enhancedSecurityManagerAvailable()) { diff --git a/src/main/java/org/wildfly/core/launcher/JBossModulesCommandBuilder.java b/src/main/java/org/wildfly/core/launcher/JBossModulesCommandBuilder.java index 32e519f..2b6b73f 100644 --- a/src/main/java/org/wildfly/core/launcher/JBossModulesCommandBuilder.java +++ b/src/main/java/org/wildfly/core/launcher/JBossModulesCommandBuilder.java @@ -172,8 +172,11 @@ public static JBossModulesCommandBuilder of(final String wildflyHome, final Stri * @return the builder */ public JBossModulesCommandBuilder setUseSecurityManager(final boolean useSecMgr) { - this.useSecMgr = useSecMgr; - return this; + if (environment.getJvm().isSecurityManagerSupported()) { + this.useSecMgr = useSecMgr; + return this; + } + throw MESSAGES.securityManagerNotSupported(environment.getJvm().getPath()); } /** @@ -616,12 +619,10 @@ public List buildArguments() { cmd.add("-javaagent:" + getModulesJarName()); } cmd.addAll(getJavaOptions()); - if (environment.getJvm().isModular()) { - cmd.addAll(DEFAULT_MODULAR_VM_ARGUMENTS); - for (final String optionalModularArgument : OPTIONAL_DEFAULT_MODULAR_VM_ARGUMENTS) { - if (Jvm.isPackageAvailable(environment.getJvm().getPath(), optionalModularArgument)) { - cmd.add(optionalModularArgument); - } + cmd.addAll(DEFAULT_MODULAR_VM_ARGUMENTS); + for (final String optionalModularArgument : OPTIONAL_DEFAULT_MODULAR_VM_ARGUMENTS) { + if (Jvm.isPackageAvailable(environment.getJvm().getPath(), optionalModularArgument)) { + cmd.add(optionalModularArgument); } } if (environment.getJvm().enhancedSecurityManagerAvailable()) { diff --git a/src/main/java/org/wildfly/core/launcher/Jvm.java b/src/main/java/org/wildfly/core/launcher/Jvm.java index 0414449..49a5f80 100644 --- a/src/main/java/org/wildfly/core/launcher/Jvm.java +++ b/src/main/java/org/wildfly/core/launcher/Jvm.java @@ -27,8 +27,9 @@ class Jvm { private static final String JAVA_EXE; private static final Path JAVA_HOME; - private static final boolean MODULAR_JVM = true; - private static final boolean ENHANCED_SECURITY_MANAGER = Runtime.version().feature() >= 12; + private static final boolean SUPPORTS_SECURITY_MANGER = Runtime.version().feature() < 24; + private static final boolean ENHANCED_SECURITY_MANAGER = SUPPORTS_SECURITY_MANGER && Runtime.version() + .feature() >= 12; static { String exe = "java"; @@ -40,15 +41,15 @@ class Jvm { JAVA_HOME = Paths.get(javaHome); } - private static final Jvm DEFAULT = new Jvm(JAVA_HOME, MODULAR_JVM, ENHANCED_SECURITY_MANAGER); + private static final Jvm DEFAULT = new Jvm(JAVA_HOME, SUPPORTS_SECURITY_MANGER, ENHANCED_SECURITY_MANAGER); private final Path path; - private final boolean isModular; + private final boolean isSecurityManagerSupported; private final boolean enhancedSecurityManager; - private Jvm(final Path path, final boolean isModular, final boolean enhancedSecurityManager) { + private Jvm(final Path path, final boolean isSecurityManagerSupported, final boolean enhancedSecurityManager) { this.path = path; - this.isModular = isModular; + this.isSecurityManagerSupported = isSecurityManagerSupported; this.enhancedSecurityManager = enhancedSecurityManager; } @@ -87,7 +88,7 @@ static Jvm of(final Path javaHome) { return DEFAULT; } final Path path = validateJavaHome(javaHome); - return new Jvm(path, isModularJavaHome(path), hasEnhancedSecurityManager(javaHome)); + return new Jvm(path, isSecurityManagerSupported(javaHome), hasEnhancedSecurityManager(javaHome)); } /** @@ -113,8 +114,18 @@ public Path getPath() { * * @return {@code true} if this is a modular JVM, otherwise {@code false} */ + @Deprecated(forRemoval = true, since = "1.0") public boolean isModular() { - return isModular; + return true; + } + + /** + * Indicates if the security manager is supported for this JVM. + * + * @return {@code true} if this is a security manager is supported in this JVM, otherwise {@code false} + */ + public boolean isSecurityManagerSupported() { + return isSecurityManagerSupported; } /** @@ -126,13 +137,7 @@ public boolean enhancedSecurityManagerAvailable() { return enhancedSecurityManager; } - private static boolean isModularJavaHome(final Path javaHome) { - final Path jmodsDir = javaHome.resolve("jmods"); - // If the jmods directory exists we can safely assume this is a modular JDK, note even in a modular JDK this - // may not exist. - if (Files.isDirectory(jmodsDir)) { - return true; - } + private static boolean isSecurityManagerSupported(final Path javaHome) { // Next check for a $JAVA_HOME/release file, for a JRE this will not exist final Path releaseFile = javaHome.resolve("release"); if (Files.isReadable(releaseFile) && Files.isRegularFile(releaseFile)) { @@ -143,28 +148,22 @@ private static boolean isModularJavaHome(final Path javaHome) { if (line.startsWith("JAVA_VERSION=")) { // Get the version value final int index = line.indexOf('='); - return isModularJavaVersion(line.substring(index + 1).replace("\"", "")); + return isSecurityManagerSupported(line.substring(index + 1).replace("\"", "")); } } } catch (IOException ignore) { } } // Final check is to launch a new process with some modular JVM arguments and check the exit code - return isModular(javaHome); + return isSecurityManagerSupportedInJvm(javaHome); } - private static boolean isModularJavaVersion(final String version) { + private static boolean isSecurityManagerSupported(final String version) { if (version != null) { try { final String[] versionParts = version.split("\\."); - if (versionParts.length == 1) { - return Integer.parseInt(versionParts[0]) >= 9; - } else if (versionParts.length > 1) { - // Check the first part and if one, use the second part - if ("1".equals(versionParts[0])) { - return Integer.parseInt(versionParts[2]) >= 9; - } - return Integer.parseInt(versionParts[0]) >= 9; + if (versionParts.length >= 1) { + return Integer.parseInt(versionParts[0]) < 24; } } catch (Exception ignore) { } @@ -196,19 +195,20 @@ static boolean isPackageAvailable(final Path javaHome, final String optionalModu } /** - * Checks to see if the {@code javaHome} is a modular JVM. + * Checks to see if the {@code javaHome} supports the security manager. * - * @param javaHome the Java Home if {@code null} an attempt to discover the Java Home will be done + * @param javaHome the Java Home * - * @return {@code true} if this is a modular environment + * @return {@code true} if this JVM supports the security manager */ - private static boolean isModular(final Path javaHome) { + private static boolean isSecurityManagerSupportedInJvm(final Path javaHome) { final List cmd = new ArrayList<>(); cmd.add(resolveJavaCommand(javaHome)); - cmd.add("--add-modules=java.se"); + cmd.add("-Djava.security.manager"); cmd.add("-version"); return checkProcessStatus(cmd); } + /** * Checks the process status. * @@ -251,7 +251,7 @@ private static boolean checkProcessStatus(final List cmd) { return result; } - private static boolean containsWarning(final Path logFile) throws IOException { + private static boolean containsWarning(final Path logFile) throws IOException { String line; try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(logFile.toFile())))) { while ((line = br.readLine()) != null) { diff --git a/src/main/java/org/wildfly/core/launcher/StandaloneCommandBuilder.java b/src/main/java/org/wildfly/core/launcher/StandaloneCommandBuilder.java index a0a1895..4eeb51b 100644 --- a/src/main/java/org/wildfly/core/launcher/StandaloneCommandBuilder.java +++ b/src/main/java/org/wildfly/core/launcher/StandaloneCommandBuilder.java @@ -572,12 +572,10 @@ public List buildArguments() { cmd.add("-javaagent:" + getModulesJarName()); } cmd.addAll(getJavaOptions()); - if (environment.getJvm().isModular()) { - cmd.addAll(DEFAULT_MODULAR_VM_ARGUMENTS); - for (final String optionalModularArgument : OPTIONAL_DEFAULT_MODULAR_VM_ARGUMENTS) { - if (Jvm.isPackageAvailable(environment.getJvm().getPath(), optionalModularArgument)) { - cmd.add(optionalModularArgument); - } + cmd.addAll(DEFAULT_MODULAR_VM_ARGUMENTS); + for (final String optionalModularArgument : OPTIONAL_DEFAULT_MODULAR_VM_ARGUMENTS) { + if (Jvm.isPackageAvailable(environment.getJvm().getPath(), optionalModularArgument)) { + cmd.add(optionalModularArgument); } } if (environment.getJvm().enhancedSecurityManagerAvailable()) { diff --git a/src/main/java/org/wildfly/core/launcher/logger/LauncherMessages.java b/src/main/java/org/wildfly/core/launcher/logger/LauncherMessages.java index 1f6db0e..6f8b2eb 100644 --- a/src/main/java/org/wildfly/core/launcher/logger/LauncherMessages.java +++ b/src/main/java/org/wildfly/core/launcher/logger/LauncherMessages.java @@ -45,4 +45,7 @@ public interface LauncherMessages { @Message(id = 7, value = "The argument %s is not allowed for %s.") IllegalArgumentException invalidArgument(String argument, String methodName); + + @Message(id = 8, value = "The security manager is not supported for %s") + IllegalArgumentException securityManagerNotSupported(Path javaHome); } diff --git a/src/test/java/org/wildfly/core/launcher/JvmTest.java b/src/test/java/org/wildfly/core/launcher/JvmTest.java index e23cc83..be0f1d6 100644 --- a/src/test/java/org/wildfly/core/launcher/JvmTest.java +++ b/src/test/java/org/wildfly/core/launcher/JvmTest.java @@ -6,6 +6,7 @@ package org.wildfly.core.launcher; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.params.provider.Arguments.arguments; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -15,33 +16,24 @@ import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.Collections; +import java.util.stream.Stream; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; /** * @author James R. Perkins */ class JvmTest { - @Test - void releaseFile() throws Exception { - testReleaseFile("", false); - testReleaseFile("1.8.0", false); - testReleaseFile("1.8.0_191", false); - testReleaseFile("9", true); - testReleaseFile("9.0", true); - testReleaseFile("9.0.1", true); - testReleaseFile("10", true); - testReleaseFile("10.0", true); - testReleaseFile("10.0.2", true); - testReleaseFile("11", true); - testReleaseFile("11.0.1", true); - } - - private static void testReleaseFile(final String version, final boolean expectedValue) throws IOException { + @ParameterizedTest + @MethodSource("testReleases") + void releaseFile(final String version, final boolean expectedValue) throws Exception { final Path javaHome = createFakeJavaHome(version); try { - assertEquals(expectedValue, Jvm.of(javaHome).isModular(), String.format("Expected version %s to %s a modular JVM", version, (expectedValue ? "be" : "not be"))); + assertEquals(expectedValue, Jvm.of(javaHome).isSecurityManagerSupported(), () -> + String.format("Expected version %s to %s support the security manager", version, (expectedValue ? "" : "not"))); } finally { Files.walkFileTree(javaHome, new SimpleFileVisitor() { @Override @@ -59,9 +51,28 @@ public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) } } + static Stream testReleases() { + return Stream.of( + arguments("", false), + arguments("9", true), + arguments("9.0", true), + arguments("9.0.1", true), + arguments("10", true), + arguments("10.0", true), + arguments("10.0.2", true), + arguments("11", true), + arguments("11.0.1", true), + arguments("21.0.5", true), + arguments("23.0.3", true), + arguments("24", false), + arguments("25.0.1", false) + ); + } + private static Path createFakeJavaHome(final String version) throws IOException { final Path javaHome = Files.createTempDirectory("fake-java-home"); - Files.createFile(Files.createDirectory(javaHome.resolve("bin")).resolve(Environment.isWindows() ? "java.exe" : "java")); + Files.createFile(Files.createDirectory(javaHome.resolve("bin")) + .resolve(Environment.isWindows() ? "java.exe" : "java")); final Path releaseFile = javaHome.resolve("release"); Files.write(releaseFile, Collections.singleton(String.format("JAVA_VERSION=\"%s\"%n", version)), StandardCharsets.UTF_8); return javaHome;