Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8269543: The warning for System::setSecurityManager should only appea…
…r once for each caller

Reviewed-by: lancea, alanb, dfuchs
  • Loading branch information
wangweij committed Jul 2, 2021
1 parent 2db9005 commit c4ea13edd036bd6aeb213bb5391dd374d283d382
Showing with 54 additions and 20 deletions.
  1. +24 −13 src/java.base/share/classes/java/lang/System.java
  2. +30 −7 test/jdk/java/lang/System/SecurityManagerWarnings.java
@@ -54,13 +54,15 @@
import java.security.CodeSource;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.PropertyPermission;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.function.Supplier;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
@@ -326,6 +328,13 @@ private static void checkIO() {
private static native void setOut0(PrintStream out);
private static native void setErr0(PrintStream err);

private static class CallersHolder {
// Remember callers of setSecurityManager() here so that warning
// is only printed once for each different caller
final static Map<Class<?>, Boolean> callers
= Collections.synchronizedMap(new WeakHashMap<>());
}

// Remember initial System.err. setSecurityManager() warning goes here
private static volatile @Stable PrintStream initialErrStream;

@@ -378,19 +387,21 @@ private static URL codeSource(Class<?> clazz) {
public static void setSecurityManager(@SuppressWarnings("removal") SecurityManager sm) {
if (allowSecurityManager()) {
var callerClass = Reflection.getCallerClass();
URL url = codeSource(callerClass);
final String source;
if (url == null) {
source = callerClass.getName();
} else {
source = callerClass.getName() + " (" + url + ")";
}
initialErrStream.printf("""
WARNING: A terminally deprecated method in java.lang.System has been called
WARNING: System::setSecurityManager has been called by %s
WARNING: Please consider reporting this to the maintainers of %s
WARNING: System::setSecurityManager will be removed in a future release
""", source, callerClass.getName());
if (CallersHolder.callers.putIfAbsent(callerClass, true) == null) {
URL url = codeSource(callerClass);
final String source;
if (url == null) {
source = callerClass.getName();
} else {
source = callerClass.getName() + " (" + url + ")";
}
initialErrStream.printf("""
WARNING: A terminally deprecated method in java.lang.System has been called
WARNING: System::setSecurityManager has been called by %s
WARNING: Please consider reporting this to the maintainers of %s
WARNING: System::setSecurityManager will be removed in a future release
""", source, callerClass.getName());
}
implSetSecurityManager(sm);
} else {
// security manager not allowed
@@ -23,7 +23,7 @@

/*
* @test
* @bug 8266459 8268349
* @bug 8266459 8268349 8269543
* @summary check various warnings
* @library /test/lib
*/
@@ -62,7 +62,9 @@ public static void main(String args[]) throws Exception {

JarUtils.createJarFile(Path.of("a.jar"),
Path.of(testClasses),
Path.of("SecurityManagerWarnings.class"));
Path.of("SecurityManagerWarnings.class"),
Path.of("A.class"),
Path.of("B.class"));

allowTest(null, "a.jar");
} else {
@@ -72,7 +74,12 @@ public static void main(String args[]) throws Exception {
// to the original System.err and will not be swallowed.
System.setErr(new PrintStream(new ByteArrayOutputStream()));
try {
System.setSecurityManager(new SecurityManager());
// Run A.run() twice will show only one warning
// (setSecurityManager(null) to ensure the next set is permitted)
// Run B.run() and a new warning will appear
A.run(); // System.setSecurityManager(null);
A.run(); // System.setSecurityManager(null);
B.run(); // System.setSecurityManager(new SecurityManager());
} catch (Exception e) {
// Exception messages must show in original stderr
e.printStackTrace(oldErr);
@@ -113,9 +120,12 @@ static OutputAnalyzer checkInstallMessage(OutputAnalyzer oa, String cp) {
String uri = new File(cp).toURI().toString();
return oa
.stderrShouldContain("WARNING: A terminally deprecated method in java.lang.System has been called")
.stderrShouldContain("WARNING: System::setSecurityManager has been called by SecurityManagerWarnings (" + uri + ")")
.stderrShouldContain("WARNING: Please consider reporting this to the maintainers of SecurityManagerWarnings")
.stderrShouldContain("WARNING: System::setSecurityManager will be removed in a future release");
.stderrShouldContain("WARNING: System::setSecurityManager has been called by A (" + uri + ")")
.stderrShouldContain("WARNING: System::setSecurityManager has been called by B (" + uri + ")")
.stderrShouldContain("WARNING: Please consider reporting this to the maintainers of A")
.stderrShouldContain("WARNING: Please consider reporting this to the maintainers of B")
.stderrShouldContain("WARNING: System::setSecurityManager will be removed in a future release")
.stderrShouldNotMatch("(?s)by A.*by A"); // "by A" appears only once
}

static OutputAnalyzer run(String prop, String cp) throws Exception {
@@ -133,6 +143,19 @@ static OutputAnalyzer run(String prop, String cp) throws Exception {
"-Djava.security.policy=policy",
"SecurityManagerWarnings", "run");
}
return ProcessTools.executeProcess(pb);
return ProcessTools.executeProcess(pb)
.stderrShouldNotContain("AccessControlException");
}
}

class A {
static void run() {
System.setSecurityManager(null);
}
}

class B {
static void run() {
System.setSecurityManager(new SecurityManager());
}
}

1 comment on commit c4ea13e

@openjdk-notifier

This comment has been minimized.

Copy link

@openjdk-notifier openjdk-notifier bot commented on c4ea13e Jul 2, 2021

Please sign in to comment.