Skip to content

Commit

Permalink
Merge pull request #9 from jamezp/updates
Browse files Browse the repository at this point in the history
Better support disabling the security manager. Updated the JvmTest to…
  • Loading branch information
jamezp authored Nov 20, 2024
2 parents 1c6f3a5 + 0f7c9c1 commit 7ae9f77
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 84 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/wildfly-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@
</channels>
<galleon-options>
<jboss-maven-dist/>
<jboss-fork-embedded>true</jboss-fork-embedded>
</galleon-options>
</configuration>
<executions>
Expand Down
10 changes: 4 additions & 6 deletions src/main/java/org/wildfly/core/launcher/CliCommandBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -654,12 +654,10 @@ public Path getJavaHome() {
public List<String> buildArguments() {
final List<String> 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);
}
}
}
Expand Down
20 changes: 8 additions & 12 deletions src/main/java/org/wildfly/core/launcher/DomainCommandBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -709,12 +709,10 @@ public List<String> 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()) {
Expand Down Expand Up @@ -745,12 +743,10 @@ public List<String> 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()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}

/**
Expand Down Expand Up @@ -616,12 +619,10 @@ public List<String> 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()) {
Expand Down
64 changes: 32 additions & 32 deletions src/main/java/org/wildfly/core/launcher/Jvm.java
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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;
}

Expand Down Expand Up @@ -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));
}

/**
Expand All @@ -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;
}

/**
Expand All @@ -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)) {
Expand All @@ -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) {
}
Expand Down Expand Up @@ -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<String> 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.
*
Expand Down Expand Up @@ -251,7 +251,7 @@ private static boolean checkProcessStatus(final List<String> 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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -572,12 +572,10 @@ public List<String> 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()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
49 changes: 30 additions & 19 deletions src/test/java/org/wildfly/core/launcher/JvmTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 <a href="mailto:jperkins@redhat.com">James R. Perkins</a>
*/
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<Path>() {
@Override
Expand All @@ -59,9 +51,28 @@ public FileVisitResult postVisitDirectory(final Path dir, final IOException exc)
}
}

static Stream<Arguments> 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;
Expand Down

0 comments on commit 7ae9f77

Please sign in to comment.