OpenJDK / amber / amber
changeset 44416:2b02517c73a2
8177136: Caller sensitive method System::getLogger should specify what happens if there is no caller on the stack.
Summary: IllegalCallerException (instead of undocumented NPE) is thrown if there is no caller on the stack. The specification is clarified in this respect.
Reviewed-by: alanb, mchung, dholmes, bchristi
author | dfuchs |
---|---|
date | Wed, 29 Mar 2017 13:16:12 +0100 |
parents | 6acf3aa6d3e9 |
children | a431edba1629 |
files | jdk/src/java.base/share/classes/java/lang/System.java |
diffstat | 1 files changed, 27 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/jdk/src/java.base/share/classes/java/lang/System.java Tue Mar 28 17:33:48 2017 -0700 +++ b/jdk/src/java.base/share/classes/java/lang/System.java Wed Mar 29 13:16:12 2017 +0100 @@ -1568,6 +1568,14 @@ * obtained by calling {@link LoggerFinder#getLogger(java.lang.String, * java.lang.reflect.Module) LoggerFinder.getLogger(name, module)}, where * {@code module} is the caller's module. + * In cases where {@code System.getLogger} is called from a context where + * there is no caller frame on the stack (e.g when called directly + * from a JNI attached thread), {@code IllegalCallerException} is thrown. + * To obtain a logger in such a context, use an auxiliary class that will + * implicitly be identified as the caller, or use the system {@link + * LoggerFinder#getLoggerFinder() LoggerFinder} to obtain a logger instead. + * Note that doing the latter may eagerly initialize the underlying + * logging system. * * @apiNote * This method may defer calling the {@link @@ -1580,6 +1588,8 @@ * @return an instance of {@link Logger} that can be used by the calling * class. * @throws NullPointerException if {@code name} is {@code null}. + * @throws IllegalCallerException if there is no Java caller frame on the + * stack. * * @since 9 */ @@ -1587,6 +1597,9 @@ public static Logger getLogger(String name) { Objects.requireNonNull(name); final Class<?> caller = Reflection.getCallerClass(); + if (caller == null) { + throw new IllegalCallerException("no caller frame"); + } return LazyLoggers.getLogger(name, caller.getModule()); } @@ -1600,8 +1613,16 @@ * The returned logger will perform message localization as specified * by {@link LoggerFinder#getLocalizedLogger(java.lang.String, * java.util.ResourceBundle, java.lang.reflect.Module) - * LoggerFinder.getLocalizedLogger(name, bundle, module}, where + * LoggerFinder.getLocalizedLogger(name, bundle, module)}, where * {@code module} is the caller's module. + * In cases where {@code System.getLogger} is called from a context where + * there is no caller frame on the stack (e.g when called directly + * from a JNI attached thread), {@code IllegalCallerException} is thrown. + * To obtain a logger in such a context, use an auxiliary class that + * will implicitly be identified as the caller, or use the system {@link + * LoggerFinder#getLoggerFinder() LoggerFinder} to obtain a logger instead. + * Note that doing the latter may eagerly initialize the underlying + * logging system. * * @apiNote * This method is intended to be used after the system is fully initialized. @@ -1620,6 +1641,8 @@ * resource bundle for message localization. * @throws NullPointerException if {@code name} is {@code null} or * {@code bundle} is {@code null}. + * @throws IllegalCallerException if there is no Java caller frame on the + * stack. * * @since 9 */ @@ -1628,6 +1651,9 @@ final ResourceBundle rb = Objects.requireNonNull(bundle); Objects.requireNonNull(name); final Class<?> caller = Reflection.getCallerClass(); + if (caller == null) { + throw new IllegalCallerException("no caller frame"); + } final SecurityManager sm = System.getSecurityManager(); // We don't use LazyLoggers if a resource bundle is specified. // Bootstrap sensitive classes in the JDK do not use resource bundles