You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ti...@apache.org on 2022/01/21 08:46:06 UTC
[maven-surefire] branch master updated: [SUREFIRE-1975] JDK18 - The Security Manager is deprecated and will be removed in a future release
This is an automated email from the ASF dual-hosted git repository.
tibordigana pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git
The following commit(s) were added to refs/heads/master by this push:
new aeb6a32 [SUREFIRE-1975] JDK18 - The Security Manager is deprecated and will be removed in a future release
aeb6a32 is described below
commit aeb6a32522e79461337b825cfe36a84661fcf440
Author: Tibor Digaňa <ti...@apache.org>
AuthorDate: Wed Jan 19 21:45:03 2022 +0100
[SUREFIRE-1975] JDK18 - The Security Manager is deprecated and will be removed in a future release
---
.github/workflows/maven-verify.yml | 3 +-
.../plugin/surefire/AbstractSurefireMojo.java | 5 +-
.../src/site/apt/examples/junit.apt.vm | 3 ++
.../surefire/api/util/internal/ObjectUtils.java | 11 ++++
.../java/org/apache/maven/JUnit4SuiteTest.java | 4 +-
.../api/util/internal/ObjectUtilsTest.java} | 30 ++++-------
.../maven/surefire/booter/ProviderFactory.java | 3 +-
.../apache/maven/surefire/booter/SystemUtils.java | 50 +++----------------
.../maven/surefire/booter/SystemUtilsTest.java | 12 -----
.../its/jiras/Surefire34SecurityManagerIT.java | 9 ++++
.../maven/surefire/junit/JUnit3Provider.java | 26 +++++++---
.../maven/surefire/junit/JUnitTestSetTest.java | 58 ++++++++++++++++++++++
12 files changed, 125 insertions(+), 89 deletions(-)
diff --git a/.github/workflows/maven-verify.yml b/.github/workflows/maven-verify.yml
index 3e89f82..3b0adba 100644
--- a/.github/workflows/maven-verify.yml
+++ b/.github/workflows/maven-verify.yml
@@ -26,6 +26,7 @@ jobs:
name: Verify
uses: apache/maven-gh-actions-shared/.github/workflows/maven-verify.yml@v2
with:
+ jdk-matrix: '[ "8", "11", "17", "18-ea" ]'
ff-goal: 'clean install -nsu -P run-its'
ff-site-goal: 'clean install site -nsu -DskipTests -P reporting'
verify-goal: 'clean install -nsu -P run-its'
@@ -35,5 +36,5 @@ jobs:
surefire-its/target/*/log.txt
surefire-its/target/**/surefire-reports/*
surefire-its/target/**/failsafe-reports/*
- max-parallel: 4
+ max-parallel: 5
timeout-minutes: 420
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
index 33f83d0..24bf9af 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
@@ -141,12 +141,12 @@ import static org.apache.maven.surefire.api.suite.RunResult.noTestsRun;
import static org.apache.maven.surefire.api.util.ReflectionUtils.invokeMethodWithArray;
import static org.apache.maven.surefire.api.util.ReflectionUtils.tryGetMethod;
import static org.apache.maven.surefire.booter.Classpath.emptyClasspath;
-import static org.apache.maven.surefire.booter.SystemUtils.JAVA_SPECIFICATION_VERSION;
import static org.apache.maven.surefire.booter.SystemUtils.endsWithJavaPath;
import static org.apache.maven.surefire.booter.SystemUtils.isBuiltInJava9AtLeast;
import static org.apache.maven.surefire.booter.SystemUtils.isJava9AtLeast;
import static org.apache.maven.surefire.booter.SystemUtils.toJdkHomeFromJvmExec;
import static org.apache.maven.surefire.booter.SystemUtils.toJdkVersionFromReleaseFile;
+import static org.apache.maven.surefire.shared.lang3.JavaVersion.JAVA_RECENT;
import static org.apache.maven.surefire.shared.lang3.StringUtils.substringBeforeLast;
import static org.apache.maven.surefire.shared.lang3.SystemUtils.IS_OS_WINDOWS;
import static org.apache.maven.surefire.shared.utils.StringUtils.capitalizeFirstLetter;
@@ -2673,8 +2673,7 @@ public abstract class AbstractSurefireMojo
// use the same JVM as the one used to run Maven (the "java.home" one)
String jvmToUse = System.getProperty( "java.home" ) + File.separator + "bin" + File.separator + "java";
- getConsoleLogger().debug( "Using JVM: " + jvmToUse + " with Java version "
- + JAVA_SPECIFICATION_VERSION.toPlainString() );
+ getConsoleLogger().debug( "Using JVM: " + jvmToUse + " with Java version " + JAVA_RECENT );
return new JdkAttributes( jvmToUse, isBuiltInJava9AtLeast() );
}
diff --git a/maven-surefire-plugin/src/site/apt/examples/junit.apt.vm b/maven-surefire-plugin/src/site/apt/examples/junit.apt.vm
index 52b2d94..4352e1c 100644
--- a/maven-surefire-plugin/src/site/apt/examples/junit.apt.vm
+++ b/maven-surefire-plugin/src/site/apt/examples/junit.apt.vm
@@ -204,6 +204,9 @@ else
As long as <<<forkCount>>> is not 0 and you use JUnit3, you can run your tests with a Java security manager enabled.
The class name of the security manager must be sent as a system property variable to the JUnit3 provider.
+ The JDK 17 deprecated the class <<<java.lang.SecurityManager>>> and the security manager is not fully supported
+ since JDK 18. The JUnit3 provider fails with enabled system property <<surefire.security.manager>>> in JDK 18+.
+
JUnit4 uses mechanisms internally that are not compatible with the tested
security managers and thus this means of configuring a security manager with JUnit4 is not supported
by Surefire.
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/api/util/internal/ObjectUtils.java b/surefire-api/src/main/java/org/apache/maven/surefire/api/util/internal/ObjectUtils.java
index b316be2..9ee7571 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/api/util/internal/ObjectUtils.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/api/util/internal/ObjectUtils.java
@@ -22,6 +22,9 @@ package org.apache.maven.surefire.api.util.internal;
import java.lang.management.ManagementFactory;
import java.util.Map;
+import static org.apache.maven.surefire.shared.lang3.JavaVersion.JAVA_17;
+import static org.apache.maven.surefire.shared.lang3.JavaVersion.JAVA_RECENT;
+
/**
* Similar to Java 7 java.util.Objects.
*
@@ -44,4 +47,12 @@ public final class ObjectUtils
{
return ManagementFactory.getRuntimeMXBean().getSystemProperties();
}
+
+ /**
+ * @return true if SecurityManager is supported (even if deprecated) in JDK (up to 17)
+ */
+ public static boolean isSecurityManagerSupported()
+ {
+ return JAVA_RECENT.atMost( JAVA_17 );
+ }
}
diff --git a/surefire-api/src/test/java/org/apache/maven/JUnit4SuiteTest.java b/surefire-api/src/test/java/org/apache/maven/JUnit4SuiteTest.java
index c707ed6..016cce4 100644
--- a/surefire-api/src/test/java/org/apache/maven/JUnit4SuiteTest.java
+++ b/surefire-api/src/test/java/org/apache/maven/JUnit4SuiteTest.java
@@ -42,6 +42,7 @@ import org.apache.maven.surefire.api.util.internal.ChannelsReaderTest;
import org.apache.maven.surefire.api.util.internal.ChannelsWriterTest;
import org.apache.maven.surefire.api.util.internal.ConcurrencyUtilsTest;
import org.apache.maven.surefire.api.util.internal.ImmutableMapTest;
+import org.apache.maven.surefire.api.util.internal.ObjectUtilsTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@@ -72,7 +73,8 @@ import org.junit.runners.Suite;
ChannelsWriterTest.class,
AsyncSocketTest.class,
AbstractStreamEncoderTest.class,
- AbstractStreamDecoderTest.class
+ AbstractStreamDecoderTest.class,
+ ObjectUtilsTest.class
} )
@RunWith( Suite.class )
public class JUnit4SuiteTest
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/api/util/internal/ObjectUtils.java b/surefire-api/src/test/java/org/apache/maven/surefire/api/util/internal/ObjectUtilsTest.java
similarity index 59%
copy from surefire-api/src/main/java/org/apache/maven/surefire/api/util/internal/ObjectUtils.java
copy to surefire-api/src/test/java/org/apache/maven/surefire/api/util/internal/ObjectUtilsTest.java
index b316be2..7d3c0a9 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/api/util/internal/ObjectUtils.java
+++ b/surefire-api/src/test/java/org/apache/maven/surefire/api/util/internal/ObjectUtilsTest.java
@@ -19,29 +19,21 @@ package org.apache.maven.surefire.api.util.internal;
* under the License.
*/
-import java.lang.management.ManagementFactory;
-import java.util.Map;
+import org.junit.Test;
+
+import static org.apache.maven.surefire.shared.lang3.JavaVersion.JAVA_17;
+import static org.apache.maven.surefire.shared.lang3.JavaVersion.JAVA_RECENT;
+import static org.fest.assertions.Assertions.assertThat;
/**
- * Similar to Java 7 java.util.Objects.
- *
- * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
- * @since 2.20
+ * @since 3.0.0-M6
*/
-public final class ObjectUtils
+public class ObjectUtilsTest
{
- private ObjectUtils()
- {
- throw new IllegalStateException( "no instantiable constructor" );
- }
-
- public static <T> T useNonNull( T target, T fallback )
- {
- return target == null ? fallback : target;
- }
-
- public static Map<String, String> systemProps()
+ @Test
+ public void shouldSupportSecurityManager()
{
- return ManagementFactory.getRuntimeMXBean().getSystemProperties();
+ assertThat( ObjectUtils.isSecurityManagerSupported() )
+ .isEqualTo( JAVA_RECENT.atMost( JAVA_17 ) );
}
}
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java
index 86b430e..43461df 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java
@@ -32,6 +32,7 @@ import static org.apache.maven.surefire.api.util.ReflectionUtils.getMethod;
import static org.apache.maven.surefire.api.util.ReflectionUtils.invokeGetter;
import static org.apache.maven.surefire.api.util.ReflectionUtils.invokeMethodWithArray;
import static org.apache.maven.surefire.api.util.ReflectionUtils.invokeMethodWithArray2;
+import static org.apache.maven.surefire.api.util.internal.ObjectUtils.isSecurityManagerSupported;
/**
* Creates the surefire provider.
@@ -85,7 +86,7 @@ public class ProviderFactory
}
finally
{
- if ( restoreStreams && System.getSecurityManager() == null )
+ if ( restoreStreams && ( !isSecurityManagerSupported() || System.getSecurityManager() == null ) )
{
System.setOut( orgSystemOut );
System.setErr( orgSystemErr );
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/SystemUtils.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/SystemUtils.java
index 50467e2..674cb22 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/SystemUtils.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/SystemUtils.java
@@ -33,17 +33,18 @@ import java.math.BigDecimal;
import java.util.Properties;
import java.util.StringTokenizer;
-import static java.lang.Character.isDigit;
import static java.lang.Thread.currentThread;
import static java.util.Objects.requireNonNull;
import static org.apache.maven.surefire.api.util.ReflectionUtils.invokeMethodWithArray;
+import static org.apache.maven.surefire.shared.lang3.JavaVersion.JAVA_RECENT;
+import static org.apache.maven.surefire.shared.lang3.JavaVersion.JAVA_9;
import static org.apache.maven.surefire.shared.lang3.StringUtils.isNumeric;
-import static org.apache.maven.surefire.shared.lang3.SystemUtils.IS_OS_FREE_BSD;
+import static org.apache.maven.surefire.api.util.ReflectionUtils.invokeMethodChain;
+import static org.apache.maven.surefire.api.util.ReflectionUtils.tryLoadClass;
import static org.apache.maven.surefire.shared.lang3.SystemUtils.IS_OS_LINUX;
+import static org.apache.maven.surefire.shared.lang3.SystemUtils.IS_OS_FREE_BSD;
import static org.apache.maven.surefire.shared.lang3.SystemUtils.IS_OS_NET_BSD;
import static org.apache.maven.surefire.shared.lang3.SystemUtils.IS_OS_OPEN_BSD;
-import static org.apache.maven.surefire.api.util.ReflectionUtils.invokeMethodChain;
-import static org.apache.maven.surefire.api.util.ReflectionUtils.tryLoadClass;
/**
* JDK 9 support.
@@ -53,8 +54,6 @@ import static org.apache.maven.surefire.api.util.ReflectionUtils.tryLoadClass;
*/
public final class SystemUtils
{
- public static final BigDecimal JAVA_SPECIFICATION_VERSION = getJavaSpecificationVersion();
-
private static final BigDecimal JIGSAW_JAVA_VERSION = new BigDecimal( 9 ).stripTrailingZeros();
private static final int PROC_STATUS_PID_FIRST_CHARS = 20;
@@ -165,43 +164,6 @@ public final class SystemUtils
}
}
- /**
- * Safely extracts major and minor version as fractional number from
- * <pre>
- * $MAJOR.$MINOR.$SECURITY
- * </pre>.
- * <br>
- * The security version is usually not needed to know.
- * It can be applied to not certified JRE.
- *
- * @return major.minor version derived from java specification version of <em>this</em> JVM, e.g. 1.8, 9, etc.
- */
- private static BigDecimal getJavaSpecificationVersion()
- {
- StringBuilder fractionalVersion = new StringBuilder( "0" );
- for ( char c : org.apache.maven.surefire.shared.lang3.SystemUtils.JAVA_SPECIFICATION_VERSION.toCharArray() )
- {
- if ( isDigit( c ) )
- {
- fractionalVersion.append( c );
- }
- else if ( c == '.' )
- {
- if ( fractionalVersion.indexOf( "." ) == -1 )
- {
- fractionalVersion.append( '.' );
- }
- else
- {
- break;
- }
- }
- }
- String majorMinorVersion = fractionalVersion.toString();
- return new BigDecimal( majorMinorVersion.endsWith( "." ) ? majorMinorVersion + "0" : majorMinorVersion )
- .stripTrailingZeros();
- }
-
public static boolean isJava9AtLeast( String jvmExecutablePath )
{
File externalJavaHome = toJdkHomeFromJvmExec( jvmExecutablePath );
@@ -220,7 +182,7 @@ public final class SystemUtils
public static boolean isBuiltInJava9AtLeast()
{
- return JAVA_SPECIFICATION_VERSION.compareTo( JIGSAW_JAVA_VERSION ) >= 0;
+ return JAVA_RECENT.atLeast( JAVA_9 );
}
public static boolean isJava9AtLeast( BigDecimal version )
diff --git a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SystemUtilsTest.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SystemUtilsTest.java
index c504e04..5919dd2 100644
--- a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SystemUtilsTest.java
+++ b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SystemUtilsTest.java
@@ -46,7 +46,6 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.verifyStatic;
-import static org.powermock.reflect.Whitebox.invokeMethod;
/**
* Test of {@link SystemUtils}.
@@ -63,17 +62,6 @@ public class SystemUtilsTest
*/
public static class PlainUnitTests
{
-
- @Test
- public void shouldMatchJavaSpecVersion() throws Exception
- {
- BigDecimal actual = invokeMethod( SystemUtils.class, "getJavaSpecificationVersion" );
- BigDecimal expected =
- new BigDecimal( System.getProperty( "java.specification.version" ) ).stripTrailingZeros();
- assertThat( actual ).isEqualTo( expected );
- assertThat( SystemUtils.JAVA_SPECIFICATION_VERSION ).isEqualTo( expected );
- }
-
@Test
public void shouldParseProprietaryReleaseFile() throws IOException
{
diff --git a/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire34SecurityManagerIT.java b/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire34SecurityManagerIT.java
index bb80aec..1138546 100644
--- a/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire34SecurityManagerIT.java
+++ b/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire34SecurityManagerIT.java
@@ -21,8 +21,11 @@ package org.apache.maven.surefire.its.jiras;
import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase;
import org.apache.maven.surefire.its.fixture.SurefireLauncher;
+import org.junit.BeforeClass;
import org.junit.Test;
+import static org.apache.maven.surefire.its.fixture.HelperAssertions.assumeJavaMaxVersion;
+
/**
* SUREFIRE-621 Asserts proper test counts when running junit 3 tests in parallel
*
@@ -31,6 +34,12 @@ import org.junit.Test;
public class Surefire34SecurityManagerIT
extends SurefireJUnit4IntegrationTestCase
{
+ @BeforeClass
+ public static void checkJavaVersion()
+ {
+ assumeJavaMaxVersion( 17 );
+ }
+
@Test
public void testSecurityManager()
{
diff --git a/surefire-providers/surefire-junit3/src/main/java/org/apache/maven/surefire/junit/JUnit3Provider.java b/surefire-providers/surefire-junit3/src/main/java/org/apache/maven/surefire/junit/JUnit3Provider.java
index f7c2c0c..ff210ec 100644
--- a/surefire-providers/surefire-junit3/src/main/java/org/apache/maven/surefire/junit/JUnit3Provider.java
+++ b/surefire-providers/surefire-junit3/src/main/java/org/apache/maven/surefire/junit/JUnit3Provider.java
@@ -31,13 +31,14 @@ import org.apache.maven.surefire.api.report.SimpleReportEntry;
import org.apache.maven.surefire.api.report.TestSetReportEntry;
import org.apache.maven.surefire.api.suite.RunResult;
import org.apache.maven.surefire.api.testset.TestSetFailedException;
-import org.apache.maven.surefire.api.util.ReflectionUtils;
import org.apache.maven.surefire.api.util.RunOrderCalculator;
import org.apache.maven.surefire.api.util.ScanResult;
import org.apache.maven.surefire.api.util.TestsToRun;
import java.util.Map;
+import static org.apache.maven.surefire.api.util.ReflectionUtils.instantiate;
+import static org.apache.maven.surefire.api.util.internal.ObjectUtils.isSecurityManagerSupported;
import static org.apache.maven.surefire.api.util.internal.ObjectUtils.systemProps;
/**
@@ -100,13 +101,7 @@ public class JUnit3Provider
final RunListener reporter = reporterFactory.createReporter();
ConsoleOutputCapture.startCapture( (ConsoleOutputReceiver) reporter );
Map<String, String> systemProperties = systemProps();
- String smClassName = System.getProperty( "surefire.security.manager" );
- if ( smClassName != null )
- {
- SecurityManager securityManager =
- ReflectionUtils.instantiate( getClass().getClassLoader(), smClassName, SecurityManager.class );
- System.setSecurityManager( securityManager );
- }
+ setSystemManager( System.getProperty( "surefire.security.manager" ) );
for ( Class<?> clazz : testsToRun )
{
@@ -121,6 +116,21 @@ public class JUnit3Provider
return runResult;
}
+ static void setSystemManager( String smClassName ) throws TestSetFailedException
+ {
+ if ( smClassName != null )
+ {
+ if ( !isSecurityManagerSupported() )
+ {
+ throw new TestSetFailedException( "JDK does not support overriding Security Manager with "
+ + "a value in system property 'surefire.security.manager'." );
+ }
+ ClassLoader classLoader = JUnit3Provider.class.getClassLoader();
+ SecurityManager sm = instantiate( classLoader, smClassName, SecurityManager.class );
+ System.setSecurityManager( sm );
+ }
+ }
+
private SurefireTestSet createTestSet( Class<?> clazz )
{
return reflector.isJUnit3Available() && jUnit3TestChecker.accept( clazz )
diff --git a/surefire-providers/surefire-junit3/src/test/java/org/apache/maven/surefire/junit/JUnitTestSetTest.java b/surefire-providers/surefire-junit3/src/test/java/org/apache/maven/surefire/junit/JUnitTestSetTest.java
index 594dcc5..67d1ece 100644
--- a/surefire-providers/surefire-junit3/src/test/java/org/apache/maven/surefire/junit/JUnitTestSetTest.java
+++ b/surefire-providers/surefire-junit3/src/test/java/org/apache/maven/surefire/junit/JUnitTestSetTest.java
@@ -22,15 +22,22 @@ package org.apache.maven.surefire.junit;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
+import org.apache.maven.surefire.api.testset.TestSetFailedException;
import org.apache.maven.surefire.common.junit3.JUnit3Reflector;
import org.apache.maven.surefire.api.report.ReportEntry;
import org.apache.maven.surefire.api.report.RunListener;
import org.apache.maven.surefire.api.report.RunMode;
import org.apache.maven.surefire.api.report.TestSetReportEntry;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.List;
+import static org.apache.maven.surefire.shared.lang3.JavaVersion.JAVA_17;
+import static org.apache.maven.surefire.shared.lang3.JavaVersion.JAVA_RECENT;
+
/**
*
*/
@@ -54,6 +61,57 @@ public class JUnitTestSetTest
succeededTests.get( 0 ).getName() );
}
+ public void testSystemManager()
+ {
+ boolean isDeprecated = !JAVA_RECENT.atMost( JAVA_17 );
+ Object originalSm = null;
+ try
+ {
+ if ( !isDeprecated )
+ {
+ originalSm = System.getSecurityManager();
+ }
+
+ JUnit3Provider.setSystemManager( "java.lang.SecurityManager" );
+
+ if ( isDeprecated )
+ {
+ fail();
+ }
+
+ Object sm = System.getSecurityManager();
+ assertNotNull( sm );
+ assertEquals( "java.lang.SecurityManager", sm.getClass().getName() );
+ assertNotSame( originalSm, sm );
+ }
+ catch ( TestSetFailedException e )
+ {
+ if ( !isDeprecated )
+ {
+ fail();
+ }
+ }
+ finally
+ {
+ if ( !isDeprecated )
+ {
+ try
+ {
+ SecurityManager sm = (SecurityManager) originalSm;
+ AccessController.doPrivileged( (PrivilegedAction<Object>) () ->
+ {
+ System.setSecurityManager( sm );
+ return null;
+ } );
+ }
+ catch ( AccessControlException e )
+ {
+ // ignore
+ }
+ }
+ }
+ }
+
/**
*
*/