8344235: Revisit SecurityManager usage in java.logging after JEP 486 and JEP 491 integration

Reviewed-by: jpai
This commit is contained in:
Daniel Fuchs 2024-11-21 11:54:28 +00:00
parent 18df6fd5ba
commit a62279ca0a
17 changed files with 202 additions and 903 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,9 +25,6 @@
package jdk.internal.logger;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@ -131,15 +128,8 @@ public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
@Override
public Thread newThread(Runnable r) {
ExecutorService owner = getExecutor();
@SuppressWarnings("removal")
Thread thread = AccessController.doPrivileged(new PrivilegedAction<Thread>() {
@Override
public Thread run() {
Thread t = InnocuousThread.newThread(new BootstrapMessageLoggerTask(owner, r));
t.setName("BootstrapMessageLoggerTask-"+t.getName());
return t;
}
}, null, new RuntimePermission("enableContextClassLoaderOverride"));
Thread thread = InnocuousThread.newThread(new BootstrapMessageLoggerTask(owner, r));
thread.setName("BootstrapMessageLoggerTask-" + thread.getName());
thread.setDaemon(true);
return thread;
}
@ -269,8 +259,6 @@ public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
// the parameters etc... we need to store the context of the
// caller who logged the message - so that we can reuse it when
// we finally log the message.
@SuppressWarnings("removal")
final AccessControlContext acc;
// The next event in the queue
LogEvent next;
@ -279,7 +267,6 @@ public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
private LogEvent(BootstrapLogger bootstrap, Level level,
ResourceBundle bundle, String msg,
Throwable thrown, Object[] params) {
this.acc = AccessController.getContext();
this.timeMillis = System.currentTimeMillis();
this.nanoAdjustment = VM.getNanoTimeAdjustment(timeMillis);
this.level = level;
@ -298,7 +285,6 @@ public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
private LogEvent(BootstrapLogger bootstrap, Level level,
Supplier<String> msgSupplier,
Throwable thrown, Object[] params) {
this.acc = AccessController.getContext();
this.timeMillis = System.currentTimeMillis();
this.nanoAdjustment = VM.getNanoTimeAdjustment(timeMillis);
this.level = level;
@ -319,7 +305,6 @@ public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
String sourceClass, String sourceMethod,
ResourceBundle bundle, String msg,
Throwable thrown, Object[] params) {
this.acc = AccessController.getContext();
this.timeMillis = System.currentTimeMillis();
this.nanoAdjustment = VM.getNanoTimeAdjustment(timeMillis);
this.level = null;
@ -340,7 +325,6 @@ public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
String sourceClass, String sourceMethod,
Supplier<String> msgSupplier,
Throwable thrown, Object[] params) {
this.acc = AccessController.getContext();
this.timeMillis = System.currentTimeMillis();
this.nanoAdjustment = VM.getNanoTimeAdjustment(timeMillis);
this.level = null;
@ -444,20 +428,12 @@ public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
Objects.requireNonNull(level),
Objects.requireNonNull(msgSupplier), null, null);
}
@SuppressWarnings("removal")
static void log(LogEvent log, Logger logger) {
final SecurityManager sm = System.getSecurityManager();
// not sure we can actually use lambda here. We may need to create
// an anonymous class. Although if we reach here, then it means
// the VM is booted.
if (sm == null || log.acc == null) {
BootstrapExecutors.submit(() -> log.log(logger));
} else {
BootstrapExecutors.submit(() ->
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
log.log(logger); return null;
}, log.acc));
}
BootstrapExecutors.submit(() -> log.log(logger));
}
// non default methods from PlatformLogger.Bridge interface
@ -510,20 +486,9 @@ public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
Objects.requireNonNull(level), sourceClass,
sourceMethod, msgSupplier, thrown, null);
}
@SuppressWarnings("removal")
static void log(LogEvent log, PlatformLogger.Bridge logger) {
final SecurityManager sm = System.getSecurityManager();
if (sm == null || log.acc == null) {
BootstrapExecutors.submit(() -> log.log(logger));
} else {
// not sure we can actually use lambda here. We may need to create
// an anonymous class. Although if we reach here, then it means
// the VM is booted.
BootstrapExecutors.submit(() ->
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
log.log(logger); return null;
}, log.acc));
}
BootstrapExecutors.submit(() -> log.log(logger));
}
static void log(LogEvent event) {
@ -897,37 +862,32 @@ public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
// We do not want this field to get initialized if VM.isBooted() is false.
@SuppressWarnings("removal")
private static final class DetectBackend {
static final LoggingBackend detectedBackend;
static {
detectedBackend = AccessController.doPrivileged(new PrivilegedAction<LoggingBackend>() {
@Override
public LoggingBackend run() {
final Iterator<LoggerFinder> iterator =
ServiceLoader.load(LoggerFinder.class, ClassLoader.getSystemClassLoader())
.iterator();
if (iterator.hasNext()) {
return LoggingBackend.CUSTOM; // Custom Logger Provider is registered
}
// No custom logger provider: we will be using the default
// backend.
final Iterator<DefaultLoggerFinder> iterator2 =
ServiceLoader.loadInstalled(DefaultLoggerFinder.class)
.iterator();
if (iterator2.hasNext()) {
// LoggingProviderImpl is registered. The default
// implementation is java.util.logging
String cname = System.getProperty("java.util.logging.config.class");
String fname = System.getProperty("java.util.logging.config.file");
return (cname != null || fname != null)
? LoggingBackend.JUL_WITH_CONFIG
: LoggingBackend.JUL_DEFAULT;
} else {
// SimpleConsoleLogger is used
return LoggingBackend.NONE;
}
}
});
static final LoggingBackend detectedBackend = detectBackend();
static LoggingBackend detectBackend() {
final Iterator<LoggerFinder> iterator =
ServiceLoader.load(LoggerFinder.class, ClassLoader.getSystemClassLoader())
.iterator();
if (iterator.hasNext()) {
return LoggingBackend.CUSTOM; // Custom Logger Provider is registered
}
// No custom logger provider: we will be using the default
// backend.
final Iterator<DefaultLoggerFinder> iterator2 =
ServiceLoader.loadInstalled(DefaultLoggerFinder.class)
.iterator();
if (iterator2.hasNext()) {
// LoggingProviderImpl is registered. The default
// implementation is java.util.logging
String cname = System.getProperty("java.util.logging.config.class");
String fname = System.getProperty("java.util.logging.config.file");
return (cname != null || fname != null)
? LoggingBackend.JUL_WITH_CONFIG
: LoggingBackend.JUL_DEFAULT;
} else {
// SimpleConsoleLogger is used
return LoggingBackend.NONE;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -36,8 +36,6 @@ import java.util.Objects;
import java.lang.System.LoggerFinder;
import java.lang.System.Logger;
import java.lang.ref.ReferenceQueue;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collection;
import java.util.ResourceBundle;
@ -70,7 +68,7 @@ import java.util.ResourceBundle;
* that provides the necessary configuration.
*
* @apiNote Programmers are not expected to call this class directly.
* Instead they should rely on the static methods defined by {@link
* Instead, they should rely on the static methods defined by {@link
* java.lang.System java.lang.System} or {@link sun.util.logging.PlatformLogger
* sun.util.logging.PlatformLogger}.
*
@ -81,30 +79,12 @@ import java.util.ResourceBundle;
*/
public class DefaultLoggerFinder extends LoggerFinder {
static final RuntimePermission LOGGERFINDER_PERMISSION =
new RuntimePermission("loggerFinder");
/**
* Creates a new instance of DefaultLoggerFinder.
* @throws SecurityException if the calling code does not have the
* {@code RuntimePermission("loggerFinder")}
*/
protected DefaultLoggerFinder() {
this(checkPermission());
}
private DefaultLoggerFinder(Void unused) {
// nothing to do.
}
private static Void checkPermission() {
@SuppressWarnings("removal")
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOGGERFINDER_PERMISSION);
}
return null;
}
// SharedLoggers is a default cache of loggers used when JUL is not
// present - in that case we use instances of SimpleConsoleLogger which
@ -139,23 +119,14 @@ public class DefaultLoggerFinder extends LoggerFinder {
static final SharedLoggers application = new SharedLoggers();
}
@SuppressWarnings("removal")
public static boolean isSystem(Module m) {
return AccessController.doPrivileged(new PrivilegedAction<>() {
@Override
public Boolean run() {
// returns true if moduleCL is the platform class loader
// or one of its ancestors.
return VM.isSystemDomainLoader(m.getClassLoader());
}
});
return VM.isSystemDomainLoader(m.getClassLoader());
}
@Override
public final Logger getLogger(String name, Module module) {
Objects.requireNonNull(name, "name");
Objects.requireNonNull(module, "module");
checkPermission();
return demandLoggerFor(name, module);
}
@ -176,11 +147,8 @@ public class DefaultLoggerFinder extends LoggerFinder {
* @param name The name of the logger.
* @param module The module on behalf of which the logger is created.
* @return A {@link Logger logger} suitable for the application usage.
* @throws SecurityException if the calling code does not have the
* {@code RuntimePermission("loggerFinder")}.
*/
protected Logger demandLoggerFor(String name, Module module) {
checkPermission();
if (isSystem(module)) {
return SharedLoggers.system.get(SimpleConsoleLogger::makeSimpleLogger, name);
} else {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,8 +25,6 @@
package jdk.internal.logger;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.function.BiFunction;
import java.lang.System.LoggerFinder;
import java.lang.System.Logger;
@ -44,9 +42,6 @@ import sun.util.logging.PlatformLogger;
*/
public final class LazyLoggers {
static final RuntimePermission LOGGERFINDER_PERMISSION =
new RuntimePermission("loggerFinder");
private LazyLoggers() {
throw new InternalError();
}
@ -341,7 +336,6 @@ public final class LazyLoggers {
// Do not expose this outside of this package.
private static volatile LoggerFinder provider;
@SuppressWarnings("removal")
private static LoggerFinder accessLoggerFinder() {
LoggerFinder prov = provider;
if (prov == null) {
@ -350,10 +344,7 @@ public final class LazyLoggers {
// the result.
// This is just an optimization to avoid the cost of calling
// doPrivileged every time.
final SecurityManager sm = System.getSecurityManager();
prov = sm == null ? LoggerFinder.getLoggerFinder() :
AccessController.doPrivileged(
(PrivilegedAction<LoggerFinder>)LoggerFinder::getLoggerFinder);
prov = LoggerFinder.getLoggerFinder();
if (prov instanceof TemporaryLoggerFinder) return prov;
provider = prov;
}
@ -403,17 +394,9 @@ public final class LazyLoggers {
* @param module module on behalf of which the logger is created
* @return The logger returned by the LoggerFinder.
*/
@SuppressWarnings("removal")
static Logger getLoggerFromFinder(String name, Module module) {
final SecurityManager sm = System.getSecurityManager();
if (sm == null) {
return accessLoggerFinder().getLogger(name, module);
} else {
return AccessController.doPrivileged((PrivilegedAction<Logger>)
() -> {return accessLoggerFinder().getLogger(name, module);},
null, LOGGERFINDER_PERMISSION);
}
}
return accessLoggerFinder().getLogger(name, module);
}
/**
* Returns a (possibly lazy) Logger for the caller.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -24,12 +24,8 @@
*/
package jdk.internal.logger;
import java.io.FilePermission;
import java.lang.System.Logger;
import java.lang.System.LoggerFinder;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
import java.util.Iterator;
import java.util.Locale;
import java.util.ServiceConfigurationError;
@ -37,9 +33,6 @@ import java.util.ServiceLoader;
import java.util.function.BooleanSupplier;
import jdk.internal.vm.annotation.Stable;
import sun.security.util.SecurityConstants;
import sun.security.action.GetBooleanAction;
import sun.security.action.GetPropertyAction;
/**
* Helper class used to load the {@link java.lang.System.LoggerFinder}.
@ -47,13 +40,6 @@ import sun.security.action.GetPropertyAction;
public final class LoggerFinderLoader {
private static volatile System.LoggerFinder service;
private static final Object lock = new int[0];
static final Permission CLASSLOADER_PERMISSION =
SecurityConstants.GET_CLASSLOADER_PERMISSION;
static final Permission READ_PERMISSION =
new FilePermission("<<ALL FILES>>",
SecurityConstants.FILE_READ_ACTION);
public static final RuntimePermission LOGGERFINDER_PERMISSION =
new RuntimePermission("loggerFinder");
// This is used to control how the LoggerFinderLoader handles
// errors when instantiating the LoggerFinder provider.
@ -63,7 +49,7 @@ public final class LoggerFinderLoader {
// DEBUG => Do not fail, use plain default (simple logger) implementation,
// prints warning and exception stack trace on console.
// QUIET => Do not fail and stay silent.
private static enum ErrorPolicy { ERROR, WARNING, DEBUG, QUIET };
private static enum ErrorPolicy { ERROR, WARNING, DEBUG, QUIET }
// This class is static and cannot be instantiated.
private LoggerFinderLoader() {
@ -107,8 +93,7 @@ public final class LoggerFinderLoader {
// Get configuration error policy
private static ErrorPolicy configurationErrorPolicy() {
String errorPolicy =
GetPropertyAction.privilegedGetProperty("jdk.logger.finder.error");
String errorPolicy = System.getProperty("jdk.logger.finder.error");
if (errorPolicy == null || errorPolicy.isEmpty()) {
return ErrorPolicy.WARNING;
}
@ -122,25 +107,12 @@ public final class LoggerFinderLoader {
// Whether multiple provider should be considered as an error.
// This is further submitted to the configuration error policy.
private static boolean ensureSingletonProvider() {
return GetBooleanAction.privilegedGetProperty
("jdk.logger.finder.singleton");
return Boolean.getBoolean("jdk.logger.finder.singleton");
}
@SuppressWarnings("removal")
private static Iterator<System.LoggerFinder> findLoggerFinderProviders() {
final Iterator<System.LoggerFinder> iterator;
if (System.getSecurityManager() == null) {
iterator = ServiceLoader.load(System.LoggerFinder.class,
return ServiceLoader.load(System.LoggerFinder.class,
ClassLoader.getSystemClassLoader()).iterator();
} else {
final PrivilegedAction<Iterator<System.LoggerFinder>> pa =
() -> ServiceLoader.load(System.LoggerFinder.class,
ClassLoader.getSystemClassLoader()).iterator();
iterator = AccessController.doPrivileged(pa, null,
LOGGERFINDER_PERMISSION, CLASSLOADER_PERMISSION,
READ_PERMISSION);
}
return iterator;
}
public static final class TemporaryLoggerFinder extends LoggerFinder {
@ -219,25 +191,10 @@ public final class LoggerFinderLoader {
return result;
}
@SuppressWarnings("removal")
private static System.LoggerFinder loadDefaultImplementation() {
final SecurityManager sm = System.getSecurityManager();
final Iterator<DefaultLoggerFinder> iterator;
if (sm == null) {
iterator = ServiceLoader.loadInstalled(DefaultLoggerFinder.class).iterator();
} else {
// We use limited do privileged here - the minimum set of
// permissions required to 'see' the META-INF/services resources
// seems to be CLASSLOADER_PERMISSION and READ_PERMISSION.
// Note that do privileged is required because
// otherwise the SecurityManager will prevent the ServiceLoader
// from seeing the installed provider.
PrivilegedAction<Iterator<DefaultLoggerFinder>> pa = () ->
ServiceLoader.loadInstalled(DefaultLoggerFinder.class).iterator();
iterator = AccessController.doPrivileged(pa, null,
LOGGERFINDER_PERMISSION, CLASSLOADER_PERMISSION,
READ_PERMISSION);
}
final Iterator<DefaultLoggerFinder> iterator =
ServiceLoader.loadInstalled(DefaultLoggerFinder.class).iterator();
DefaultLoggerFinder result = null;
try {
// Iterator iterates with the access control context stored
@ -256,11 +213,6 @@ public final class LoggerFinderLoader {
}
public static System.LoggerFinder getLoggerFinder() {
@SuppressWarnings("removal")
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOGGERFINDER_PERMISSION);
}
return service();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -29,8 +29,6 @@ import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.StackWalker.StackFrame;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.time.ZonedDateTime;
import java.util.Optional;
import java.util.MissingResourceException;
@ -39,7 +37,6 @@ import java.util.function.Function;
import java.lang.System.Logger;
import java.util.function.Predicate;
import java.util.function.Supplier;
import sun.security.action.GetPropertyAction;
import sun.util.logging.PlatformLogger;
import sun.util.logging.PlatformLogger.ConfigurableBridge.LoggerConfiguration;
@ -56,8 +53,7 @@ public class SimpleConsoleLogger extends LoggerConfiguration
PlatformLogger.toPlatformLevel(DEFAULT_LEVEL);
static Level getDefaultLevel() {
String levelName = GetPropertyAction
.privilegedGetProperty("jdk.system.logger.level", "INFO");
String levelName = System.getProperty("jdk.system.logger.level", "INFO");
try {
return Level.valueOf(levelName);
} catch (IllegalArgumentException iae) {
@ -202,18 +198,9 @@ public class SimpleConsoleLogger extends LoggerConfiguration
/*
* CallerFinder is a stateful predicate.
*/
@SuppressWarnings("removal")
static final class CallerFinder implements Predicate<StackWalker.StackFrame> {
private static final StackWalker WALKER;
static {
final PrivilegedAction<StackWalker> action = new PrivilegedAction<>() {
@Override
public StackWalker run() {
return StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
}
};
WALKER = AccessController.doPrivileged(action);
}
private static final StackWalker WALKER =
StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
/**
* Returns StackFrame of the caller's frame.
@ -439,8 +426,7 @@ public class SimpleConsoleLogger extends LoggerConfiguration
// Make it easier to wrap Logger...
private static final String[] skips;
static {
String additionalPkgs =
GetPropertyAction.privilegedGetProperty("jdk.logger.packages");
String additionalPkgs = System.getProperty("jdk.logger.packages");
skips = additionalPkgs == null ? new String[0] : additionalPkgs.split(",");
}
@ -499,7 +485,7 @@ public class SimpleConsoleLogger extends LoggerConfiguration
// jdk/test/java/lang/invoke/lambda/LogGeneratedClassesTest.java
// to fail - because that test has a testcase which somehow references
// PlatformLogger and counts the number of generated lambda classes.
String format = GetPropertyAction.privilegedGetProperty(key);
String format = System.getProperty(key);
if (format == null && defaultPropertyGetter != null) {
format = defaultPropertyGetter.apply(key);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -78,7 +78,7 @@ public class ConsoleHandler extends StreamHandler {
// configure with specific defaults for ConsoleHandler
super(Level.INFO, new SimpleFormatter(), null);
setOutputStreamPrivileged(System.err);
setOutputStream(System.err);
}
/**

View File

@ -43,8 +43,6 @@ import java.nio.file.LinkOption;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashSet;
import java.util.Set;
@ -267,7 +265,6 @@ public class FileHandler extends StreamHandler {
* @throws NullPointerException if pattern property is an empty String.
*/
public FileHandler() throws IOException {
checkPermission();
configure();
// pattern will have been set by configure. check that it's not
// empty.
@ -293,10 +290,9 @@ public class FileHandler extends StreamHandler {
* @throws IllegalArgumentException if pattern is an empty string
*/
public FileHandler(String pattern) throws IOException {
if (pattern.length() < 1 ) {
if (pattern.isEmpty()) {
throw new IllegalArgumentException();
}
checkPermission();
configure();
this.pattern = pattern;
this.limit = 0;
@ -323,10 +319,9 @@ public class FileHandler extends StreamHandler {
* @throws IllegalArgumentException if pattern is an empty string
*/
public FileHandler(String pattern, boolean append) throws IOException {
if (pattern.length() < 1 ) {
if (pattern.isEmpty()) {
throw new IllegalArgumentException();
}
checkPermission();
configure();
this.pattern = pattern;
this.limit = 0;
@ -357,10 +352,9 @@ public class FileHandler extends StreamHandler {
* @throws IllegalArgumentException if pattern is an empty string
*/
public FileHandler(String pattern, int limit, int count) throws IOException {
if (limit < 0 || count < 1 || pattern.length() < 1) {
if (limit < 0 || count < 1 || pattern.isEmpty()) {
throw new IllegalArgumentException();
}
checkPermission();
configure();
this.pattern = pattern;
this.limit = limit;
@ -425,10 +419,9 @@ public class FileHandler extends StreamHandler {
*/
public FileHandler(String pattern, long limit, int count, boolean append)
throws IOException {
if (limit < 0 || count < 1 || pattern.length() < 1) {
if (limit < 0 || count < 1 || pattern.isEmpty()) {
throw new IllegalArgumentException();
}
checkPermission();
configure();
this.pattern = pattern;
this.limit = limit;
@ -451,7 +444,6 @@ public class FileHandler extends StreamHandler {
*/
private void openFiles() throws IOException {
LogManager manager = LogManager.getLogManager();
manager.checkPermission();
if (count < 1) {
throw new IllegalArgumentException("file count = " + count);
}
@ -481,7 +473,7 @@ public class FileHandler extends StreamHandler {
// Now try to lock that filename.
// Because some systems (e.g., Solaris) can only do file locks
// between processes (and not within a process), we first check
// if we ourself already have the file locked.
// if we ourselves already have the file locked.
synchronized(locks) {
if (locks.contains(lockFileName)) {
// We already own this lock, for a different FileHandler
@ -616,7 +608,7 @@ public class FileHandler extends StreamHandler {
* @param generation the generation number to distinguish rotated logs
* @param unique a unique number to resolve conflicts
* @return the generated File
* @throws IOException
* @throws IOException if an I/O error occurs
*/
private File generate(String pattern, int generation, int unique)
throws IOException
@ -696,7 +688,7 @@ public class FileHandler extends StreamHandler {
if (unique > 0 && !sawu) {
word = word.append('.').append(unique);
}
if (word.length() > 0) {
if (!word.isEmpty()) {
String n = word.toString();
Path p = prev == null ? Paths.get(n) : prev.resolveSibling(n);
result = result == null ? p : result.resolve(p);
@ -714,21 +706,7 @@ public class FileHandler extends StreamHandler {
/**
* Rotate the set of output files
*/
private void rotate() {
if (tryUseLock()) {
try {
rotate0();
} finally {
unlock();
}
} else {
synchronized (this) {
rotate0();
}
}
}
private void rotate0() {
private synchronized void rotate() {
Level oldLevel = getLevel();
setLevel(Level.OFF);
@ -761,40 +739,14 @@ public class FileHandler extends StreamHandler {
* silently ignored and is not published
*/
@Override
public void publish(LogRecord record) {
if (tryUseLock()) {
try {
publish0(record);
} finally {
unlock();
}
} else {
synchronized (this) {
publish0(record);
}
}
}
@SuppressWarnings("removal")
private void publish0(LogRecord record) {
public synchronized void publish(LogRecord record) {
if (!isLoggable(record)) {
return;
}
super.publish(record);
flush();
if (limit > 0 && (meter.written >= limit || meter.written < 0)) {
// We performed access checks in the "init" method to make sure
// we are only initialized from trusted code. So we assume
// it is OK to write the target files, even if we are
// currently being called from untrusted code.
// So it is safe to raise privilege here.
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
rotate();
return null;
}
});
rotate();
}
}
@ -802,21 +754,7 @@ public class FileHandler extends StreamHandler {
* Close all the files.
*/
@Override
public void close() {
if (tryUseLock()) {
try {
close0();
} finally {
unlock();
}
} else {
synchronized (this) {
close0();
}
}
}
private void close0() throws SecurityException {
public synchronized void close() {
super.close();
// Unlock any lock file.
if (lockFileName == null) {

View File

@ -28,9 +28,6 @@ package java.util.logging;
import java.util.Objects;
import java.io.UnsupportedEncodingException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.concurrent.locks.ReentrantLock;
/**
* A {@code Handler} object takes log messages from a {@code Logger} and
@ -52,6 +49,8 @@ import java.util.concurrent.locks.ReentrantLock;
public abstract class Handler {
private static final int offValue = Level.OFF.intValue();
// ensure log manager is initialized
private final LogManager manager = LogManager.getLogManager();
// We're using volatile here to avoid synchronizing getters, which
@ -66,7 +65,6 @@ public abstract class Handler {
private volatile Level logLevel = Level.ALL;
private volatile ErrorManager errorManager = new ErrorManager();
private volatile String encoding;
private final ReentrantLock lock;
/**
* Default constructor. The resulting {@code Handler} has a log
@ -74,19 +72,7 @@ public abstract class Handler {
* {@code Filter}. A default {@code ErrorManager} instance is installed
* as the {@code ErrorManager}.
*/
protected Handler() {
lock = initLocking();
}
private ReentrantLock initLocking() {
Class<?> clazz = this.getClass();
ClassLoader loader = clazz.getClassLoader();
if (loader != null && loader != ClassLoader.getPlatformClassLoader()) {
return null;
} else {
return new ReentrantLock();
}
}
protected Handler() { }
/**
* Package-private constructor for chaining from subclass constructors
@ -100,7 +86,6 @@ public abstract class Handler {
* nor found in LogManager configuration properties
* @param specifiedFormatter if not null, this is the formatter to configure
*/
@SuppressWarnings("removal")
Handler(Level defaultLevel, Formatter defaultFormatter,
Formatter specifiedFormatter) {
this();
@ -111,38 +96,23 @@ public abstract class Handler {
final Level level = manager.getLevelProperty(cname + ".level", defaultLevel);
final Filter filter = manager.getFilterProperty(cname + ".filter", null);
final Formatter formatter = specifiedFormatter == null
? manager.getFormatterProperty(cname + ".formatter", defaultFormatter)
: specifiedFormatter;
? manager.getFormatterProperty(cname + ".formatter", defaultFormatter)
: specifiedFormatter;
final String encoding = manager.getStringProperty(cname + ".encoding", null);
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
setLevel(level);
setFilter(filter);
setFormatter(formatter);
try {
setEncoding(encoding);
} catch (Exception ex) {
try {
setEncoding(null);
} catch (Exception ex2) {
// doing a setEncoding with null should always work.
// assert false;
}
}
return null;
setLevel(level);
setFilter(filter);
setFormatter(formatter);
try {
setEncoding(encoding);
} catch (Exception ex) {
try {
setEncoding(null);
} catch (Exception ex2) {
// doing a setEncoding with null should always work.
// assert false;
}
}, null, LogManager.controlPermission);
}
boolean tryUseLock() {
if (lock == null) return false;
lock.lock();
return true;
}
void unlock() {
lock.unlock();
}
}
/**
@ -183,22 +153,7 @@ public abstract class Handler {
*
* @param newFormatter the {@code Formatter} to use (may not be null)
*/
public void setFormatter(Formatter newFormatter) {
if (tryUseLock()) {
try {
setFormatter0(newFormatter);
} finally {
unlock();
}
} else {
synchronized (this) {
setFormatter0(newFormatter);
}
}
}
private void setFormatter0(Formatter newFormatter) throws SecurityException {
checkPermission();
public synchronized void setFormatter(Formatter newFormatter) {
formatter = Objects.requireNonNull(newFormatter);
}
@ -221,24 +176,8 @@ public abstract class Handler {
* @throws UnsupportedEncodingException if the named encoding is
* not supported.
*/
public void setEncoding(String encoding)
public synchronized void setEncoding(String encoding)
throws java.io.UnsupportedEncodingException {
if (tryUseLock()) {
try {
setEncoding0(encoding);
} finally {
unlock();
}
} else {
synchronized (this) {
setEncoding0(encoding);
}
}
}
private void setEncoding0(String encoding)
throws SecurityException, java.io.UnsupportedEncodingException {
checkPermission();
if (encoding != null) {
try {
if(!java.nio.charset.Charset.isSupported(encoding)) {
@ -270,22 +209,7 @@ public abstract class Handler {
*
* @param newFilter a {@code Filter} object (may be null)
*/
public void setFilter(Filter newFilter) {
if (tryUseLock()) {
try {
setFilter0(newFilter);
} finally {
unlock();
}
} else {
synchronized (this) {
setFilter0(newFilter);
}
}
}
private void setFilter0(Filter newFilter) throws SecurityException {
checkPermission();
public synchronized void setFilter(Filter newFilter) {
filter = newFilter;
}
@ -306,22 +230,7 @@ public abstract class Handler {
*
* @param em the new ErrorManager
*/
public void setErrorManager(ErrorManager em) {
if (tryUseLock()) {
try {
setErrorManager0(em);
} finally {
unlock();
}
} else {
synchronized (this) {
setErrorManager0(em);
}
}
}
private void setErrorManager0(ErrorManager em) {
checkPermission();
public synchronized void setErrorManager(ErrorManager em) {
if (em == null) {
throw new NullPointerException();
}
@ -334,7 +243,6 @@ public abstract class Handler {
* @return the ErrorManager for this Handler
*/
public ErrorManager getErrorManager() {
checkPermission();
return errorManager;
}
@ -366,25 +274,10 @@ public abstract class Handler {
*
* @param newLevel the new value for the log level
*/
public void setLevel(Level newLevel) {
if (tryUseLock()) {
try {
setLevel0(newLevel);
} finally {
unlock();
}
} else {
synchronized (this) {
setLevel0(newLevel);
}
}
}
private void setLevel0(Level newLevel) throws SecurityException {
public synchronized void setLevel(Level newLevel) {
if (newLevel == null) {
throw new NullPointerException();
}
checkPermission();
logLevel = newLevel;
}
@ -426,10 +319,4 @@ public abstract class Handler {
return filter.isLoggable(record);
}
// Package-private support method for security checks.
// We check that the caller has appropriate security privileges
// to update Handler state and if not throw a SecurityException.
void checkPermission() throws SecurityException {
manager.checkPermission();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -29,8 +29,6 @@ import java.io.Serial;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@ -620,9 +618,7 @@ public class Level implements java.io.Serializable {
}
private static void registerWithClassLoader(Level customLevel) {
PrivilegedAction<ClassLoader> pa = customLevel.getClass()::getClassLoader;
@SuppressWarnings("removal")
final ClassLoader cl = AccessController.doPrivileged(pa);
final ClassLoader cl = customLevel.getClass().getClassLoader();
CUSTOM_LEVEL_CLV.computeIfAbsent(cl, (c, v) -> new ArrayList<>())
.add(customLevel);
}

View File

@ -27,7 +27,6 @@ package java.util.logging;
import java.io.*;
import java.util.*;
import java.security.*;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.concurrent.ConcurrentHashMap;
@ -39,8 +38,6 @@ import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jdk.internal.access.JavaAWTAccess;
import jdk.internal.access.SharedSecrets;
import sun.util.logging.internal.LoggingProviderImpl;
import static jdk.internal.logger.DefaultLoggerFinder.isSystem;
@ -218,39 +215,36 @@ public class LogManager {
Collections.synchronizedMap(new IdentityHashMap<>());
// The global LogManager object
@SuppressWarnings("removal")
private static final LogManager manager = AccessController.doPrivileged(
new PrivilegedAction<LogManager>() {
@Override
public LogManager run() {
LogManager mgr = null;
String cname = null;
try {
cname = System.getProperty("java.util.logging.manager");
if (cname != null) {
try {
@SuppressWarnings("deprecation")
Object tmp = ClassLoader.getSystemClassLoader()
.loadClass(cname).newInstance();
mgr = (LogManager) tmp;
} catch (ClassNotFoundException ex) {
@SuppressWarnings("deprecation")
Object tmp = Thread.currentThread()
.getContextClassLoader().loadClass(cname).newInstance();
mgr = (LogManager) tmp;
}
}
} catch (Exception ex) {
System.err.println("Could not load Logmanager \"" + cname + "\"");
ex.printStackTrace();
}
if (mgr == null) {
mgr = new LogManager();
}
return mgr;
private static final LogManager manager = initLogManager();
private static LogManager initLogManager() {
LogManager mgr = null;
String cname = null;
try {
cname = System.getProperty("java.util.logging.manager");
if (cname != null) {
try {
@SuppressWarnings("deprecation")
Object tmp = ClassLoader.getSystemClassLoader()
.loadClass(cname).newInstance();
mgr = (LogManager) tmp;
} catch (ClassNotFoundException ex) {
@SuppressWarnings("deprecation")
Object tmp = Thread.currentThread()
.getContextClassLoader().loadClass(cname).newInstance();
mgr = (LogManager) tmp;
}
});
}
} catch (Exception ex) {
System.err.println("Could not load Logmanager \"" + cname + "\"");
ex.printStackTrace();
}
if (mgr == null) {
mgr = new LogManager();
}
return mgr;
}
// This private class is used as a shutdown hook.
// It does a "reset" to close all open handlers.
@ -290,11 +284,6 @@ public class LogManager {
* retrieved by calling LogManager.getLogManager.
*/
protected LogManager() {
this(checkSubclassPermissions());
}
private LogManager(Void checked) {
// Add a shutdown hook to close the global handlers.
try {
Runtime.getRuntime().addShutdownHook(new Cleaner());
@ -304,20 +293,6 @@ public class LogManager {
}
}
private static Void checkSubclassPermissions() {
@SuppressWarnings("removal")
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// These permission will be checked in the LogManager constructor,
// in order to register the Cleaner() thread as a shutdown hook.
// Check them here to avoid the penalty of constructing the object
// etc...
sm.checkPermission(new RuntimePermission("shutdownHooks"));
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
}
return null;
}
/**
* Lazy initialization: if this instance of manager is the global
* manager then this method will read the initial configuration and
@ -380,40 +355,33 @@ public class LogManager {
// We use initializedCalled to break the recursion.
initializedCalled = true;
try {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
assert rootLogger == null;
assert initializedCalled && !initializationDone;
assert rootLogger == null;
assert initializedCalled && !initializationDone;
// create root logger before reading primordial
// configuration - to ensure that it will be added
// before the global logger, and not after.
final Logger root = owner.rootLogger = owner.new RootLogger();
// create root logger before reading primordial
// configuration - to ensure that it will be added
// before the global logger, and not after.
final Logger root = owner.rootLogger = owner.new RootLogger();
// Read configuration.
owner.readPrimordialConfiguration();
// Read configuration.
owner.readPrimordialConfiguration();
// Create and retain Logger for the root of the namespace.
owner.addLogger(root);
// Create and retain Logger for the root of the namespace.
owner.addLogger(root);
// Initialize level if not yet initialized
if (!root.isLevelInitialized()) {
root.setLevel(defaultLevel);
}
// Initialize level if not yet initialized
if (!root.isLevelInitialized()) {
root.setLevel(defaultLevel);
}
// Adding the global Logger.
// Do not call Logger.getGlobal() here as this might trigger
// subtle inter-dependency issues.
@SuppressWarnings("deprecation")
final Logger global = Logger.global;
// Adding the global Logger.
// Do not call Logger.getGlobal() here as this might trigger
// subtle inter-dependency issues.
@SuppressWarnings("deprecation") final Logger global = Logger.global;
// Make sure the global logger will be registered in the
// global manager
owner.addLogger(global);
return null;
}
});
// Make sure the global logger will be registered in the
// global manager
owner.addLogger(global);
} finally {
initializationDone = true;
}
@ -461,29 +429,6 @@ public class LogManager {
// Loggers are isolated from each AppContext.
private LoggerContext getUserContext() {
LoggerContext context = null;
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
JavaAWTAccess javaAwtAccess = SharedSecrets.getJavaAWTAccess();
if (sm != null && javaAwtAccess != null) {
// for each applet, it has its own LoggerContext isolated from others
final Object ecx = javaAwtAccess.getAppletContext();
if (ecx != null) {
synchronized (javaAwtAccess) {
// find the AppContext of the applet code
// will be null if we are in the main app context.
if (contextsMap == null) {
contextsMap = new WeakHashMap<>();
}
context = contextsMap.get(ecx);
if (context == null) {
// Create a new LoggerContext for the applet.
context = new LoggerContext();
contextsMap.put(ecx, context);
}
}
}
}
// for standalone app, return userContext
return context != null ? context : userContext;
}
@ -552,7 +497,6 @@ public class LogManager {
return demandSystemLogger(name, resourceBundleName, module);
}
@SuppressWarnings("removal")
Logger demandSystemLogger(String name, String resourceBundleName, Module module) {
// Add a system logger in the system context's namespace
final Logger sysLogger = getSystemContext()
@ -578,14 +522,7 @@ public class LogManager {
// LogManager will set the sysLogger's handlers via LogManager.addLogger method.
if (logger != sysLogger) {
// if logger already exists we merge the two logger configurations.
final Logger l = logger;
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
l.mergeWithSystemLogger(sysLogger);
return null;
}
});
logger.mergeWithSystemLogger(sysLogger);
}
return sysLogger;
}
@ -801,7 +738,7 @@ public class LogManager {
// the logger's level is already initialized
Level level = owner.getLevelProperty(name + ".level", null);
if (level != null && !logger.isLevelInitialized()) {
doSetLevel(logger, level);
logger.setLevel(level);
}
// instantiation of the handler is done in the LogManager.addLogger
@ -826,7 +763,7 @@ public class LogManager {
}
if (parent != null) {
doSetParent(logger, parent);
logger.setParent(parent);
}
// Walk over the children and tell them we are their new parent.
node.walkAndSetParent(logger);
@ -855,22 +792,15 @@ public class LogManager {
// If logger.getUseParentHandlers() returns 'true' and any of the logger's
// parents have levels or handlers defined, make sure they are instantiated.
@SuppressWarnings("removal")
private void processParentHandlers(final Logger logger, final String name,
Predicate<Logger> visited) {
final LogManager owner = getOwner();
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
if (logger != owner.rootLogger) {
boolean useParent = owner.getBooleanProperty(name + ".useParentHandlers", true);
if (!useParent) {
logger.setUseParentHandlers(false);
}
}
return null;
if (logger != owner.rootLogger) {
boolean useParent = owner.getBooleanProperty(name + ".useParentHandlers", true);
if (!useParent) {
logger.setUseParentHandlers(false);
}
});
}
int ix = 1;
for (;;) {
@ -898,7 +828,7 @@ public class LogManager {
return root;
}
LogNode node = root;
while (name.length() > 0) {
while (!name.isEmpty()) {
int ix = name.indexOf('.');
String head;
if (ix > 0) {
@ -961,21 +891,10 @@ public class LogManager {
}
// Add new per logger handlers.
// We need to raise privilege here. All our decisions will
// be made based on the logging configuration, which can
// only be modified by trusted code.
@SuppressWarnings("removal")
private void loadLoggerHandlers(final Logger logger, final String name,
final String handlersPropertyName)
{
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
setLoggerHandlers(logger, name, handlersPropertyName,
createLoggerHandlers(name, handlersPropertyName));
return null;
}
});
final String handlersPropertyName) {
setLoggerHandlers(logger, name, handlersPropertyName,
createLoggerHandlers(name, handlersPropertyName));
}
private void setLoggerHandlers(final Logger logger, final String name,
@ -1228,45 +1147,6 @@ public class LogManager {
&& configurationLock.isHeldByCurrentThread();
}
// Private method to set a level on a logger.
// If necessary, we raise privilege before doing the call.
@SuppressWarnings("removal")
private static void doSetLevel(final Logger logger, final Level level) {
SecurityManager sm = System.getSecurityManager();
if (sm == null) {
// There is no security manager, so things are easy.
logger.setLevel(level);
return;
}
// There is a security manager. Raise privilege before
// calling setLevel.
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
logger.setLevel(level);
return null;
}});
}
// Private method to set a parent on a logger.
// If necessary, we raise privilege before doing the setParent call.
@SuppressWarnings("removal")
private static void doSetParent(final Logger logger, final Logger parent) {
SecurityManager sm = System.getSecurityManager();
if (sm == null) {
// There is no security manager, so things are easy.
logger.setParent(parent);
return;
}
// There is a security manager. Raise privilege before
// calling setParent.
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
logger.setParent(parent);
return null;
}});
}
/**
* Method to find a named logger.
@ -1350,7 +1230,6 @@ public class LogManager {
* @throws IOException if there are IO problems reading the configuration.
*/
public void readConfiguration() throws IOException {
checkPermission();
// if a configuration class is specified, load it and use it.
String cname = System.getProperty("java.util.logging.config.class");
@ -1383,7 +1262,7 @@ public class LogManager {
}
}
String getConfigurationFileName() throws IOException {
String getConfigurationFileName() {
String fname = System.getProperty("java.util.logging.config.file");
if (fname == null) {
fname = System.getProperty("java.home");
@ -1413,7 +1292,6 @@ public class LogManager {
*/
public void reset() {
checkPermission();
List<CloseOnReset> persistent;
@ -1518,7 +1396,7 @@ public class LogManager {
String word = hands.substring(ix, end);
ix = end+1;
word = word.trim();
if (word.length() == 0) {
if (word.isEmpty()) {
continue;
}
result.add(word);
@ -1553,7 +1431,6 @@ public class LogManager {
* {@linkplain java.util.Properties properties file} format.
*/
public void readConfiguration(InputStream ins) throws IOException {
checkPermission();
// We don't want reset() and readConfiguration() to run
// in parallel.
@ -1857,7 +1734,6 @@ public class LogManager {
*/
public void updateConfiguration(Function<String, BiFunction<String,String,String>> mapper)
throws IOException {
checkPermission();
ensureLogManagerInitialized();
drainLoggerRefQueueBounded();
@ -2054,7 +1930,6 @@ public class LogManager {
public void updateConfiguration(InputStream ins,
Function<String, BiFunction<String,String,String>> mapper)
throws IOException {
checkPermission();
ensureLogManagerInitialized();
drainLoggerRefQueueBounded();
@ -2410,16 +2285,6 @@ public class LogManager {
}
}
static final Permission controlPermission =
new LoggingPermission("control", null);
void checkPermission() {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(controlPermission);
}
/**
* Does nothing.
*
@ -2456,7 +2321,7 @@ public class LogManager {
if (logger == null) {
node.walkAndSetParent(parent);
} else {
doSetParent(logger, parent);
logger.setParent(parent);
}
}
}
@ -2590,19 +2455,8 @@ public class LogManager {
*/
public LogManager addConfigurationListener(Runnable listener) {
final Runnable r = Objects.requireNonNull(listener);
checkPermission();
@SuppressWarnings("removal")
final SecurityManager sm = System.getSecurityManager();
@SuppressWarnings("removal")
final AccessControlContext acc =
sm == null ? null : AccessController.getContext();
final PrivilegedAction<Void> pa =
acc == null ? null : () -> { r.run() ; return null; };
@SuppressWarnings("removal")
final Runnable pr =
acc == null ? r : () -> AccessController.doPrivileged(pa, acc);
// Will do nothing if already registered.
listeners.putIfAbsent(r, pr);
listeners.putIfAbsent(r, r);
return this;
}
@ -2618,7 +2472,6 @@ public class LogManager {
*/
public void removeConfigurationListener(Runnable listener) {
final Runnable key = Objects.requireNonNull(listener);
checkPermission();
listeners.remove(key);
}
@ -2652,8 +2505,7 @@ public class LogManager {
* behalf of system and application classes.
*/
private static final class LoggingProviderAccess
implements LoggingProviderImpl.LogManagerAccess,
PrivilegedAction<Void> {
implements LoggingProviderImpl.LogManagerAccess {
private LoggingProviderAccess() {
}
@ -2684,11 +2536,6 @@ public class LogManager {
}
Objects.requireNonNull(name);
Objects.requireNonNull(module);
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(controlPermission);
}
if (isSystem(module)) {
return manager.demandSystemLogger(name,
Logger.SYSTEM_LOGGER_RB_NAME, module);
@ -2697,23 +2544,15 @@ public class LogManager {
}
}
@Override
public Void run() {
private void init() {
LoggingProviderImpl.setLogManagerAccess(INSTANCE);
return null;
}
static final LoggingProviderAccess INSTANCE = new LoggingProviderAccess();
}
static {
initStatic();
}
@SuppressWarnings("removal")
private static void initStatic() {
AccessController.doPrivileged(LoggingProviderAccess.INSTANCE, null,
controlPermission);
LoggingProviderAccess.INSTANCE.init();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,8 +28,6 @@ import java.time.Instant;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import java.io.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.time.Clock;
import java.util.function.Predicate;
import static jdk.internal.logger.SurrogateLogger.isFilteredFrame;
@ -767,14 +765,10 @@ public class LogRecord implements java.io.Serializable {
/*
* CallerFinder is a stateful predicate.
*/
@SuppressWarnings("removal")
static final class CallerFinder implements Predicate<StackWalker.StackFrame> {
private static final StackWalker WALKER;
static {
final PrivilegedAction<StackWalker> action =
() -> StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
WALKER = AccessController.doPrivileged(action);
}
private static final StackWalker WALKER =
StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
/**
* Returns StackFrame of the caller's frame.

View File

@ -26,8 +26,6 @@
package java.util.logging;
import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Locale;
@ -579,7 +577,7 @@ public class Logger {
// should never come here
throw new InternalError("invalid logger merge");
}
checkPermission();
ensureManagerInitialized();
final ConfigurationData cfg = config;
if (cfg != system.config) {
config = cfg.merge(system);
@ -614,13 +612,12 @@ public class Logger {
this.manager = manager;
}
private void checkPermission() throws SecurityException {
private void ensureManagerInitialized() {
if (!anonymous) {
if (manager == null) {
// Complete initialization of the global Logger.
manager = LogManager.getLogManager();
}
manager.checkPermission();
}
}
@ -633,17 +630,8 @@ public class Logger {
// These system loggers only set the resource bundle to the given
// resource bundle name (rather than the default system resource bundle).
private static class SystemLoggerHelper {
static boolean disableCallerCheck = getBooleanProperty("sun.util.logging.disableCallerCheck");
private static boolean getBooleanProperty(final String key) {
@SuppressWarnings("removal")
String s = AccessController.doPrivileged(new PrivilegedAction<String>() {
@Override
public String run() {
return System.getProperty(key);
}
});
return Boolean.parseBoolean(s);
}
static boolean disableCallerCheck =
Boolean.getBoolean("sun.util.logging.disableCallerCheck");
}
private static Logger demandLogger(String name, String resourceBundleName, Class<?> caller) {
@ -930,7 +918,7 @@ public class Logger {
* @param newFilter a filter object (may be null)
*/
public void setFilter(Filter newFilter) {
checkPermission();
ensureManagerInitialized();
config.setFilter(newFilter);
}
@ -1990,7 +1978,7 @@ public class Logger {
* @param newLevel the new value for the log level (may be null)
*/
public void setLevel(Level newLevel) {
checkPermission();
ensureManagerInitialized();
synchronized (treeLock) {
config.setLevelObject(newLevel);
updateEffectiveLevel();
@ -2047,7 +2035,7 @@ public class Logger {
*/
public void addHandler(Handler handler) {
Objects.requireNonNull(handler);
checkPermission();
ensureManagerInitialized();
config.addHandler(handler);
}
@ -2059,7 +2047,7 @@ public class Logger {
* @param handler a logging Handler
*/
public void removeHandler(Handler handler) {
checkPermission();
ensureManagerInitialized();
if (handler == null) {
return;
}
@ -2091,7 +2079,7 @@ public class Logger {
* logger's parent.
*/
public void setUseParentHandlers(boolean useParentHandlers) {
checkPermission();
ensureManagerInitialized();
config.setUseParentHandlers(useParentHandlers);
}
@ -2187,11 +2175,8 @@ public class Logger {
try {
// We are called by an unnamed module: try with the
// unnamed module class loader:
PrivilegedAction<ClassLoader> getModuleClassLoader =
() -> callerModule.getClassLoader();
@SuppressWarnings("removal")
ClassLoader moduleCL =
AccessController.doPrivileged(getModuleClassLoader);
ClassLoader moduleCL = callerModule.getClassLoader();
// moduleCL can be null if the logger is created by a class
// appended to the bootclasspath.
// If moduleCL is null we would use cl, but we already tried
@ -2267,7 +2252,7 @@ public class Logger {
setCallerModuleRef(callerModule);
if (isSystemLogger && (callerModule != null && !isSystem(callerModule))) {
checkPermission();
ensureManagerInitialized();
}
if (name.equals(SYSTEM_LOGGER_RB_NAME)) {
@ -2300,7 +2285,7 @@ public class Logger {
* @since 1.8
*/
public void setResourceBundle(ResourceBundle bundle) {
checkPermission();
ensureManagerInitialized();
// Will throw NPE if bundle is null.
final String baseName = bundle.getBaseBundleName();
@ -2359,11 +2344,7 @@ public class Logger {
throw new NullPointerException();
}
// check permission for all loggers, including anonymous loggers
if (manager == null) {
manager = LogManager.getLogManager();
}
manager.checkPermission();
ensureManagerInitialized();
doSetParent(parent);
}

View File

@ -26,7 +26,6 @@
package java.util.logging;
import java.security.*;
/**
* This class is for logging permissions. Currently there is only one

View File

@ -178,21 +178,7 @@ public class MemoryHandler extends Handler {
* silently ignored and is not published
*/
@Override
public void publish(LogRecord record) {
if (tryUseLock()) {
try {
publish0(record);
} finally {
unlock();
}
} else {
synchronized (this) {
publish0(record);
}
}
}
private void publish0(LogRecord record) {
public synchronized void publish(LogRecord record) {
if (!isLoggable(record)) {
return;
}
@ -214,21 +200,7 @@ public class MemoryHandler extends Handler {
* <p>
* The buffer is then cleared.
*/
public void push() {
if (tryUseLock()) {
try {
push0();
} finally {
unlock();
}
} else {
synchronized (this) {
push0();
}
}
}
private void push0() {
public synchronized void push() {
for (int i = 0; i < count; i++) {
int ix = (start+i)%buffer.length;
LogRecord record = buffer[ix];
@ -267,25 +239,10 @@ public class MemoryHandler extends Handler {
*
* @param newLevel the new value of the {@code pushLevel}
*/
public void setPushLevel(Level newLevel) {
if (tryUseLock()) {
try {
setPushLevel0(newLevel);
} finally {
unlock();
}
} else {
synchronized (this) {
setPushLevel0(newLevel);
}
}
}
private void setPushLevel0(Level newLevel) throws SecurityException {
public synchronized void setPushLevel(Level newLevel) {
if (newLevel == null) {
throw new NullPointerException();
}
checkPermission();
pushLevel = newLevel;
}

View File

@ -146,28 +146,14 @@ public class SocketHandler extends StreamHandler {
sock = new Socket(host, port);
OutputStream out = sock.getOutputStream();
BufferedOutputStream bout = new BufferedOutputStream(out);
setOutputStreamPrivileged(bout);
setOutputStream(bout);
}
/**
* Close this output stream.
*/
@Override
public void close() {
if (tryUseLock()) {
try {
close0();
} finally {
unlock();
}
} else {
synchronized (this) {
close0();
}
}
}
private void close0() throws SecurityException {
public synchronized void close() {
super.close();
if (sock != null) {
try {
@ -186,21 +172,7 @@ public class SocketHandler extends StreamHandler {
* silently ignored and is not published
*/
@Override
public void publish(LogRecord record) {
if (tryUseLock()) {
try {
publish0(record);
} finally {
unlock();
}
} else {
synchronized (this) {
publish0(record);
}
}
}
private void publish0(LogRecord record) {
public synchronized void publish(LogRecord record) {
if (!isLoggable(record)) {
return;
}

View File

@ -27,8 +27,6 @@
package java.util.logging;
import java.io.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Objects;
/**
@ -99,7 +97,7 @@ public class StreamHandler extends Handler {
// configure with default level but use specified formatter
super(Level.INFO, null, Objects.requireNonNull(formatter));
setOutputStreamPrivileged(out);
setOutputStream(out);
}
/**
@ -120,21 +118,7 @@ public class StreamHandler extends Handler {
*
* @param out New output stream. May not be null.
*/
protected void setOutputStream(OutputStream out) {
if (tryUseLock()) {
try {
setOutputStream0(out);
} finally {
unlock();
}
} else {
synchronized (this) {
setOutputStream0(out);
}
}
}
private void setOutputStream0(OutputStream out) throws SecurityException {
protected synchronized void setOutputStream(OutputStream out) {
if (out == null) {
throw new NullPointerException();
}
@ -167,22 +151,8 @@ public class StreamHandler extends Handler {
* not supported.
*/
@Override
public void setEncoding(String encoding)
public synchronized void setEncoding(String encoding)
throws java.io.UnsupportedEncodingException {
if (tryUseLock()) {
try {
setEncoding0(encoding);
} finally {
unlock();
}
} else {
synchronized (this) {
setEncoding0(encoding);
}
}
}
private void setEncoding0(String encoding)
throws SecurityException, java.io.UnsupportedEncodingException {
super.setEncoding(encoding);
if (output == null) {
return;
@ -214,22 +184,8 @@ public class StreamHandler extends Handler {
* silently ignored and is not published
*/
@Override
public void publish(LogRecord record) {
if (tryUseLock()) {
try {
publish0(record);
} finally {
unlock();
}
} else {
synchronized (this) {
publish0(record);
}
}
}
private void publish0(LogRecord record) {
if (!isLoggable(record)) {
public synchronized void publish(LogRecord record) {
if (!isLoggable(record)) {
return;
}
String msg;
@ -280,21 +236,7 @@ public class StreamHandler extends Handler {
* Flush any buffered messages.
*/
@Override
public void flush() {
if (tryUseLock()) {
try {
flush0();
} finally {
unlock();
}
} else {
synchronized (this) {
flush0();
}
}
}
private void flush0() {
public synchronized void flush() {
Writer writer = this.writer;
if (writer != null) {
try {
@ -307,8 +249,7 @@ public class StreamHandler extends Handler {
}
}
private void flushAndClose() throws SecurityException {
checkPermission();
private void flushAndClose() {
Writer writer = this.writer;
if (writer != null) {
try {
@ -338,30 +279,8 @@ public class StreamHandler extends Handler {
* "tail" string.
*/
@Override
public void close() {
if (tryUseLock()) {
try {
flushAndClose();
} finally {
unlock();
}
} else {
synchronized (this) {
flushAndClose();
}
}
public synchronized void close() {
flushAndClose();
}
// Package-private support for setting OutputStream
// with elevated privilege.
@SuppressWarnings("removal")
final void setOutputStreamPrivileged(final OutputStream out) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
setOutputStream(out);
return null;
}
}, null, LogManager.controlPermission);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,8 +26,6 @@
package sun.util.logging.internal;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ResourceBundle;
import java.util.function.Supplier;
import java.lang.System.LoggerFinder;
@ -35,7 +33,6 @@ import java.lang.System.Logger;
import java.util.Objects;
import java.util.logging.LogManager;
import jdk.internal.logger.DefaultLoggerFinder;
import java.util.logging.LoggingPermission;
import sun.util.logging.PlatformLogger;
import sun.util.logging.PlatformLogger.ConfigurableBridge.LoggerConfiguration;
@ -77,15 +74,9 @@ import sun.util.logging.PlatformLogger.ConfigurableBridge.LoggerConfiguration;
*
*/
public final class LoggingProviderImpl extends DefaultLoggerFinder {
static final RuntimePermission LOGGERFINDER_PERMISSION =
new RuntimePermission("loggerFinder");
private static final LoggingPermission LOGGING_CONTROL_PERMISSION =
new LoggingPermission("control", null);
/**
* Creates a new instance of LoggingProviderImpl.
* @throws SecurityException if the calling code does not have the
* {@code RuntimePermission("loggerFinder")}.
*/
public LoggingProviderImpl() {
}
@ -147,13 +138,13 @@ public final class LoggingProviderImpl extends DefaultLoggerFinder {
}
@Override
public void log(sun.util.logging.PlatformLogger.Level level, Supplier<String> msgSuppier) {
julLogger.log(toJUL(level), msgSuppier);
public void log(sun.util.logging.PlatformLogger.Level level, Supplier<String> msgSupplier) {
julLogger.log(toJUL(level), msgSupplier);
}
@Override
public void log(sun.util.logging.PlatformLogger.Level level, Throwable thrown, Supplier<String> msgSuppier) {
julLogger.log(toJUL(level), thrown, msgSuppier);
public void log(sun.util.logging.PlatformLogger.Level level, Throwable thrown, Supplier<String> msgSupplier) {
julLogger.log(toJUL(level), thrown, msgSupplier);
}
@Override
@ -403,18 +394,10 @@ public final class LoggingProviderImpl extends DefaultLoggerFinder {
* @param module the module for which the logger should be created.
* @return a Logger suitable for use in the given module.
*/
@SuppressWarnings("removal")
private static java.util.logging.Logger demandJULLoggerFor(final String name,
Module module) {
final LogManager manager = LogManager.getLogManager();
final SecurityManager sm = System.getSecurityManager();
if (sm == null) {
return logManagerAccess.demandLoggerFor(manager, name, module);
} else {
final PrivilegedAction<java.util.logging.Logger> pa =
() -> logManagerAccess.demandLoggerFor(manager, name, module);
return AccessController.doPrivileged(pa, null, LOGGING_CONTROL_PERMISSION);
}
return logManagerAccess.demandLoggerFor(manager, name, module);
}
/**
@ -425,16 +408,9 @@ public final class LoggingProviderImpl extends DefaultLoggerFinder {
* corresponding java.util.logging.Logger backend}.
*
* @return {@inheritDoc}
* @throws SecurityException if the calling code doesn't have the
* {@code RuntimePermission("loggerFinder")}.
*/
@Override
protected Logger demandLoggerFor(String name, Module module) {
@SuppressWarnings("removal")
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOGGERFINDER_PERMISSION);
}
return JULWrapper.of(demandJULLoggerFor(name,module));
}
@ -445,25 +421,17 @@ public final class LoggingProviderImpl extends DefaultLoggerFinder {
// Hook for tests
public static LogManagerAccess getLogManagerAccess() {
@SuppressWarnings("removal")
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOGGING_CONTROL_PERMISSION);
}
// Triggers initialization of accessJulLogger if not set.
// Triggers initialization of logManagerAccess if not set.
LogManagerAccess logManagerAccess = LoggingProviderImpl.logManagerAccess;
if (logManagerAccess == null) LogManager.getLogManager();
logManagerAccess = LoggingProviderImpl.logManagerAccess;
return logManagerAccess;
}
private static volatile LogManagerAccess logManagerAccess;
public static void setLogManagerAccess(LogManagerAccess accesLoggers) {
@SuppressWarnings("removal")
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOGGING_CONTROL_PERMISSION);
}
logManagerAccess = accesLoggers;
public static void setLogManagerAccess(LogManagerAccess accessLoggers) {
logManagerAccess = accessLoggers;
}
}