diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 379281d4..f6ba5dfe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,10 +16,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - name: Set up JDK 11 and maven cache + - name: Set up JDK 25 and maven cache uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0 with: - java-version: '11' + java-version: '25' distribution: 'temurin' cache: maven - name: Add virtual env entry to hosts file diff --git a/at_client/src/test/java/org/atsign/client/impl/cli/CliIT.java b/at_client/src/test/java/org/atsign/client/impl/cli/CliIT.java index b82cc981..99b99b89 100644 --- a/at_client/src/test/java/org/atsign/client/impl/cli/CliIT.java +++ b/at_client/src/test/java/org/atsign/client/impl/cli/CliIT.java @@ -6,6 +6,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import java.security.SecureRandom; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicReference; import java.util.regex.Matcher; @@ -47,17 +48,13 @@ public static void classTeardown() { @Test public void testShareUsage() throws Exception { - int shareCode = runMainExpectSystemExit(() -> Share.main(new String[] {VIRTUAL_ENV_ROOT})); - assertThat(shareCode, not(equalTo(0))); - - int scanCode = runMainExpectSystemExit(() -> Scan.main(new String[] {VIRTUAL_ENV_ROOT})); - assertThat(scanCode, not(equalTo(0))); - - int getCode = runMainExpectSystemExit(() -> Get.main(new String[] {VIRTUAL_ENV_ROOT})); - assertThat(getCode, not(equalTo(0))); - - int deleteCode = runMainExpectSystemExit(() -> Delete.main(new String[] {VIRTUAL_ENV_ROOT})); - assertThat(deleteCode, not(equalTo(0))); + // Each CLI prints usage and exits non-zero when given too few args. Run each main in a + // forked JVM and read its real exit code: System.exit can no longer be trapped in-process + // now that the Security Manager is gone (JDK 24, JEP 486). + assertThat(runMainInSubprocess(Share.class, VIRTUAL_ENV_ROOT), not(equalTo(0))); + assertThat(runMainInSubprocess(Scan.class, VIRTUAL_ENV_ROOT), not(equalTo(0))); + assertThat(runMainInSubprocess(Get.class, VIRTUAL_ENV_ROOT), not(equalTo(0))); + assertThat(runMainInSubprocess(Delete.class, VIRTUAL_ENV_ROOT), not(equalTo(0))); } @Test @@ -113,12 +110,19 @@ public void testShareScanGetDelete() throws Exception { assertThrows(AssertionError.class, () -> findLines(secondScanStdout, "\\s+0:\\s+.*" + keyname + ".*")); } - public static int runMainExpectSystemExit(Statement statement, String... stdin) throws Exception { - AtomicReference stdout = new AtomicReference<>(); - return SystemLambda.catchSystemExit(() -> stdout.set(SystemLambda.tapSystemErr(() -> { - SystemLambda.SystemInStub stub = SystemLambda.withTextFromSystemIn(String.join("\n", List.of(stdin))); - stub.execute(statement); - }))); + /** + * Runs a CLI {@code main} in a forked JVM and returns its exit code. The code under test calls + * {@link System#exit}, which can no longer be intercepted in-process now that the Security + * Manager has been removed (JDK 24, JEP 486) and {@code System.setSecurityManager} throws. The + * child inherits this JVM's classpath and stdio. + */ + public static int runMainInSubprocess(Class mainClass, String... args) throws Exception { + List command = new ArrayList<>(List.of( + System.getProperty("java.home") + "/bin/java", + "-cp", System.getProperty("java.class.path"), + mainClass.getName())); + command.addAll(List.of(args)); + return new ProcessBuilder(command).inheritIO().start().waitFor(); } public static List runMain(Statement statement, String... stdin) throws Exception { diff --git a/pom.xml b/pom.xml index 7df91769..6da4118b 100644 --- a/pom.xml +++ b/pom.xml @@ -55,12 +55,12 @@ 4.7.6 2.0.13 2.25.3 - 1.18.30 + 1.18.46 2.4.0 5.10.2 1.10.2 - 5.5.0 + 5.20.0 2.2 7.14.0 2.0.3 @@ -149,11 +149,6 @@ ${version.junit-platform-suite} - - org.mockito - mockito-inline - ${version.mockito} - org.mockito mockito-junit-jupiter @@ -201,6 +196,27 @@ + + org.apache.maven.plugins + maven-compiler-plugin + 3.14.0 + + + + + org.projectlombok + lombok + ${version.lombok} + + + + + org.apache.maven.plugins maven-jar-plugin @@ -299,7 +315,7 @@ com.diffplug.spotless spotless-maven-plugin - 2.30.0 + 2.44.0 @@ -358,7 +374,7 @@ org.jacoco jacoco-maven-plugin - 0.8.11 + 0.8.15 prepare-agent