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
+                }
+            }
+        }
+    }
+
     /**
      *
      */