8269543: The warning for System::setSecurityManager should only appear once for each caller
Reviewed-by: lancea, alanb, dfuchs
This commit is contained in:
parent
2db9005c07
commit
c4ea13edd0
src/java.base/share/classes/java/lang
test/jdk/java/lang/System
@ -54,6 +54,7 @@ import java.security.AccessController;
|
||||
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;
|
||||
@ -61,6 +62,7 @@ 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 @@ public final class System {
|
||||
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 @@ public final class System {
|
||||
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 + ")";
|
||||
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());
|
||||
}
|
||||
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 class SecurityManagerWarnings {
|
||||
|
||||
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 class SecurityManagerWarnings {
|
||||
// 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 @@ public class SecurityManagerWarnings {
|
||||
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 @@ public class SecurityManagerWarnings {
|
||||
"-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());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user