Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better support disabling the security manager. Updated the JvmTest to… #9

Merged
merged 1 commit into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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:[email protected]">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