< prev index next >
src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java
Print this page
*** 29,38 ****
--- 29,39 ----
import java.security.PrivilegedAction;
import java.util.function.BiFunction;
import java.lang.System.LoggerFinder;
import java.lang.System.Logger;
import java.lang.ref.WeakReference;
+ import java.lang.reflect.Module;
import java.util.Objects;
import jdk.internal.misc.VM;
import sun.util.logging.PlatformLogger;
/**
*** 57,75 ****
/**
* A factory method to create an SPI logger.
* Usually, this will be something like LazyLoggers::getSystemLogger.
*/
! final BiFunction<String, Class<?>, L> loggerSupplier;
! public LazyLoggerFactories(BiFunction<String, Class<?>, L> loggerSupplier) {
this(Objects.requireNonNull(loggerSupplier),
(Void)null);
}
! private LazyLoggerFactories(BiFunction<String, Class<?>, L> loggerSupplier,
Void unused) {
this.loggerSupplier = loggerSupplier;
}
}
--- 58,76 ----
/**
* A factory method to create an SPI logger.
* Usually, this will be something like LazyLoggers::getSystemLogger.
*/
! final BiFunction<String, Module, L> loggerSupplier;
! public LazyLoggerFactories(BiFunction<String, Module, L> loggerSupplier) {
this(Objects.requireNonNull(loggerSupplier),
(Void)null);
}
! private LazyLoggerFactories(BiFunction<String, Module, L> loggerSupplier,
Void unused) {
this.loggerSupplier = loggerSupplier;
}
}
*** 105,116 ****
static final class LazyLoggerAccessor implements LoggerAccessor {
// The factories that will be used to create the logger lazyly
final LazyLoggerFactories<? extends Logger> factories;
! // We need to pass the actual caller when creating the logger.
! private final WeakReference<Class<?>> callerRef;
// The name of the logger that will be created lazyly
final String name;
// The plain logger SPI object - null until it is accessed for the
// first time.
--- 106,117 ----
static final class LazyLoggerAccessor implements LoggerAccessor {
// The factories that will be used to create the logger lazyly
final LazyLoggerFactories<? extends Logger> factories;
! // We need to pass the actual caller module when creating the logger.
! private final WeakReference<Module> moduleRef;
// The name of the logger that will be created lazyly
final String name;
// The plain logger SPI object - null until it is accessed for the
// first time.
*** 119,139 ****
private volatile PlatformLogger.Bridge p;
private LazyLoggerAccessor(String name,
LazyLoggerFactories<? extends Logger> factories,
! Class<?> caller) {
this(Objects.requireNonNull(name), Objects.requireNonNull(factories),
! Objects.requireNonNull(caller), null);
}
private LazyLoggerAccessor(String name,
LazyLoggerFactories<? extends Logger> factories,
! Class<?> caller, Void unused) {
this.name = name;
this.factories = factories;
! this.callerRef = new WeakReference<Class<?>>(caller);
}
/**
* The logger name.
* @return The name of the logger that is / will be lazily created.
--- 120,140 ----
private volatile PlatformLogger.Bridge p;
private LazyLoggerAccessor(String name,
LazyLoggerFactories<? extends Logger> factories,
! Module module) {
this(Objects.requireNonNull(name), Objects.requireNonNull(factories),
! Objects.requireNonNull(module), null);
}
private LazyLoggerAccessor(String name,
LazyLoggerFactories<? extends Logger> factories,
! Module module, Void unused) {
this.name = name;
this.factories = factories;
! this.moduleRef = new WeakReference<>(module);
}
/**
* The logger name.
* @return The name of the logger that is / will be lazily created.
*** 268,283 ****
return this.platform();
}
// Creates the wrapped logger by invoking the SPI.
Logger createLogger() {
! final Class<?> caller = callerRef.get();
! if (caller == null) {
! throw new IllegalStateException("The class for which this logger"
+ " was created has been garbage collected");
}
! return this.factories.loggerSupplier.apply(name, caller);
}
/**
* Creates a new lazy logger accessor for the named logger. The given
* factories will be use when it becomes necessary to actually create
--- 269,284 ----
return this.platform();
}
// Creates the wrapped logger by invoking the SPI.
Logger createLogger() {
! final Module module = moduleRef.get();
! if (module == null) {
! throw new IllegalStateException("The module for which this logger"
+ " was created has been garbage collected");
}
! return this.factories.loggerSupplier.apply(name, module);
}
/**
* Creates a new lazy logger accessor for the named logger. The given
* factories will be use when it becomes necessary to actually create
*** 287,298 ****
* @param factories The factories that should be used to create the
* wrapped logger.
* @return A new LazyLoggerAccessor.
*/
public static LazyLoggerAccessor makeAccessor(String name,
! LazyLoggerFactories<? extends Logger> factories, Class<?> caller) {
! return new LazyLoggerAccessor(name, factories, caller);
}
}
/**
--- 288,299 ----
* @param factories The factories that should be used to create the
* wrapped logger.
* @return A new LazyLoggerAccessor.
*/
public static LazyLoggerAccessor makeAccessor(String name,
! LazyLoggerFactories<? extends Logger> factories, Module module) {
! return new LazyLoggerAccessor(name, factories, module);
}
}
/**
*** 344,358 ****
return prov;
}
// Avoid using lambda here as lazy loggers could be created early
// in the bootstrap sequence...
! private static final BiFunction<String, Class<?>, Logger> loggerSupplier =
new BiFunction<>() {
@Override
! public Logger apply(String name, Class<?> caller) {
! return LazyLoggers.getLoggerFromFinder(name, caller);
}
};
private static final LazyLoggerFactories<Logger> factories =
new LazyLoggerFactories<>(loggerSupplier);
--- 345,359 ----
return prov;
}
// Avoid using lambda here as lazy loggers could be created early
// in the bootstrap sequence...
! private static final BiFunction<String, Module, Logger> loggerSupplier =
new BiFunction<>() {
@Override
! public Logger apply(String name, Module module) {
! return LazyLoggers.getLoggerFromFinder(name, module);
}
};
private static final LazyLoggerFactories<Logger> factories =
new LazyLoggerFactories<>(loggerSupplier);
*** 365,376 ****
// The JdkLazyLogger uses a LazyLoggerAccessor objects, which relies
// on the logic embedded in BootstrapLogger to avoid loading the concrete
// logger provider until the VM has finished booting.
//
private static final class JdkLazyLogger extends LazyLoggerWrapper {
! JdkLazyLogger(String name, Class<?> caller) {
! this(LazyLoggerAccessor.makeAccessor(name, factories, caller),
(Void)null);
}
private JdkLazyLogger(LazyLoggerAccessor holder, Void unused) {
super(holder);
}
--- 366,377 ----
// The JdkLazyLogger uses a LazyLoggerAccessor objects, which relies
// on the logic embedded in BootstrapLogger to avoid loading the concrete
// logger provider until the VM has finished booting.
//
private static final class JdkLazyLogger extends LazyLoggerWrapper {
! JdkLazyLogger(String name, Module module) {
! this(LazyLoggerAccessor.makeAccessor(name, factories, module),
(Void)null);
}
private JdkLazyLogger(LazyLoggerAccessor holder, Void unused) {
super(holder);
}
*** 378,434 ****
/**
* Gets a logger from the LoggerFinder. Creates the actual concrete
* logger.
* @param name name of the logger
! * @param caller class on behalf of which the logger is created
* @return The logger returned by the LoggerFinder.
*/
! static Logger getLoggerFromFinder(String name, Class<?> caller) {
final SecurityManager sm = System.getSecurityManager();
if (sm == null) {
! return accessLoggerFinder().getLogger(name, caller);
} else {
return AccessController.doPrivileged((PrivilegedAction<Logger>)
! () -> {return accessLoggerFinder().getLogger(name, caller);},
null, LOGGERFINDER_PERMISSION);
}
}
/**
* Returns a (possibly lazy) Logger for the caller.
*
* @param name the logger name
! * @param caller The class on behalf of which the logger is created.
! * If the caller is not loaded from the Boot ClassLoader,
* the LoggerFinder is accessed and the logger returned
! * by {@link LoggerFinder#getLogger(java.lang.String, java.lang.Class)}
* is returned to the caller directly.
* Otherwise, the logger returned by
! * {@link #getLazyLogger(java.lang.String, java.lang.Class)}
* is returned to the caller.
*
* @return a (possibly lazy) Logger instance.
*/
! public static final Logger getLogger(String name, Class<?> caller) {
! if (caller.getClassLoader() == null) {
! return getLazyLogger(name, caller);
} else {
! return getLoggerFromFinder(name, caller);
}
}
/**
* Returns a (possibly lazy) Logger suitable for system classes.
* Whether the returned logger is lazy or not depend on the result
* returned by {@link BootstrapLogger#useLazyLoggers()}.
*
* @param name the logger name
! * @param caller the class on behalf of which the logger is created.
* @return a (possibly lazy) Logger instance.
*/
! public static final Logger getLazyLogger(String name, Class<?> caller) {
// BootstrapLogger has the logic to determine whether a LazyLogger
// should be used. Usually, it is worth it only if:
// - the VM is not yet booted
// - or, the backend is JUL and there is no configuration
--- 379,435 ----
/**
* Gets a logger from the LoggerFinder. Creates the actual concrete
* logger.
* @param name name of the logger
! * @param module module on behalf of which the logger is created
* @return The logger returned by the LoggerFinder.
*/
! 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);
}
}
/**
* Returns a (possibly lazy) Logger for the caller.
*
* @param name the logger name
! * @param module The module on behalf of which the logger is created.
! * If the module is not loaded from the Boot ClassLoader,
* the LoggerFinder is accessed and the logger returned
! * by {@link LoggerFinder#getLogger(java.lang.String, java.lang.reflect.Module)}
* is returned to the caller directly.
* Otherwise, the logger returned by
! * {@link #getLazyLogger(java.lang.String, java.lang.reflect.Module)}
* is returned to the caller.
*
* @return a (possibly lazy) Logger instance.
*/
! public static final Logger getLogger(String name, Module module) {
! if (DefaultLoggerFinder.isSystem(module)) {
! return getLazyLogger(name, module);
} else {
! return getLoggerFromFinder(name, module);
}
}
/**
* Returns a (possibly lazy) Logger suitable for system classes.
* Whether the returned logger is lazy or not depend on the result
* returned by {@link BootstrapLogger#useLazyLoggers()}.
*
* @param name the logger name
! * @param module the module on behalf of which the logger is created.
* @return a (possibly lazy) Logger instance.
*/
! public static final Logger getLazyLogger(String name, Module module) {
// BootstrapLogger has the logic to determine whether a LazyLogger
// should be used. Usually, it is worth it only if:
// - the VM is not yet booted
// - or, the backend is JUL and there is no configuration
*** 436,448 ****
// that is going to load...
// So if for instance the VM is booted and we use JUL with a custom
// configuration, we're not going to delay the creation of loggers...
final boolean useLazyLogger = BootstrapLogger.useLazyLoggers();
if (useLazyLogger) {
! return new JdkLazyLogger(name, caller);
} else {
// Directly invoke the LoggerFinder.
! return getLoggerFromFinder(name, caller);
}
}
}
--- 437,449 ----
// that is going to load...
// So if for instance the VM is booted and we use JUL with a custom
// configuration, we're not going to delay the creation of loggers...
final boolean useLazyLogger = BootstrapLogger.useLazyLoggers();
if (useLazyLogger) {
! return new JdkLazyLogger(name, module);
} else {
// Directly invoke the LoggerFinder.
! return getLoggerFromFinder(name, module);
}
}
}
< prev index next >