Path: blob/master/test/jdk/java/lang/System/LoggerFinder/internal/backend/LoggerFinderBackendTest.java
41161 views
/*1* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/**24* @test25* @bug 814036426* @author danielfuchs27* @summary JDK implementation specific unit test for JDK internal artifacts.28* This test tests all the public API methods defined in the {@link29* java.lang.System.Logger} interface, as well as all the JDK30* internal methods defined in the31* {@link sun.util.logging.PlatformLogger.Bridge}32* interface, with loggers returned by {@link33* java.lang.System.LoggerFinder#getLogger(java.lang.String, java.lang.Class)}34* and {@link java.lang.System.LoggerFinder#getLocalizedLogger(java.lang.String,35* java.util.ResourceBundle, java.lang.Class)}36* (using both a null resource bundle and a non null resource bundle).37* It calls both the {@link java.lang.System} factory methods and38* {@link jdk.internal.logger.LazyLoggers} to obtains those loggers,39* and configure them with all possible known levels.40* @modules java.base/java.lang:open41* java.base/sun.util.logging42* java.base/jdk.internal.logger43* java.logging/sun.util.logging.internal44* @build LoggerFinderBackendTest SystemClassLoader45* @run main/othervm -Djava.system.class.loader=SystemClassLoader -Dtest.logger.hidesProvider=true LoggerFinderBackendTest46* @run main/othervm -Djava.system.class.loader=SystemClassLoader -Dtest.logger.hidesProvider=false LoggerFinderBackendTest47*/484950import java.lang.invoke.MethodHandle;51import java.lang.invoke.MethodHandles;52import java.lang.invoke.MethodHandles.Lookup;53import java.lang.invoke.MethodType;54import java.lang.reflect.InvocationTargetException;55import java.lang.reflect.Method;56import java.util.ArrayList;57import java.util.Arrays;58import java.util.Collections;59import java.util.Enumeration;60import java.util.HashMap;61import java.util.LinkedHashMap;62import java.util.LinkedHashSet;63import java.util.List;64import java.util.Map;65import java.util.Objects;66import java.util.ResourceBundle;67import java.util.concurrent.atomic.AtomicInteger;68import java.util.function.BiFunction;69import java.util.function.BooleanSupplier;70import java.util.function.Function;71import java.util.function.Supplier;72import java.lang.System.LoggerFinder;73import java.util.logging.ConsoleHandler;74import java.util.logging.Handler;75import sun.util.logging.PlatformLogger.Level;76import java.util.logging.LogManager;77import java.util.logging.LogRecord;78import java.util.logging.Logger;79import sun.util.logging.internal.LoggingProviderImpl;8081/**82* @author danielfuchs83*/84public class LoggerFinderBackendTest {8586// whether the implementation of Logger try to do a best87// effort for logp... If the provider is not hidden, then88// the logp() implementation comes from LoggerWrapper - which does a89// best effort. Otherwise, it comes from the default provider90// which does support logp.91static final boolean BEST_EFFORT_FOR_LOGP =92!Boolean.getBoolean("test.logger.hidesProvider");93static final boolean VERBOSE = false;9495static final Class<java.lang.System.Logger> spiLoggerClass =96java.lang.System.Logger.class;97static final Class<java.lang.System.Logger> jdkLoggerClass =98java.lang.System.Logger.class;99static final Class<sun.util.logging.PlatformLogger.Bridge> bridgeLoggerClass =100sun.util.logging.PlatformLogger.Bridge.class;101102/** Use to retrieve the log records that were produced by the JUL backend */103static class LoggerTesterHandler extends Handler {104public final List<LogRecord> records =105Collections.synchronizedList(new ArrayList<>());106107@Override108public void publish(LogRecord record) {109record.getSourceClassName(); record.getSourceMethodName();110records.add(record);111}112113@Override114public void flush() {115}116117@Override118public void close() throws SecurityException {119records.clear();120}121122public void reset() {123records.clear();124}125}126127/** The {@link LoggerTesterHandler} handler is added to the root logger. */128static final LoggerTesterHandler handler = new LoggerTesterHandler();129static {130for (Handler h : Logger.getLogger("").getHandlers()) {131if (h instanceof ConsoleHandler) {132Logger.getLogger("").removeHandler(h);133}134}135Logger.getLogger("").addHandler(handler);136}137138/**139* A resource handler parameter that will be used when calling out the140* logrb-like methods - as well as when calling the level-specific141* methods that take a ResourceBundle parameter.142*/143public static class ResourceBundeParam extends ResourceBundle {144Map<String, String> map = Collections.synchronizedMap(new LinkedHashMap<>());145@Override146protected Object handleGetObject(String key) {147map.putIfAbsent(key, "${"+key+"}");148return map.get(key);149}150151@Override152public Enumeration<String> getKeys() {153return Collections.enumeration(new LinkedHashSet<>(map.keySet()));154}155156}157158final static ResourceBundle bundleParam =159ResourceBundle.getBundle(ResourceBundeParam.class.getName());160161/**162* A resource handler parameter that will be used when creating localized163* loggers by calling {@link164* LoggerFinder#getLocalizedLogger(java.lang.String, java.util.ResourceBundle, java.lang.Class)}.165*/166public static class ResourceBundeLocalized extends ResourceBundle {167Map<String, String> map = Collections.synchronizedMap(new LinkedHashMap<>());168@Override169protected Object handleGetObject(String key) {170map.putIfAbsent(key, "Localized:${"+key+"}");171return map.get(key);172}173174@Override175public Enumeration<String> getKeys() {176return Collections.enumeration(new LinkedHashSet<>(map.keySet()));177}178179}180181/**182* The Levels enum is used to call all the level-specific methods on183* a logger instance. To minimize the amount of code it uses reflection184* to do so.185*/186static Lookup lookup = MethodHandles.lookup();187public enum Levels {188/** Used to call all forms of Logger.log?(SEVERE, ...) */189SEVERE("severe", bridgeLoggerClass, Level.SEVERE, null, "error", false),190/** Used to call all forms of Logger.log?(WARNING,...) */191WARNING("warning", bridgeLoggerClass, Level.WARNING, "warning", "warning", false),192/** Used to call all forms of Logger.log?(INFO,...) */193INFO("info", bridgeLoggerClass, Level.INFO, "info", "info", false),194/** Used to call all forms of Logger.log?(CONFIG,...) */195CONFIG("config", bridgeLoggerClass, Level.CONFIG, null, "debug", false),196/** Used to call all forms of Logger.log?(FINE,...) */197FINE("fine", bridgeLoggerClass, Level.FINE, null, "debug", false),198/** Used to call all forms of Logger.log?(FINER,...) */199FINER("finer", bridgeLoggerClass, Level.FINER, null, "trace", false),200/** Used to call all forms of Logger.log?(FINEST,...) */201FINEST("finest", bridgeLoggerClass, Level.FINEST, null, "trace", false),202;203public final String method; // The name of the level-specific method to call204public final Class<?> definingClass; // which interface j.u.logger.Logger or j.u.logging.spi.Logger defines it205public final Level platformLevel; // The platform Level it will be mapped to in Jul when Jul is the backend206public final String jdkExtensionToJUL; // The name of the method called on the JUL logger when JUL is the backend207public final String julToJdkExtension; // The name of the method called in the jdk extension by the default impl in jdk.internal.logging.Logger208public final String enableMethod; // The name of the isXxxxEnabled method209public final boolean hasSpecificIsEnabled;210Levels(String method, Class<?> definingClass, Level defaultMapping,211String jdkExtensionToJUL, String julToJdkExtension,212boolean hasSpecificIsEnabled) {213this.method = method;214this.definingClass = definingClass;215this.platformLevel = defaultMapping;216this.jdkExtensionToJUL = jdkExtensionToJUL;217this.julToJdkExtension = julToJdkExtension;218this.hasSpecificIsEnabled = hasSpecificIsEnabled;219if (hasSpecificIsEnabled) {220this.enableMethod = "is" + method.substring(0,1).toUpperCase()221+ method.substring(1) + "Enabled";222} else {223this.enableMethod = "isLoggable";224}225}226227/*228* calls this level specific method - e.g. if this==INFO: logger.info(msg);229*/230public void level(Object logger, String msg) {231MethodType mt = MethodType.methodType(void.class, Level.class, String.class);232invoke("log", logger, mt, platformLevel, msg);233}234235/*236* calls this level specific method - e.g. if this==INFO: logger.info(msgSupplier);237*/238public void level(Object logger, Supplier<String> msgSupplier) {239MethodType mt = MethodType.methodType(void.class, Level.class, Supplier.class);240invoke("log", logger, mt, platformLevel, msgSupplier);241}242243/*244* calls this level specific method - e.g. if this==INFO: logger.info(msg, params);245*/246public void level(Object logger, String msg, Object... params) {247MethodType mt = MethodType.methodType(void.class, Level.class, String.class,248Object[].class);249invoke("log", logger, mt, platformLevel, msg, params);250}251252/*253* calls this level specific method - e.g. if this==INFO: logger.info(msg, thrown);254*/255public void level(Object logger, String msg, Throwable thrown) {256MethodType mt = MethodType.methodType(void.class, Level.class, String.class,257Throwable.class);258invoke("log", logger, mt, platformLevel, msg, thrown);259}260261/*262* calls this level specific method - e.g. if this==INFO: logger.info(msgSupplier, thrown);263*/264public void level(Object logger, Supplier<String> msgSupplier, Throwable thrown) {265MethodType mt = MethodType.methodType(void.class, Level.class,266Throwable.class, Supplier.class);267invoke("log", logger, mt, platformLevel, thrown, msgSupplier);268}269270/*271* calls this level specific method - e.g. if this==INFO: logger.info(bundle, msg);272*/273public void level(Object logger, String msg, ResourceBundle bundle) {274MethodType mt = MethodType.methodType(void.class, Level.class,275ResourceBundle.class, String.class, Object[].class);276invoke("logrb", logger, mt, platformLevel, bundle, msg, null);277}278279public void level(Object logger, String msg, ResourceBundle bundle,280Object... params) {281MethodType mt = MethodType.methodType(void.class, Level.class,282ResourceBundle.class, String.class, Object[].class);283invoke("logrb", logger, mt, platformLevel, bundle, msg, params);284}285286public void level(Object logger, String msg, ResourceBundle bundle,287Throwable thrown) {288MethodType mt = MethodType.methodType(void.class, Level.class,289ResourceBundle.class, String.class, Throwable.class);290invoke("logrb", logger, mt, platformLevel, bundle, msg, thrown);291}292293public boolean isEnabled(Object logger) {294try {295if (hasSpecificIsEnabled) {296MethodType mt = MethodType.methodType(boolean.class);297final MethodHandle handle = lookup.findVirtual(definingClass,298enableMethod, mt).bindTo(logger);299return Boolean.class.cast(handle.invoke());300} else {301MethodType mt = MethodType.methodType(boolean.class,302Level.class);303final MethodHandle handle = lookup.findVirtual(definingClass,304enableMethod, mt).bindTo(logger);305return Boolean.class.cast(handle.invoke(platformLevel));306}307} catch (Throwable ex) {308throw new RuntimeException(ex);309}310}311312private void invoke(String method, Object logger, MethodType mt, Object... args) {313try {314final int last = mt.parameterCount()-1;315boolean isVarargs = mt.parameterType(last).isArray();316final MethodHandle handle = lookup.findVirtual(definingClass,317method, mt).bindTo(logger);318319final StringBuilder builder = new StringBuilder();320builder.append(logger.getClass().getSimpleName()).append('.')321.append(method).append('(');322String sep = "";323int offset = 0;324Object[] params = args;325for (int i=0; (i-offset) < params.length; i++) {326if (isVarargs && i == last) {327offset = last;328params = (Object[])args[i];329if (params == null) break;330}331Object p = params[i - offset];332String quote = (p instanceof String) ? "\"" : "";333builder.append(sep).append(quote).append(p).append(quote);334sep = ", ";335}336builder.append(')');337if (verbose) {338System.out.println(builder);339}340handle.invokeWithArguments(args);341} catch (Throwable ex) {342throw new RuntimeException(ex);343}344}345346};347348static interface Checker<LogResult, L> extends BiFunction<LogResult, L, Void> {}349static interface JdkLogTester350extends BiFunction<sun.util.logging.PlatformLogger.Bridge, Level, Void> {}351static interface SpiLogTester352extends BiFunction<java.lang.System.Logger, java.lang.System.Logger.Level, Void> {}353354static interface MethodInvoker<LOGGER, LEVEL> {355public void logX(LOGGER logger, LEVEL level, Object... args);356}357358public enum JdkLogMethodInvoker359implements MethodInvoker<sun.util.logging.PlatformLogger.Bridge, Level> {360/**361* Tests {@link362* jdk.internal.logging.Logger#log(Level, String, Object...)};363**/364LOG_STRING_PARAMS("log", MethodType.methodType(void.class,365Level.class, String.class, Object[].class)),366/**367* Tests {@link368* jdk.internal.logging.Logger#log(Level, String, Throwable)};369**/370LOG_STRING_THROWN("log", MethodType.methodType(void.class,371Level.class, String.class, Throwable.class)),372/**373* Tests {@link374* jdk.internal.logging.Logger#log(Level, Supplier<String>)};375**/376LOG_SUPPLIER("log", MethodType.methodType(void.class,377Level.class, Supplier.class)),378/**379* Tests {@link380* jdk.internal.logging.Logger#log(Level, Throwable, Supplier<String>)};381**/382LOG_SUPPLIER_THROWN("log", MethodType.methodType(void.class,383Level.class, Throwable.class, Supplier.class)),384/**385* Tests {@link386* jdk.internal.logging.Logger#logp(Level, String, String, String)};387**/388LOGP_STRING("logp", MethodType.methodType(void.class,389Level.class, String.class, String.class, String.class)),390/**391* Tests {@link392* jdk.internal.logging.Logger#logp(Level, String, String, String, Object...)};393**/394LOGP_STRING_PARAMS("logp", MethodType.methodType(void.class,395Level.class, String.class, String.class, String.class, Object[].class)),396/**397* Tests {@link398* jdk.internal.logging.Logger#logp(Level, String, String, String, Throwable)};399**/400LOGP_STRING_THROWN("logp", MethodType.methodType(void.class,401Level.class, String.class, String.class, String.class, Throwable.class)),402/**403* Tests {@link404* jdk.internal.logging.Logger#logp(Level, String, String, Supplier<String>)};405**/406LOGP_SUPPLIER("logp", MethodType.methodType(void.class,407Level.class, String.class, String.class, Supplier.class)),408/**409* Tests {@link410* jdk.internal.logging.Logger#logp(Level, String, String, Throwable, Supplier<String>)};411**/412LOGP_SUPPLIER_THROWN("logp", MethodType.methodType(void.class,413Level.class, String.class, String.class,414Throwable.class, Supplier.class)),415/**416* Tests {@link417* jdk.internal.logging.Logger#logrb(Level, ResourceBundle, String, Object...)};418**/419LOGRB_STRING_PARAMS("logrb", MethodType.methodType(void.class,420Level.class, ResourceBundle.class, String.class, Object[].class)),421/**422* Tests {@link423* jdk.internal.logging.Logger#logrb(Level, ResourceBundle, String, Throwable)};424**/425LOGRB_STRING_THROWN("logrb", MethodType.methodType(void.class,426Level.class, ResourceBundle.class, String.class, Throwable.class)),427/**428* Tests {@link429* jdk.internal.logging.Logger#logrb(Level, String, String, ResourceBundle, String, Object...)};430**/431LOGRBP_STRING_PARAMS("logrb", MethodType.methodType(void.class,432Level.class, String.class, String.class, ResourceBundle.class,433String.class, Object[].class)),434/**435* Tests {@link436* jdk.internal.logging.Logger#logrb(Level, String, String, ResourceBundle, String, Throwable)};437**/438LOGRBP_STRING_THROWN("logrb", MethodType.methodType(void.class,439Level.class, String.class, String.class, ResourceBundle.class,440String.class, Throwable.class)),441;442final MethodType mt;443final String method;444JdkLogMethodInvoker(String method, MethodType mt) {445this.mt = mt;446this.method = method;447}448Object[] makeArgs(Level level, Object... rest) {449List<Object> list = new ArrayList<>(rest == null ? 1 : rest.length + 1);450list.add(level);451if (rest != null) {452list.addAll(Arrays.asList(rest));453}454return list.toArray(new Object[list.size()]);455}456457@Override458public void logX(sun.util.logging.PlatformLogger.Bridge logger, Level level, Object... args) {459try {460MethodHandle handle = lookup.findVirtual(bridgeLoggerClass,461method, mt).bindTo(logger);462final int last = mt.parameterCount()-1;463boolean isVarargs = mt.parameterType(last).isArray();464465args = makeArgs(level, args);466467final StringBuilder builder = new StringBuilder();468builder.append(logger.getClass().getSimpleName()).append('.')469.append(this.method).append('(');470String sep = "";471int offset = 0;472Object[] params = args;473for (int i=0; (i-offset) < params.length; i++) {474if (isVarargs && i == last) {475offset = last;476params = (Object[])args[i];477if (params == null) break;478}479Object p = params[i - offset];480String quote = (p instanceof String) ? "\"" : "";481p = p instanceof Level ? "Level."+p : p;482builder.append(sep).append(quote).append(p).append(quote);483sep = ", ";484}485builder.append(')');486if (verbose) System.out.println(builder);487handle.invokeWithArguments(args);488} catch (Throwable ex) {489throw new RuntimeException(ex);490}491}492}493494495public enum SpiLogMethodInvoker implements MethodInvoker<java.lang.System.Logger,496java.lang.System.Logger.Level> {497/**498* Tests {@link499* jdk.internal.logging.Logger#log(Level, String, Object...)};500**/501LOG_STRING_PARAMS("log", MethodType.methodType(void.class,502java.lang.System.Logger.Level.class, String.class, Object[].class)),503/**504* Tests {@link505* jdk.internal.logging.Logger#log(Level, String, Throwable)};506**/507LOG_STRING_THROWN("log", MethodType.methodType(void.class,508java.lang.System.Logger.Level.class, String.class, Throwable.class)),509/**510* Tests {@link511* jdk.internal.logging.Logger#log(Level, Supplier<String>)};512**/513LOG_SUPPLIER("log", MethodType.methodType(void.class,514java.lang.System.Logger.Level.class, Supplier.class)),515/**516* Tests {@link517* jdk.internal.logging.Logger#log(Level, Throwable, Supplier<String>)};518**/519LOG_SUPPLIER_THROWN("log", MethodType.methodType(void.class,520java.lang.System.Logger.Level.class, Supplier.class, Throwable.class)),521/**522* Tests {@link523* jdk.internal.logging.Logger#log(Level, Supplier<String>)};524**/525LOG_OBJECT("log", MethodType.methodType(void.class,526java.lang.System.Logger.Level.class, Object.class)),527/**528* Tests {@link529* jdk.internal.logging.Logger#logrb(Level, ResourceBundle, String, Object...)};530**/531LOGRB_STRING_PARAMS("log", MethodType.methodType(void.class,532java.lang.System.Logger.Level.class, ResourceBundle.class,533String.class, Object[].class)),534/**535* Tests {@link536* jdk.internal.logging.Logger#logrb(Level, ResourceBundle, String, Throwable)};537**/538LOGRB_STRING_THROWN("log", MethodType.methodType(void.class,539java.lang.System.Logger.Level.class, ResourceBundle.class,540String.class, Throwable.class)),541;542final MethodType mt;543final String method;544SpiLogMethodInvoker(String method, MethodType mt) {545this.mt = mt;546this.method = method;547}548Object[] makeArgs(java.lang.System.Logger.Level level, Object... rest) {549List<Object> list = new ArrayList<>(rest == null ? 1 : rest.length + 1);550list.add(level);551if (rest != null) {552list.addAll(Arrays.asList(rest));553}554return list.toArray(new Object[list.size()]);555}556557@Override558public void logX(java.lang.System.Logger logger,559java.lang.System.Logger.Level level, Object... args) {560try {561MethodHandle handle = lookup.findVirtual(spiLoggerClass,562method, mt).bindTo(logger);563final int last = mt.parameterCount()-1;564boolean isVarargs = mt.parameterType(last).isArray();565566args = makeArgs(level, args);567568final StringBuilder builder = new StringBuilder();569builder.append(logger.getClass().getSimpleName()).append('.')570.append(this.method).append('(');571String sep = "";572int offset = 0;573Object[] params = args;574for (int i=0; (i-offset) < params.length; i++) {575if (isVarargs && i == last) {576offset = last;577params = (Object[])args[i];578if (params == null) break;579}580Object p = params[i - offset];581String quote = (p instanceof String) ? "\"" : "";582p = p instanceof Level ? "Level."+p : p;583builder.append(sep).append(quote).append(p).append(quote);584sep = ", ";585}586builder.append(')');587if (verbose) System.out.println(builder);588handle.invokeWithArguments(args);589} catch (Throwable ex) {590throw new RuntimeException(ex);591}592}593}594595596public abstract static class BackendTester<BackendRecord> {597static final Level[] levelMap = {Level.ALL, Level.FINER, Level.FINE,598Level.INFO, Level.WARNING, Level.SEVERE, Level.OFF};599600abstract class BackendAdaptor {601public abstract String getLoggerName(BackendRecord res);602public abstract Object getLevel(BackendRecord res);603public abstract String getMessage(BackendRecord res);604public abstract String getSourceClassName(BackendRecord res);605public abstract String getSourceMethodName(BackendRecord res);606public abstract Throwable getThrown(BackendRecord res);607public abstract ResourceBundle getResourceBundle(BackendRecord res);608public abstract void setLevel(java.lang.System.Logger logger,609Level level);610public abstract void setLevel(java.lang.System.Logger logger,611java.lang.System.Logger.Level level);612public abstract List<BackendRecord> getBackendRecords();613public abstract void resetBackendRecords();614public boolean shouldBeLoggable(Levels level, Level loggerLevel) {615final Level logLevel = level.platformLevel;616return shouldBeLoggable(logLevel, loggerLevel);617}618public boolean shouldBeLoggable(Level logLevel, Level loggerLevel) {619return loggerLevel.intValue() != Level.OFF.intValue()620&& logLevel.intValue() >= loggerLevel.intValue();621}622public boolean shouldBeLoggable(java.lang.System.Logger.Level logLevel,623java.lang.System.Logger.Level loggerLevel) {624return loggerLevel != java.lang.System.Logger.Level.OFF625&& logLevel.ordinal() >= loggerLevel.ordinal();626}627public boolean isLoggable(java.lang.System.Logger logger, Level l) {628return bridgeLoggerClass.cast(logger).isLoggable(l);629}630public String getCallerClassName(Levels level, String clazz) {631return clazz != null ? clazz : Levels.class.getName();632}633public String getCallerClassName(MethodInvoker<?,?> logMethod,634String clazz) {635return clazz != null ? clazz : logMethod.getClass().getName();636}637public String getCallerMethodName(Levels level, String method) {638return method != null ? method : "invoke";639}640public String getCallerMethodName(MethodInvoker<?,?> logMethod,641String method) {642return method != null ? method : "logX";643}644public Object getMappedLevel(Object level) {645return level;646}647648public Level toJUL(java.lang.System.Logger.Level level) {649return levelMap[level.ordinal()];650}651}652653public final boolean isSystem;654public final Class<? extends java.lang.System.Logger> restrictedTo;655public final ResourceBundle localized;656public BackendTester(boolean isSystem) {657this(isSystem,null,null);658}659public BackendTester(boolean isSystem, ResourceBundle localized) {660this(isSystem,null,localized);661}662public BackendTester(boolean isSystem,663Class<? extends java.lang.System.Logger> restrictedTo) {664this(isSystem, restrictedTo, null);665}666public BackendTester(boolean isSystem,667Class<? extends java.lang.System.Logger> restrictedTo,668ResourceBundle localized) {669this.isSystem = isSystem;670this.restrictedTo = restrictedTo;671this.localized = localized;672}673674public java.lang.System.Logger convert(java.lang.System.Logger logger) {675return logger;676}677678public static Level[] LEVELS = {679Level.OFF,680Level.SEVERE, Level.WARNING, Level.INFO, Level.CONFIG,681Level.FINE, Level.FINER, Level.FINEST,682Level.ALL683};684685abstract BackendAdaptor adaptor();686687protected void checkRecord(Levels test, BackendRecord res, String loggerName,688Level level, String msg, String className, String methodName,689Throwable thrown, ResourceBundle bundle, Object... params) {690checkRecord(test, res, loggerName, level, ()->msg, className,691methodName, thrown, bundle, params);692693}694protected void checkRecord(Levels test, BackendRecord res, String loggerName,695Level level, Supplier<String> msg, String className, String methodName,696Throwable thrown, ResourceBundle bundle, Object... params) {697checkRecord(test.method, res, loggerName, level, msg,698className, methodName, thrown, bundle, params);699}700protected <L> void checkRecord(String logMethod, BackendRecord res, String loggerName,701L level, Supplier<String> msg, String className, String methodName,702Throwable thrown, ResourceBundle bundle, Object... params) {703final BackendAdaptor analyzer = adaptor();704if (! Objects.equals(analyzer.getLoggerName(res), loggerName)) {705throw new RuntimeException(logMethod+": expected logger name "706+ loggerName + " got " + analyzer.getLoggerName(res));707}708if (!Objects.equals(analyzer.getLevel(res), analyzer.getMappedLevel(level))) {709throw new RuntimeException(logMethod+": expected level "710+ analyzer.getMappedLevel(level) + " got " + analyzer.getLevel(res));711}712if (!Objects.equals(analyzer.getMessage(res), msg.get())) {713throw new RuntimeException(logMethod+": expected message \""714+ msg.get() + "\" got \"" + analyzer.getMessage(res) +"\"");715}716if (!Objects.equals(analyzer.getSourceClassName(res), className)) {717throw new RuntimeException(logMethod718+ ": expected class name \"" + className719+ "\" got \"" + analyzer.getSourceClassName(res) +"\"");720}721if (!Objects.equals(analyzer.getSourceMethodName(res), methodName)) {722throw new RuntimeException(logMethod723+ ": expected method name \"" + methodName724+ "\" got \"" + analyzer.getSourceMethodName(res) +"\"");725}726final Throwable thrownRes = analyzer.getThrown(res);727if (!Objects.equals(thrownRes, thrown)) {728throw new RuntimeException(logMethod729+ ": expected throwable \"" + thrown730+ "\" got \"" + thrownRes + "\"");731}732if (!Objects.equals(analyzer.getResourceBundle(res), bundle)) {733throw new RuntimeException(logMethod734+ ": expected bundle \"" + bundle735+ "\" got \"" + analyzer.getResourceBundle(res) +"\"");736}737}738739public void testLevel(Levels level, java.lang.System.Logger logger,740String msg) {741Runnable test = () -> level.level(logger, msg);742Checker<BackendRecord, Level> check = (res, l) -> {743checkRecord(level, res, logger.getName(), l, msg,744adaptor().getCallerClassName(level, Levels.class.getName()),745adaptor().getCallerMethodName(level, "invoke"),746null, localized);747return null;748};749test("msg", level, logger, test, check);750}751752public void testLevel(Levels level, java.lang.System.Logger logger,753String msg, Object... params) {754Runnable test = () -> level.level(logger, msg, (Object[])params);755Checker<BackendRecord, Level> check = (res, l) -> {756checkRecord(level, res, logger.getName(), l, msg,757adaptor().getCallerClassName(level, Levels.class.getName()),758adaptor().getCallerMethodName(level, "invoke"),759null, localized, (Object[])params);760return null;761};762test("msg, params", level, logger, test, check);763}764765public void testLevel(Levels level, java.lang.System.Logger logger,766String msg, Throwable thrown) {767Runnable test = () -> level.level(logger, msg, thrown);768Checker<BackendRecord, Level> check = (res, l) -> {769checkRecord(level, res, logger.getName(), l, msg,770adaptor().getCallerClassName(level, Levels.class.getName()),771adaptor().getCallerMethodName(level, "invoke"),772thrown, localized);773return null;774};775test("msg, thrown", level, logger, test, check);776}777778public void testLevel(Levels level, java.lang.System.Logger logger,779Supplier<String> msg) {780Runnable test = () -> level.level(logger, msg);781Checker<BackendRecord, Level> check = (res, l) -> {782checkRecord(level, res, logger.getName(), l, msg,783adaptor().getCallerClassName(level, Levels.class.getName()),784adaptor().getCallerMethodName(level, "invoke"),785null, null);786return null;787};788test("msgSupplier", level, logger, test, check);789}790791public void testLevel(Levels level, java.lang.System.Logger logger,792Supplier<String> msg, Throwable thrown) {793Runnable test = () -> level.level(logger, msg, thrown);794Checker<BackendRecord, Level> check = (res, l) -> {795checkRecord(level, res, logger.getName(), l, msg,796adaptor().getCallerClassName(level, Levels.class.getName()),797adaptor().getCallerMethodName(level, "invoke"),798thrown, null);799return null;800};801test("throw, msgSupplier", level, logger, test, check);802}803804public void testLevel(Levels level, java.lang.System.Logger logger,805String msg, ResourceBundle bundle) {806Runnable test = () -> level.level(logger, msg, bundle);807Checker<BackendRecord, Level> check = (res, l) -> {808checkRecord(level, res, logger.getName(), l, msg,809adaptor().getCallerClassName(level, Levels.class.getName()),810adaptor().getCallerMethodName(level, "invoke"),811null, bundle);812return null;813};814test("bundle, msg", level, logger, test, check);815}816817public void testLevel(Levels level, java.lang.System.Logger logger,818String msg, ResourceBundle bundle, Object... params) {819Runnable test = () -> level.level(logger, msg, bundle, (Object[])params);820Checker<BackendRecord, Level> check = (res, l) -> {821checkRecord(level, res, logger.getName(), l, msg,822adaptor().getCallerClassName(level, Levels.class.getName()),823adaptor().getCallerMethodName(level, "invoke"),824null, bundle, (Object[])params);825return null;826};827test("bundle, msg, params", level, logger, test, check);828}829830public void testLevel(Levels level, java.lang.System.Logger logger,831String msg, ResourceBundle bundle, Throwable thrown) {832Runnable test = () -> level.level(logger, msg, bundle, thrown);833Checker<BackendRecord, Level> check = (res, l) -> {834checkRecord(level, res, logger.getName(), l, msg,835adaptor().getCallerClassName(level, Levels.class.getName()),836adaptor().getCallerMethodName(level, "invoke"),837thrown, bundle);838return null;839};840test("bundle, msg, throwable", level, logger, test, check);841}842843// System.Logger844public void testSpiLog(java.lang.System.Logger logger, String msg) {845Checker<BackendRecord, java.lang.System.Logger.Level> check = (res, l) -> {846checkRecord("log", res, logger.getName(), l, () -> msg,847adaptor().getCallerClassName(848SpiLogMethodInvoker.LOG_STRING_PARAMS,849SpiLogMethodInvoker.class.getName()),850adaptor().getCallerMethodName(851SpiLogMethodInvoker.LOG_STRING_PARAMS,852"logX"), null, localized);853return null;854};855SpiLogTester tester = (x, level) -> {856SpiLogMethodInvoker.LOG_STRING_PARAMS.logX(x, level, msg, (Object[])null);857return null;858};859Function<String, String> nameProducer = (l) -> "log(Level." + l + ", \"" + msg + "\")";860testSpiLog(logger, tester, check, nameProducer);861}862863public void testSpiLog(java.lang.System.Logger logger,864ResourceBundle bundle, String msg) {865Checker<BackendRecord, java.lang.System.Logger.Level> check = (res, l) -> {866checkRecord("log", res, logger.getName(), l, () -> msg,867adaptor().getCallerClassName(868SpiLogMethodInvoker.LOGRB_STRING_PARAMS,869SpiLogMethodInvoker.class.getName()),870adaptor().getCallerMethodName(871SpiLogMethodInvoker.LOGRB_STRING_PARAMS,872"logX"), null, bundle);873return null;874};875SpiLogTester tester = (x, level) -> {876SpiLogMethodInvoker.LOGRB_STRING_PARAMS.logX(x, level, bundle, msg, (Object[])null);877return null;878};879Function<String, String> nameProducer = (l) -> "log(Level." + l880+ ", bundle, \"" + msg + "\")";881testSpiLog(logger, tester, check, nameProducer);882}883884public void testSpiLog(java.lang.System.Logger logger, String msg, Object... params) {885Checker<BackendRecord, java.lang.System.Logger.Level> check = (res, l) -> {886checkRecord("log", res, logger.getName(), l, () -> msg,887adaptor().getCallerClassName(888SpiLogMethodInvoker.LOG_STRING_PARAMS,889SpiLogMethodInvoker.class.getName()),890adaptor().getCallerMethodName(891SpiLogMethodInvoker.LOG_STRING_PARAMS,892"logX"), null, localized, params);893return null;894};895SpiLogTester tester = (x, level) -> {896SpiLogMethodInvoker.LOG_STRING_PARAMS.logX(x, level, msg, params);897return null;898};899Function<String, String> nameProducer = (l) -> "log(Level." + l + ", \"" + msg + "\", params...)";900testSpiLog(logger, tester, check, nameProducer);901}902903public void testSpiLog(java.lang.System.Logger logger,904ResourceBundle bundle, String msg, Object... params) {905Checker<BackendRecord, java.lang.System.Logger.Level> check = (res, l) -> {906checkRecord("log", res, logger.getName(), l, () -> msg,907adaptor().getCallerClassName(908SpiLogMethodInvoker.LOGRB_STRING_PARAMS,909SpiLogMethodInvoker.class.getName()),910adaptor().getCallerMethodName(911SpiLogMethodInvoker.LOGRB_STRING_PARAMS,912"logX"), null, bundle, params);913return null;914};915SpiLogTester tester = (x, level) -> {916SpiLogMethodInvoker.LOGRB_STRING_PARAMS.logX(x, level, bundle, msg, params);917return null;918};919Function<String, String> nameProducer = (l) -> "log(Level." + l920+ ", bundle, \"" + msg + "\", params...)";921testSpiLog(logger, tester, check, nameProducer);922}923924public void testSpiLog(java.lang.System.Logger logger, String msg, Throwable thrown) {925Checker<BackendRecord, java.lang.System.Logger.Level> check = (res, l) -> {926checkRecord("log", res, logger.getName(), l, () -> msg,927adaptor().getCallerClassName(928SpiLogMethodInvoker.LOG_STRING_THROWN,929SpiLogMethodInvoker.class.getName()),930adaptor().getCallerMethodName(931SpiLogMethodInvoker.LOG_STRING_THROWN,932"logX"), thrown, localized);933return null;934};935SpiLogTester tester = (x, level) -> {936SpiLogMethodInvoker.LOG_STRING_THROWN.logX(x, level, msg, thrown);937return null;938};939Function<String, String> nameProducer = (l) ->940"log(Level." + l + ", \"" + msg + "\", thrown)";941testSpiLog(logger, tester, check, nameProducer);942}943944public void testSpiLog(java.lang.System.Logger logger,945ResourceBundle bundle, String msg, Throwable thrown) {946Checker<BackendRecord, java.lang.System.Logger.Level> check = (res, l) -> {947checkRecord("log", res, logger.getName(), l, () -> msg,948adaptor().getCallerClassName(949SpiLogMethodInvoker.LOGRB_STRING_THROWN,950SpiLogMethodInvoker.class.getName()),951adaptor().getCallerMethodName(952SpiLogMethodInvoker.LOGRB_STRING_THROWN,953"logX"), thrown, bundle);954return null;955};956SpiLogTester tester = (x, level) -> {957SpiLogMethodInvoker.LOGRB_STRING_THROWN.logX(x, level, bundle, msg, thrown);958return null;959};960Function<String, String> nameProducer = (l) ->961"log(Level." + l + ", bundle, \"" + msg + "\", thrown)";962testSpiLog(logger, tester, check, nameProducer);963}964965public void testSpiLog(java.lang.System.Logger logger, Supplier<String> msg) {966Checker<BackendRecord, java.lang.System.Logger.Level> check = (res, l) -> {967checkRecord("log", res, logger.getName(), l, msg,968adaptor().getCallerClassName(969SpiLogMethodInvoker.LOG_SUPPLIER,970SpiLogMethodInvoker.class.getName()),971adaptor().getCallerMethodName(972SpiLogMethodInvoker.LOG_SUPPLIER,973"logX"), null, null);974return null;975};976SpiLogTester tester = (x, level) -> {977SpiLogMethodInvoker.LOG_SUPPLIER.logX(x, level, msg);978return null;979};980Function<String, String> nameProducer = (l) ->981"log(Level." + l + ", () -> \"" + msg.get() + "\")";982testSpiLog(logger, tester, check, nameProducer);983}984985public void testSpiLog(java.lang.System.Logger logger, Object obj) {986Checker<BackendRecord, java.lang.System.Logger.Level> check = (res, l) -> {987checkRecord("log", res, logger.getName(), l, () -> obj.toString(),988adaptor().getCallerClassName(989SpiLogMethodInvoker.LOG_OBJECT,990SpiLogMethodInvoker.class.getName()),991adaptor().getCallerMethodName(992SpiLogMethodInvoker.LOG_OBJECT,993"logX"), null, null);994return null;995};996SpiLogTester tester = (x, level) -> {997SpiLogMethodInvoker.LOG_OBJECT.logX(x, level, obj);998return null;999};1000Function<String, String> nameProducer = (l) ->1001"log(Level." + l + ", new "+obj.getClass().getSimpleName()+"(\""1002+ obj.toString() + "\"))";1003testSpiLog(logger, tester, check, nameProducer);1004}10051006public void testSpiLog(java.lang.System.Logger logger, Throwable thrown, Supplier<String> msg) {1007Checker<BackendRecord, java.lang.System.Logger.Level> check = (res, l) -> {1008checkRecord("log", res, logger.getName(), l, msg,1009adaptor().getCallerClassName(1010SpiLogMethodInvoker.LOG_SUPPLIER_THROWN,1011SpiLogMethodInvoker.class.getName()),1012adaptor().getCallerMethodName(1013SpiLogMethodInvoker.LOG_SUPPLIER_THROWN,1014"logX"), thrown, null);1015return null;1016};1017SpiLogTester tester = (x, level) -> {1018SpiLogMethodInvoker.LOG_SUPPLIER_THROWN.logX(x, level, msg, thrown);1019return null;1020};1021Function<String, String> nameProducer = (l) ->1022"log(Level." + l + ", () -> \"" + msg.get() + "\", thrown)";1023testSpiLog(logger, tester, check, nameProducer);1024}102510261027// JDK10281029public void testLog(java.lang.System.Logger logger, String msg) {1030Checker<BackendRecord, Level> check = (res, l) -> {1031checkRecord("log", res, logger.getName(), l, () -> msg,1032adaptor().getCallerClassName(1033JdkLogMethodInvoker.LOG_STRING_PARAMS,1034JdkLogMethodInvoker.class.getName()),1035adaptor().getCallerMethodName(1036JdkLogMethodInvoker.LOG_STRING_PARAMS,1037"logX"), null, localized);1038return null;1039};1040JdkLogTester tester = (x, level) -> {1041JdkLogMethodInvoker.LOG_STRING_PARAMS.logX(x, level, msg, (Object[])null);1042return null;1043};1044Function<String, String> nameProducer = (l) -> "log(Level." + l + ", \"" + msg + "\")";1045testJdkLog(logger, tester, check, nameProducer);1046}10471048public void testLogrb(java.lang.System.Logger logger,1049ResourceBundle bundle, String msg) {1050Checker<BackendRecord, Level> check = (res, l) -> {1051checkRecord("log", res, logger.getName(), l, () -> msg,1052adaptor().getCallerClassName(1053JdkLogMethodInvoker.LOGRB_STRING_PARAMS,1054JdkLogMethodInvoker.class.getName()),1055adaptor().getCallerMethodName(1056JdkLogMethodInvoker.LOGRB_STRING_PARAMS,1057"logX"), null, bundle);1058return null;1059};1060JdkLogTester tester = (x, level) -> {1061JdkLogMethodInvoker.LOGRB_STRING_PARAMS.logX(x, level, bundle, msg, (Object[])null);1062return null;1063};1064Function<String, String> nameProducer = (l) -> "logrb(Level." + l1065+ ", bundle, \"" + msg + "\")";1066testJdkLog(logger, tester, check, nameProducer);1067}10681069public void testLog(java.lang.System.Logger logger, String msg, Object... params) {1070Checker<BackendRecord, Level> check = (res, l) -> {1071checkRecord("log", res, logger.getName(), l, () -> msg,1072adaptor().getCallerClassName(1073JdkLogMethodInvoker.LOG_STRING_PARAMS,1074JdkLogMethodInvoker.class.getName()),1075adaptor().getCallerMethodName(1076JdkLogMethodInvoker.LOG_STRING_PARAMS,1077"logX"), null, localized, params);1078return null;1079};1080JdkLogTester tester = (x, level) -> {1081JdkLogMethodInvoker.LOG_STRING_PARAMS.logX(x, level, msg, params);1082return null;1083};1084Function<String, String> nameProducer = (l) -> "log(Level." + l + ", \"" + msg + "\", params...)";1085testJdkLog(logger, tester, check, nameProducer);1086}10871088public void testLogrb(java.lang.System.Logger logger,1089ResourceBundle bundle, String msg, Object... params) {1090Checker<BackendRecord, Level> check = (res, l) -> {1091checkRecord("log", res, logger.getName(), l, () -> msg,1092adaptor().getCallerClassName(1093JdkLogMethodInvoker.LOGRB_STRING_PARAMS,1094JdkLogMethodInvoker.class.getName()),1095adaptor().getCallerMethodName(1096JdkLogMethodInvoker.LOGRB_STRING_PARAMS,1097"logX"), null, bundle, params);1098return null;1099};1100JdkLogTester tester = (x, level) -> {1101JdkLogMethodInvoker.LOGRB_STRING_PARAMS.logX(x, level, bundle, msg, params);1102return null;1103};1104Function<String, String> nameProducer = (l) -> "log(Level." + l1105+ ", bundle, \"" + msg + "\", params...)";1106testJdkLog(logger, tester, check, nameProducer);1107}11081109public void testLog(java.lang.System.Logger logger, String msg, Throwable thrown) {1110Checker<BackendRecord, Level> check = (res, l) -> {1111checkRecord("log", res, logger.getName(), l, () -> msg,1112adaptor().getCallerClassName(1113JdkLogMethodInvoker.LOG_STRING_THROWN,1114JdkLogMethodInvoker.class.getName()),1115adaptor().getCallerMethodName(1116JdkLogMethodInvoker.LOG_STRING_THROWN,1117"logX"), thrown, localized);1118return null;1119};1120JdkLogTester tester = (x, level) -> {1121JdkLogMethodInvoker.LOG_STRING_THROWN.logX(x, level, msg, thrown);1122return null;1123};1124Function<String, String> nameProducer = (l) ->1125"log(Level." + l + ", \"" + msg + "\", thrown)";1126testJdkLog(logger, tester, check, nameProducer);1127}11281129public void testLogrb(java.lang.System.Logger logger,1130ResourceBundle bundle, String msg, Throwable thrown) {1131Checker<BackendRecord, Level> check = (res, l) -> {1132checkRecord("log", res, logger.getName(), l, () -> msg,1133adaptor().getCallerClassName(1134JdkLogMethodInvoker.LOGRB_STRING_THROWN,1135JdkLogMethodInvoker.class.getName()),1136adaptor().getCallerMethodName(1137JdkLogMethodInvoker.LOGRB_STRING_THROWN,1138"logX"), thrown, bundle);1139return null;1140};1141JdkLogTester tester = (x, level) -> {1142JdkLogMethodInvoker.LOGRB_STRING_THROWN.logX(x, level, bundle, msg, thrown);1143return null;1144};1145Function<String, String> nameProducer = (l) ->1146"log(Level." + l + ", bundle, \"" + msg + "\", thrown)";1147testJdkLog(logger, tester, check, nameProducer);1148}11491150public void testLog(java.lang.System.Logger logger, Supplier<String> msg) {1151Checker<BackendRecord, Level> check = (res, l) -> {1152checkRecord("log", res, logger.getName(), l, msg,1153adaptor().getCallerClassName(1154JdkLogMethodInvoker.LOG_SUPPLIER,1155JdkLogMethodInvoker.class.getName()),1156adaptor().getCallerMethodName(1157JdkLogMethodInvoker.LOG_SUPPLIER,1158"logX"), null, null);1159return null;1160};1161JdkLogTester tester = (x, level) -> {1162JdkLogMethodInvoker.LOG_SUPPLIER.logX(x, level, msg);1163return null;1164};1165Function<String, String> nameProducer = (l) ->1166"log(Level." + l + ", () -> \"" + msg.get() + "\")";1167testJdkLog(logger, tester, check, nameProducer);1168}11691170public void testLog(java.lang.System.Logger logger, Throwable thrown, Supplier<String> msg) {1171Checker<BackendRecord, Level> check = (res, l) -> {1172checkRecord("log", res, logger.getName(), l, msg,1173adaptor().getCallerClassName(1174JdkLogMethodInvoker.LOG_SUPPLIER_THROWN,1175JdkLogMethodInvoker.class.getName()),1176adaptor().getCallerMethodName(1177JdkLogMethodInvoker.LOG_SUPPLIER_THROWN,1178"logX"), thrown, null);1179return null;1180};1181JdkLogTester tester = (x, level) -> {1182JdkLogMethodInvoker.LOG_SUPPLIER_THROWN.logX(x, level, thrown, msg);1183return null;1184};1185Function<String, String> nameProducer = (l) ->1186"log(Level." + l + ", () -> \"" + msg.get() + "\", thrown)";1187testJdkLog(logger, tester, check, nameProducer);1188}11891190static Supplier<String> logpMessage(ResourceBundle bundle,1191String className, String methodName, Supplier<String> msg) {1192if (BEST_EFFORT_FOR_LOGP && bundle == null1193&& (className != null || methodName != null)) {1194final String cName = className == null ? "" : className;1195final String mName = methodName == null ? "" : methodName;1196return () -> {1197String m = msg.get();1198return String.format("[%s %s] %s", cName, mName, m == null ? "" : m);1199};1200} else {1201return msg;1202}1203}12041205public void testLogp(java.lang.System.Logger logger, String className,1206String methodName, String msg) {1207Checker<BackendRecord, Level> check = (res, l) -> {1208checkRecord("logp", res, logger.getName(), l,1209logpMessage(localized, className, methodName, () -> msg),1210adaptor().getCallerClassName(1211JdkLogMethodInvoker.LOGP_STRING, className),1212adaptor().getCallerClassName(1213JdkLogMethodInvoker.LOGP_STRING, methodName),1214null, localized);1215return null;1216};1217JdkLogTester tester = (x, level) -> {1218JdkLogMethodInvoker.LOGP_STRING.logX(x, level,1219className, methodName, msg);1220return null;1221};1222Function<String, String> nameProducer = (l) ->1223"logp(Level." + l + ", class, method, \"" + msg + "\")";1224testJdkLog(logger, tester, check, nameProducer);1225}12261227public void testLogrb(java.lang.System.Logger logger, String className,1228String methodName, ResourceBundle bundle, String msg) {1229Checker<BackendRecord, Level> check = (res, l) -> {1230checkRecord("logp", res, logger.getName(), l, () -> msg,1231adaptor().getCallerClassName(1232JdkLogMethodInvoker.LOGRBP_STRING_PARAMS, className),1233adaptor().getCallerClassName(1234JdkLogMethodInvoker.LOGRBP_STRING_PARAMS, methodName),1235null, bundle);1236return null;1237};1238JdkLogTester tester = (x, level) -> {1239JdkLogMethodInvoker.LOGRBP_STRING_PARAMS.logX(x, level,1240className, methodName, bundle, msg, (Object[])null);1241return null;1242};1243Function<String, String> nameProducer = (l) ->1244"logp(Level." + l + ", class, method, bundle, \"" + msg + "\")";1245testJdkLog(logger, tester, check, nameProducer);1246}12471248public void testLogp(java.lang.System.Logger logger, String className,1249String methodName, String msg, Object... params) {1250Checker<BackendRecord, Level> check = (res, l) -> {1251checkRecord("logp", res, logger.getName(), l,1252logpMessage(localized, className, methodName, () -> msg),1253adaptor().getCallerClassName(1254JdkLogMethodInvoker.LOGP_STRING_PARAMS, className),1255adaptor().getCallerClassName(1256JdkLogMethodInvoker.LOGP_STRING_PARAMS, methodName),1257null, localized, params);1258return null;1259};1260JdkLogTester tester = (x, level) -> {1261JdkLogMethodInvoker.LOGP_STRING_PARAMS.logX(x, level,1262className, methodName, msg, params);1263return null;1264};1265Function<String, String> nameProducer = (l) ->1266"log(Level." + l + ", class, method, \"" + msg + "\", params...)";1267testJdkLog(logger, tester, check, nameProducer);1268}12691270public void testLogrb(java.lang.System.Logger logger, String className,1271String methodName, ResourceBundle bundle, String msg,1272Object... params) {1273Checker<BackendRecord, Level> check = (res, l) -> {1274checkRecord("logp", res, logger.getName(), l, () -> msg,1275adaptor().getCallerClassName(1276JdkLogMethodInvoker.LOGRBP_STRING_PARAMS, className),1277adaptor().getCallerClassName(1278JdkLogMethodInvoker.LOGRBP_STRING_PARAMS, methodName),1279null, bundle, params);1280return null;1281};1282JdkLogTester tester = (x, level) -> {1283JdkLogMethodInvoker.LOGRBP_STRING_PARAMS.logX(x, level,1284className, methodName, bundle, msg, params);1285return null;1286};1287Function<String, String> nameProducer = (l) ->1288"log(Level." + l + ", class, method, bundle, \""1289+ msg + "\", params...)";1290testJdkLog(logger, tester, check, nameProducer);1291}12921293public void testLogp(java.lang.System.Logger logger, String className,1294String methodName, String msg, Throwable thrown) {1295Checker<BackendRecord, Level> check = (res, l) -> {1296checkRecord("log", res, logger.getName(), l,1297logpMessage(localized, className, methodName, () -> msg),1298adaptor().getCallerClassName(1299JdkLogMethodInvoker.LOGP_STRING_THROWN, className),1300adaptor().getCallerClassName(1301JdkLogMethodInvoker.LOGP_STRING_THROWN, methodName),1302thrown, localized);1303return null;1304};1305JdkLogTester tester = (x, level) -> {1306JdkLogMethodInvoker.LOGP_STRING_THROWN.logX(x, level,1307className, methodName, msg, thrown);1308return null;1309};1310Function<String, String> nameProducer = (l) ->1311"log(Level." + l + ", class, method, \"" + msg + "\", thrown)";1312testJdkLog(logger, tester, check, nameProducer);1313}13141315public void testLogrb(java.lang.System.Logger logger, String className,1316String methodName, ResourceBundle bundle,1317String msg, Throwable thrown) {1318Checker<BackendRecord, Level> check = (res, l) -> {1319checkRecord("log", res, logger.getName(), l, () -> msg,1320adaptor().getCallerClassName(1321JdkLogMethodInvoker.LOGRBP_STRING_THROWN, className),1322adaptor().getCallerClassName(1323JdkLogMethodInvoker.LOGRBP_STRING_THROWN, methodName),1324thrown, bundle);1325return null;1326};1327JdkLogTester tester = (x, level) -> {1328JdkLogMethodInvoker.LOGRBP_STRING_THROWN.logX(x, level,1329className, methodName, bundle, msg, thrown);1330return null;1331};1332Function<String, String> nameProducer = (l) ->1333"log(Level." + l + ", class, method, bundle, \"" + msg + "\", thrown)";1334testJdkLog(logger, tester, check, nameProducer);13351336}13371338public void testLogp(java.lang.System.Logger logger, String className,1339String methodName, Supplier<String> msg) {1340Checker<BackendRecord, Level> check = (res, l) -> {1341checkRecord("log", res, logger.getName(), l,1342logpMessage(null, className, methodName, msg),1343adaptor().getCallerClassName(1344JdkLogMethodInvoker.LOGP_SUPPLIER, className),1345adaptor().getCallerClassName(1346JdkLogMethodInvoker.LOGP_SUPPLIER, methodName),1347null, null);1348return null;1349};1350JdkLogTester tester = (x, level) -> {1351JdkLogMethodInvoker.LOGP_SUPPLIER.logX(x, level,1352className, methodName, msg);1353return null;1354};1355Function<String, String> nameProducer = (l) ->1356"log(Level." + l + ", class, method, () -> \"" + msg.get() + "\")";1357testJdkLog(logger, tester, check, nameProducer);1358}13591360public void testLogp(java.lang.System.Logger logger, String className,1361String methodName, Throwable thrown, Supplier<String> msg) {1362Checker<BackendRecord, Level> check = (res, l) -> {1363checkRecord("log", res, logger.getName(), l,1364logpMessage(null, className, methodName, msg),1365adaptor().getCallerClassName(1366JdkLogMethodInvoker.LOGP_SUPPLIER_THROWN, className),1367adaptor().getCallerClassName(1368JdkLogMethodInvoker.LOGP_SUPPLIER_THROWN, methodName),1369thrown, null);1370return null;1371};1372JdkLogTester tester = (x, level) -> {1373JdkLogMethodInvoker.LOGP_SUPPLIER_THROWN.logX(x, level,1374className, methodName, thrown, msg);1375return null;1376};1377Function<String, String> nameProducer = (l) ->1378"log(Level." + l + ", class, method, () -> \"" + msg.get() + "\", thrown)";1379testJdkLog(logger, tester, check, nameProducer);1380}13811382private void testJdkLog(java.lang.System.Logger logger,1383JdkLogTester log, Checker<BackendRecord,Level> check,1384Function<String, String> nameProducer) {1385if (restrictedTo != null) {1386if (!bridgeLoggerClass.isAssignableFrom(restrictedTo)) {1387if (VERBOSE) {1388System.out.println("Skipping method from "1389+ bridgeLoggerClass);1390}1391return;1392}1393}1394System.out.println("Testing Logger." + nameProducer.apply("*")1395+ " on " + logger);1396final BackendAdaptor adaptor = adaptor();1397for (Level loggerLevel : LEVELS) {1398adaptor.setLevel(logger, loggerLevel);1399for (Level l : LEVELS) {1400check(logger, () -> log.apply(bridgeLoggerClass.cast(logger), l),1401check, () -> adaptor.isLoggable(logger, l),1402() -> adaptor.shouldBeLoggable(l, loggerLevel),1403l, loggerLevel, nameProducer.apply(l.toString()));1404}1405}1406}14071408private void testSpiLog(java.lang.System.Logger logger,1409SpiLogTester log, Checker<BackendRecord, java.lang.System.Logger.Level> check,1410Function<String, String> nameProducer) {1411System.out.println("Testing System.Logger." + nameProducer.apply("*")1412+ " on " + logger);1413final BackendAdaptor adaptor = adaptor();1414for (java.lang.System.Logger.Level loggerLevel : java.lang.System.Logger.Level.values()) {14151416adaptor.setLevel(logger, loggerLevel);1417for (java.lang.System.Logger.Level l : java.lang.System.Logger.Level.values()) {1418check(logger, () -> log.apply(logger, l),1419check, () -> logger.isLoggable(l),1420() -> adaptor.shouldBeLoggable(l, loggerLevel),1421l, loggerLevel, nameProducer.apply(l.toString()));1422}1423}1424}14251426private void test(String args, Levels level, java.lang.System.Logger logger,1427Runnable test, Checker<BackendRecord, Level> check) {1428if (restrictedTo != null) {1429if (!level.definingClass.isAssignableFrom(restrictedTo)) {1430if (VERBOSE) {1431System.out.println("Skipping method from "1432+ level.definingClass);1433}1434return;1435}1436}1437String method = args.contains("bundle") ? "logrb" : "log";1438System.out.println("Testing Logger."1439+ method + "(Level." + level.platformLevel1440+ ", "+ args + ")" + " on " + logger);1441final BackendAdaptor adaptor = adaptor();1442for (Level loggerLevel : LEVELS) {1443adaptor.setLevel(logger, loggerLevel);1444check(logger, test, check,1445() -> level.isEnabled(logger),1446() -> adaptor.shouldBeLoggable(level, loggerLevel),1447level.platformLevel, loggerLevel, level.method);1448}1449}14501451private <L> void check(java.lang.System.Logger logger,1452Runnable test, Checker<BackendRecord,L> check,1453BooleanSupplier checkLevelEnabled,1454BooleanSupplier shouldBeLoggable,1455L logLevel, L loggerLevel, String logMethod) {1456final BackendAdaptor adaptor = adaptor();1457adaptor.resetBackendRecords();1458test.run();1459final List<BackendRecord> records = adaptor.getBackendRecords();1460if (shouldBeLoggable.getAsBoolean()) {1461if (!checkLevelEnabled.getAsBoolean()) {1462throw new RuntimeException("Logger is not enabled for "1463+ logMethod1464+ " although logger level is " + loggerLevel);1465}1466if (records.size() != 1) {1467throw new RuntimeException(loggerLevel + " [" +1468logLevel + "] : Unexpected record sizes: "1469+ records.toString());1470}1471BackendRecord res = records.get(0);1472check.apply(res, logLevel);1473} else {1474if (checkLevelEnabled.getAsBoolean()) {1475throw new RuntimeException("Logger is enabled for "1476+ logMethod1477+ " although logger level is " + loggerLevel);1478}1479if (!records.isEmpty()) {1480throw new RuntimeException(loggerLevel + " [" +1481logLevel + "] : Unexpected record sizes: "1482+ records.toString());1483}1484}1485}1486}14871488public static class JULBackendTester extends BackendTester<LogRecord>{14891490public JULBackendTester(boolean isSystem) {1491this(isSystem,null,null);1492}1493public JULBackendTester(boolean isSystem, ResourceBundle localized) {1494this(isSystem,null,localized);1495}1496public JULBackendTester(boolean isSystem,1497Class<? extends java.lang.System.Logger> restrictedTo) {1498this(isSystem, restrictedTo, null);1499}1500public JULBackendTester(boolean isSystem,1501Class<? extends java.lang.System.Logger> restrictedTo,1502ResourceBundle localized) {1503super(isSystem, restrictedTo, localized);1504}15051506Logger getBackendLogger(String name) {1507if (isSystem) {1508return LoggingProviderImpl.getLogManagerAccess().demandLoggerFor(1509LogManager.getLogManager(), name, Thread.class.getModule());1510} else {1511return Logger.getLogger(name);1512}1513}15141515class JULBackendAdaptor extends BackendAdaptor {1516@Override1517public String getLoggerName(LogRecord res) {1518return res.getLoggerName();1519}1520@Override1521public Level getLevel(LogRecord res) {1522return Level.valueOf(res.getLevel().getName());1523}1524@Override1525public String getMessage(LogRecord res) {1526return res.getMessage();1527}1528@Override1529public String getSourceClassName(LogRecord res) {1530return res.getSourceClassName();1531}1532@Override1533public String getSourceMethodName(LogRecord res) {1534return res.getSourceMethodName();1535}1536@Override1537public Throwable getThrown(LogRecord res) {1538return res.getThrown();1539}1540@Override1541public ResourceBundle getResourceBundle(LogRecord res) {1542return res.getResourceBundle();1543}1544@Override1545public void setLevel(java.lang.System.Logger logger, Level level) {1546Logger backend = getBackendLogger(logger.getName());1547backend.setLevel(java.util.logging.Level.parse(level.name()));1548}1549@Override1550public void setLevel(java.lang.System.Logger logger, java.lang.System.Logger.Level level) {1551setLevel(logger, toJUL(level));1552}1553@Override1554public List<LogRecord> getBackendRecords() {1555return handler.records;1556}1557@Override1558public void resetBackendRecords() {1559handler.reset();1560}1561@Override1562public Level getMappedLevel(Object level) {1563if (level instanceof java.lang.System.Logger.Level) {1564return toJUL((java.lang.System.Logger.Level)level);1565}1566return (Level)level;1567}1568}15691570final JULBackendAdaptor julAdaptor = new JULBackendAdaptor();15711572@Override1573BackendAdaptor adaptor() {1574return julAdaptor;1575}15761577}15781579public abstract static class BackendTesterFactory {1580public abstract BackendTester createBackendTester(boolean isSystem);1581public abstract BackendTester createBackendTester(boolean isSystem,1582Class<? extends java.lang.System.Logger> restrictedTo);1583public abstract BackendTester createBackendTester(boolean isSystem,1584Class<? extends java.lang.System.Logger> restrictedTo,1585ResourceBundle bundle);1586public abstract BackendTester createBackendTester(boolean isSystem,1587ResourceBundle bundle);1588}15891590public static class JULBackendTesterFactory extends BackendTesterFactory {15911592@Override1593public BackendTester createBackendTester(boolean isSystem) {1594return new JULBackendTester(isSystem);1595}15961597@Override1598public BackendTester createBackendTester(boolean isSystem,1599Class<? extends java.lang.System.Logger> restrictedTo) {1600return new JULBackendTester(isSystem, restrictedTo);1601}16021603@Override1604public BackendTester createBackendTester(boolean isSystem,1605Class<? extends java.lang.System.Logger> restrictedTo,1606ResourceBundle bundle) {1607return new JULBackendTester(isSystem, restrictedTo, bundle);1608}16091610@Override1611public BackendTester createBackendTester(boolean isSystem,1612ResourceBundle bundle) {1613return new JULBackendTester(isSystem, bundle);1614}1615}16161617public static class CustomLoggerFinder extends LoggerFinder {16181619static enum CustomLevel { OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE, ALL };1620static CustomLevel[] customLevelMap = { CustomLevel.ALL,1621CustomLevel.TRACE, CustomLevel.DEBUG, CustomLevel.INFO,1622CustomLevel.WARN, CustomLevel.ERROR, CustomLevel.OFF1623};1624static class CustomLogRecord {1625public final CustomLevel logLevel;1626public final java.lang.System.Logger logger;1627public final String msg;1628public final Object[] params;1629public final Throwable thrown;1630public final ResourceBundle bundle;16311632CustomLogRecord(java.lang.System.Logger producer,1633CustomLevel level, String msg) {1634this(producer, level, msg, (ResourceBundle)null, (Throwable)null, (Object[])null);1635}16361637CustomLogRecord(java.lang.System.Logger producer,1638CustomLevel level, String msg, ResourceBundle bundle,1639Throwable thrown, Object... params) {1640this.logger = producer;1641this.logLevel = level;1642this.msg = msg;1643this.params = params;1644this.thrown = thrown;1645this.bundle = bundle;1646}1647}16481649static final List<CustomLogRecord> records =1650Collections.synchronizedList(new ArrayList<>());16511652static class CustomLogger implements java.lang.System.Logger {16531654final String name;1655volatile CustomLevel level;1656CustomLogger(String name) {1657this.name = name;1658this.level = CustomLevel.INFO;1659}16601661@Override1662public String getName() {1663return name;1664}16651666public void setLevel(CustomLevel level) {1667this.level = level;1668}166916701671@Override1672public boolean isLoggable(java.lang.System.Logger.Level level) {16731674return this.level != CustomLevel.OFF && this.level.ordinal()1675>= customLevelMap[level.ordinal()].ordinal();1676}16771678@Override1679public void log(java.lang.System.Logger.Level level, ResourceBundle bundle, String key, Throwable thrown) {1680if (isLoggable(level)) {1681records.add(new CustomLogRecord(this, customLevelMap[level.ordinal()],1682key, bundle, thrown));1683}1684}16851686@Override1687public void log(java.lang.System.Logger.Level level, ResourceBundle bundle, String format, Object... params) {1688if (isLoggable(level)) {1689records.add(new CustomLogRecord(this, customLevelMap[level.ordinal()],1690format, bundle, null, params));1691}1692}16931694}16951696final Map<String, java.lang.System.Logger> applicationLoggers =1697Collections.synchronizedMap(new HashMap<>());1698final Map<String, java.lang.System.Logger> systemLoggers =1699Collections.synchronizedMap(new HashMap<>());17001701@Override1702public java.lang.System.Logger getLogger(String name, Module caller) {1703ClassLoader callerLoader = caller.getClassLoader();1704if (callerLoader == null) {1705systemLoggers.putIfAbsent(name, new CustomLogger(name));1706return systemLoggers.get(name);1707} else {1708applicationLoggers.putIfAbsent(name, new CustomLogger(name));1709return applicationLoggers.get(name);1710}1711}17121713CustomLevel fromJul(Level level) {1714if (level.intValue() == Level.OFF.intValue()) {1715return CustomLevel.OFF;1716} else if (level.intValue() > Level.SEVERE.intValue()) {1717return CustomLevel.ERROR;1718} else if (level.intValue() > Level.WARNING.intValue()) {1719return CustomLevel.ERROR;1720} else if (level.intValue() > Level.INFO.intValue()) {1721return CustomLevel.WARN;1722} else if (level.intValue() > Level.CONFIG.intValue()) {1723return CustomLevel.INFO;1724} else if (level.intValue() > Level.FINER.intValue()) {1725return CustomLevel.DEBUG;1726} else if (level.intValue() > Level.FINEST.intValue()) {1727return CustomLevel.TRACE;1728} else if (level.intValue() == Level.ALL.intValue()) {1729return CustomLevel.ALL;1730} else {1731return CustomLevel.TRACE;1732}1733}17341735Level toJul(CustomLevel level) {1736switch(level) {1737case OFF: return Level.OFF;1738case FATAL: return Level.SEVERE;1739case ERROR: return Level.SEVERE;1740case WARN: return Level.WARNING;1741case INFO: return Level.INFO;1742case DEBUG: return Level.FINE;1743case TRACE: return Level.FINER;1744case ALL: return Level.ALL;1745default: throw new InternalError("No such level: "+level);1746}1747}17481749}17501751public static class CustomBackendTester extends1752BackendTester<CustomLoggerFinder.CustomLogRecord> {17531754public final CustomLoggerFinder provider;17551756public CustomBackendTester(boolean isSystem) {1757this(isSystem, null, null);1758}17591760public CustomBackendTester(boolean isSystem,1761Class<? extends java.lang.System.Logger> restrictedTo) {1762this(isSystem, restrictedTo, null);1763}17641765public CustomBackendTester(boolean isSystem,1766ResourceBundle localized) {1767this(isSystem, null, localized);1768}17691770public CustomBackendTester(boolean isSystem,1771Class<? extends java.lang.System.Logger> restrictedTo,1772ResourceBundle localized) {1773super(isSystem, restrictedTo, localized);1774provider = (CustomLoggerFinder)java.lang.System.LoggerFinder.getLoggerFinder();1775}17761777@Override1778public java.lang.System.Logger convert(java.lang.System.Logger logger) {1779if (restrictedTo != null && restrictedTo.isInstance(logger)) {1780return logger;1781} else if (restrictedTo == jdkLoggerClass) {1782return logger;1783} else {1784return java.lang.System.Logger.class.cast(1785sun.util.logging.PlatformLogger.Bridge.convert(logger));1786}1787}17881789class CustomBackendAdaptor extends BackendAdaptor {17901791@Override1792public String getLoggerName(CustomLoggerFinder.CustomLogRecord res) {1793return res.logger.getName();1794}17951796@Override1797public CustomLoggerFinder.CustomLevel getLevel(CustomLoggerFinder.CustomLogRecord res) {1798return res.logLevel;1799}18001801@Override1802public String getMessage(CustomLoggerFinder.CustomLogRecord res) {1803return res.msg;1804}18051806@Override // we don't support source class name in our custom provider implementation1807public String getSourceClassName(CustomLoggerFinder.CustomLogRecord res) {1808return null;1809}18101811@Override // we don't support source method name in our custom provider implementation1812public String getSourceMethodName(CustomLoggerFinder.CustomLogRecord res) {1813return null;1814}18151816@Override1817public Throwable getThrown(CustomLoggerFinder.CustomLogRecord res) {1818return res.thrown;1819}18201821@Override1822public ResourceBundle getResourceBundle(CustomLoggerFinder.CustomLogRecord res) {1823return res.bundle;1824}18251826@Override1827public void setLevel(java.lang.System.Logger logger, Level level) {1828final CustomLoggerFinder.CustomLogger l =1829(CustomLoggerFinder.CustomLogger)1830(isSystem ? provider.getLogger(logger.getName(), Thread.class.getModule()) :1831provider.getLogger(logger.getName(), LoggerFinderBackendTest.class.getModule()));1832l.setLevel(provider.fromJul(level));1833}1834@Override1835public void setLevel(java.lang.System.Logger logger,1836java.lang.System.Logger.Level level) {1837setLevel(logger, toJUL(level));1838}18391840CustomLoggerFinder.CustomLevel getLevel(java.lang.System.Logger logger) {1841final CustomLoggerFinder.CustomLogger l =1842(CustomLoggerFinder.CustomLogger)1843(isSystem ? provider.getLogger(logger.getName(), Thread.class.getModule()) :1844provider.getLogger(logger.getName(), LoggerFinderBackendTest.class.getModule()));1845return l.level;1846}18471848@Override1849public List<CustomLoggerFinder.CustomLogRecord> getBackendRecords() {1850return CustomLoggerFinder.records;1851}18521853@Override1854public void resetBackendRecords() {1855CustomLoggerFinder.records.clear();1856}18571858@Override1859public boolean shouldBeLoggable(Levels level, Level loggerLevel) {1860return loggerLevel != Level.OFF &&1861fromLevels(level).ordinal() <= provider.fromJul(loggerLevel).ordinal();1862}18631864@Override1865public boolean isLoggable(java.lang.System.Logger logger, Level l) {1866return super.isLoggable(logger, l);1867}18681869@Override1870public boolean shouldBeLoggable(Level logLevel, Level loggerLevel) {1871return loggerLevel != Level.OFF &&1872provider.fromJul(logLevel).ordinal() <= provider.fromJul(loggerLevel).ordinal();1873}18741875@Override // we don't support source class name in our custom provider implementation1876public String getCallerClassName(Levels level, String clazz) {1877return null;1878}18791880@Override // we don't support source method name in our custom provider implementation1881public String getCallerMethodName(Levels level, String method) {1882return null;1883}18841885@Override // we don't support source class name in our custom provider implementation1886public String getCallerClassName(MethodInvoker<?,?> logMethod, String clazz) {1887return null;1888}18891890@Override // we don't support source method name in our custom provider implementation1891public String getCallerMethodName(MethodInvoker<?,?> logMethod, String method) {1892return null;1893}18941895@Override1896public CustomLoggerFinder.CustomLevel getMappedLevel(Object level) {1897if (level instanceof java.lang.System.Logger.Level) {1898final int index = ((java.lang.System.Logger.Level)level).ordinal();1899return CustomLoggerFinder.customLevelMap[index];1900} else if (level instanceof Level) {1901return provider.fromJul((Level)level);1902}1903return (CustomLoggerFinder.CustomLevel) level;1904}19051906CustomLoggerFinder.CustomLevel fromLevels(Levels level) {1907switch(level) {1908case SEVERE:1909return CustomLoggerFinder.CustomLevel.ERROR;1910case WARNING:1911return CustomLoggerFinder.CustomLevel.WARN;1912case INFO:1913return CustomLoggerFinder.CustomLevel.INFO;1914case CONFIG: case FINE:1915return CustomLoggerFinder.CustomLevel.DEBUG;1916case FINER: case FINEST:1917return CustomLoggerFinder.CustomLevel.TRACE;1918}1919throw new InternalError("No such level "+level);1920}19211922}19231924@Override1925BackendAdaptor adaptor() {1926return new CustomBackendAdaptor();1927}19281929}19301931public static class CustomBackendTesterFactory extends BackendTesterFactory {19321933@Override1934public BackendTester createBackendTester(boolean isSystem) {1935return new CustomBackendTester(isSystem);1936}19371938@Override1939public BackendTester createBackendTester(boolean isSystem,1940Class<? extends java.lang.System.Logger> restrictedTo) {1941return new CustomBackendTester(isSystem, restrictedTo);1942}19431944@Override1945public BackendTester createBackendTester(boolean isSystem,1946Class<? extends java.lang.System.Logger> restrictedTo,1947ResourceBundle bundle) {1948return new CustomBackendTester(isSystem, restrictedTo, bundle);1949}19501951@Override1952public BackendTester createBackendTester(boolean isSystem,1953ResourceBundle bundle) {1954return new CustomBackendTester(isSystem, bundle);1955}1956}19571958static final Method getLazyLogger;1959static final Method accessLoggerFinder;1960static {1961// jdk.internal.logger.LazyLoggers.getLazyLogger(name, caller);1962try {1963Class<?> lazyLoggers = jdk.internal.logger.LazyLoggers.class;1964getLazyLogger = lazyLoggers.getMethod("getLazyLogger",1965String.class, Module.class);1966getLazyLogger.setAccessible(true);1967Class<?> loggerFinderLoader =1968Class.forName("java.lang.System$LoggerFinder");1969accessLoggerFinder = loggerFinderLoader.getDeclaredMethod("accessProvider");1970accessLoggerFinder.setAccessible(true);1971} catch (Throwable ex) {1972throw new ExceptionInInitializerError(ex);1973}1974}19751976static java.lang.System.Logger getSystemLogger(String name, Module caller) throws Exception {1977try {1978return java.lang.System.Logger.class.cast(getLazyLogger.invoke(null, name, caller));1979} catch (InvocationTargetException x) {1980Throwable t = x.getTargetException();1981if (t instanceof Exception) {1982throw (Exception)t;1983} else {1984throw (Error)t;1985}1986}1987}1988static java.lang.System.Logger getSystemLogger(String name,1989ResourceBundle bundle, Module caller) throws Exception {1990try {1991LoggerFinder provider = LoggerFinder.class.cast(accessLoggerFinder.invoke(null));1992return provider.getLocalizedLogger(name, bundle, caller);1993} catch (InvocationTargetException x) {1994Throwable t = x.getTargetException();1995if (t instanceof Exception) {1996throw (Exception)t;1997} else {1998throw (Error)t;1999}2000}2001}20022003// Change this to 'true' to get more traces...2004public static boolean verbose = false;20052006public static void main(String[] argv) throws Exception {20072008final AtomicInteger nb = new AtomicInteger(0);2009final boolean hidesProvider = Boolean.getBoolean("test.logger.hidesProvider");2010System.out.println(ClassLoader.getSystemClassLoader());2011final BackendTesterFactory factory;2012if (java.lang.System.LoggerFinder.getLoggerFinder() instanceof CustomLoggerFinder) {2013if (hidesProvider) {2014System.err.println("Custom backend "2015+ java.lang.System.LoggerFinder.getLoggerFinder()2016+ " should have been hidden!");2017throw new RuntimeException(2018"Custom backend should have been hidden: "2019+ "check value of java.system.class.loader property");2020}2021System.out.println("Using custom backend");2022factory = new CustomBackendTesterFactory();2023} else {2024if (!hidesProvider) {2025System.err.println("Default JUL backend "2026+ java.lang.System.LoggerFinder.getLoggerFinder()2027+ " should have been hidden!");2028throw new RuntimeException(2029"Default JUL backend should have been hidden: "2030+ "check value of java.system.class.loader property");2031}2032System.out.println("Using JUL backend");2033factory = new JULBackendTesterFactory();2034}20352036testBackend(nb, factory);2037}20382039public static void testBackend(AtomicInteger nb, BackendTesterFactory factory) throws Exception {20402041// Tests all level specifics methods with loggers configured with2042// all possible levels and loggers obtained with all possible2043// entry points from LoggerFactory and JdkLoggerFactory, with2044// JUL as backend.20452046// Test a simple application logger with JUL backend2047final BackendTester tester = factory.createBackendTester(false);2048final java.lang.System.Logger logger =2049java.lang.System.LoggerFinder.getLoggerFinder()2050.getLogger("foo", LoggerFinderBackendTest.class.getModule());20512052testLogger(tester, logger, nb);20532054// Test a simple system logger with JUL backend2055final java.lang.System.Logger system =2056java.lang.System.LoggerFinder.getLoggerFinder()2057.getLogger("bar", Thread.class.getModule());2058final BackendTester systemTester = factory.createBackendTester(true);2059testLogger(systemTester, system, nb);20602061// Test a localized application logger with null resource bundle and2062// JUL backend2063final java.lang.System.Logger noBundleLogger =2064java.lang.System.LoggerFinder.getLoggerFinder()2065.getLocalizedLogger("baz", null, LoggerFinderBackendTest.class.getModule());2066final BackendTester noBundleTester =2067factory.createBackendTester(false, spiLoggerClass);2068testLogger(noBundleTester, noBundleLogger, nb);20692070// Test a localized system logger with null resource bundle and JUL2071// backend2072final java.lang.System.Logger noBundleSysLogger =2073java.lang.System.LoggerFinder.getLoggerFinder()2074.getLocalizedLogger("oof", null, Thread.class.getModule());2075final BackendTester noBundleSysTester =2076factory.createBackendTester(true, spiLoggerClass);2077testLogger(noBundleSysTester, noBundleSysLogger, nb);20782079// Test a localized application logger with null resource bundle and2080// JUL backend2081try {2082System.getLogger("baz", null);2083throw new RuntimeException("Expected NullPointerException not thrown");2084} catch (NullPointerException x) {2085System.out.println("System.Loggers.getLogger(\"baz\", null): got expected " + x);2086}2087final java.lang.System.Logger noBundleExtensionLogger =2088getSystemLogger("baz", null, LoggerFinderBackendTest.class.getModule());2089final BackendTester noBundleExtensionTester =2090factory.createBackendTester(false, jdkLoggerClass);2091testLogger(noBundleExtensionTester, noBundleExtensionLogger, nb);20922093// Test a simple system logger with JUL backend2094final java.lang.System.Logger sysExtensionLogger =2095getSystemLogger("oof", Thread.class.getModule());2096final BackendTester sysExtensionTester =2097factory.createBackendTester(true, jdkLoggerClass);2098testLogger(sysExtensionTester, sysExtensionLogger, nb);20992100// Test a localized system logger with null resource bundle and JUL2101// backend2102final java.lang.System.Logger noBundleSysExtensionLogger =2103getSystemLogger("oof", null, Thread.class.getModule());2104final BackendTester noBundleSysExtensionTester =2105factory.createBackendTester(true, jdkLoggerClass);2106testLogger(noBundleSysExtensionTester, noBundleSysExtensionLogger, nb);21072108// Test a localized application logger converted to JDK with null2109// resource bundle and JUL backend2110final java.lang.System.Logger noBundleConvertedLogger =2111(java.lang.System.Logger)2112sun.util.logging.PlatformLogger.Bridge.convert(noBundleLogger);2113final BackendTester noBundleJdkTester = factory.createBackendTester(false);2114testLogger(noBundleJdkTester, noBundleConvertedLogger, nb);21152116// Test a localized system logger converted to JDK with null resource2117// bundle and JUL backend2118final java.lang.System.Logger noBundleConvertedSysLogger =2119(java.lang.System.Logger)2120sun.util.logging.PlatformLogger.Bridge.convert(noBundleSysLogger);2121final BackendTester noBundleJdkSysTester = factory.createBackendTester(true);2122testLogger(noBundleJdkSysTester, noBundleConvertedSysLogger, nb);21232124// Test a localized application logger with resource bundle and JUL2125// backend2126final ResourceBundle bundle =2127ResourceBundle.getBundle(ResourceBundeLocalized.class.getName());2128final java.lang.System.Logger bundleLogger =2129java.lang.System.LoggerFinder.getLoggerFinder()2130.getLocalizedLogger("toto", bundle, LoggerFinderBackendTest.class.getModule());2131final BackendTester bundleTester =2132factory.createBackendTester(false, spiLoggerClass, bundle);2133testLogger(bundleTester, bundleLogger, nb);21342135// Test a localized system logger with resource bundle and JUL backend2136final java.lang.System.Logger bundleSysLogger =2137java.lang.System.LoggerFinder.getLoggerFinder()2138.getLocalizedLogger("titi", bundle, Thread.class.getModule());2139final BackendTester bundleSysTester =2140factory.createBackendTester(true, spiLoggerClass, bundle);2141testLogger(bundleSysTester, bundleSysLogger, nb);21422143// Test a localized Jdk application logger with resource bundle and JUL2144// backend2145final java.lang.System.Logger bundleExtensionLogger =2146System.getLogger("tita", bundle);2147final BackendTester bundleExtensionTester =2148factory.createBackendTester(false, jdkLoggerClass, bundle);2149testLogger(bundleExtensionTester, bundleExtensionLogger, nb);21502151// Test a localized Jdk system logger with resource bundle and JUL2152// backend2153final java.lang.System.Logger bundleExtensionSysLogger =2154getSystemLogger("titu", bundle, Thread.class.getModule());2155final BackendTester bundleExtensionSysTester =2156factory.createBackendTester(true, jdkLoggerClass, bundle);2157testLogger(bundleExtensionSysTester, bundleExtensionSysLogger, nb);21582159// Test a localized application logger converted to JDK with resource2160// bundle and JUL backend2161final BackendTester bundleJdkTester =2162factory.createBackendTester(false, bundle);2163final java.lang.System.Logger bundleConvertedLogger =2164(java.lang.System.Logger)2165sun.util.logging.PlatformLogger.Bridge.convert(bundleLogger);2166testLogger(bundleJdkTester, bundleConvertedLogger, nb);21672168// Test a localized Jdk system logger converted to JDK with resource2169// bundle and JUL backend2170final BackendTester bundleJdkSysTester =2171factory.createBackendTester(true, bundle);2172final java.lang.System.Logger bundleConvertedSysLogger =2173(java.lang.System.Logger)2174sun.util.logging.PlatformLogger.Bridge.convert(bundleSysLogger);2175testLogger(bundleJdkSysTester, bundleConvertedSysLogger, nb);21762177// Now need to add tests for all the log/logp/logrb methods...21782179}21802181private static class FooObj {2182final String s;2183FooObj(String s) {2184this.s = s;2185}21862187@Override2188public String toString() {2189return super.toString() +": "+s;2190}21912192}21932194public static void testLogger(BackendTester tester,2195java.lang.System.Logger spiLogger, AtomicInteger nb) {21962197// Test all level-specific method forms:2198// fatal(...) error(...) severe(...) etc...2199java.lang.System.Logger jdkLogger = tester.convert(spiLogger);2200for (Levels l : Levels.values()) {2201java.lang.System.Logger logger =2202l.definingClass.equals(spiLoggerClass) ? spiLogger : jdkLogger;2203tester.testLevel(l, logger, l.method + "[" + logger.getName()+ "]-"2204+ nb.incrementAndGet());2205tester.testLevel(l, logger, l.method + "[" + logger.getName()+ "]-"2206+ nb.incrementAndGet(),2207bundleParam);2208final int nbb = nb.incrementAndGet();2209tester.testLevel(l, logger, () -> l.method + "[" + logger.getName()2210+ "]-" + nbb);2211}2212for (Levels l : Levels.values()) {2213java.lang.System.Logger logger =2214l.definingClass.equals(spiLoggerClass) ? spiLogger : jdkLogger;2215tester.testLevel(l, logger,2216l.method + "[" + logger.getName()+ "]({0},{1})-"2217+ nb.incrementAndGet(),2218"One", "Two");2219tester.testLevel(l, logger,2220l.method + "[" + logger.getName()+ "]({0},{1})-"2221+ nb.incrementAndGet(),2222bundleParam, "One", "Two");2223}2224final Throwable thrown = new RuntimeException("Test");2225for (Levels l : Levels.values()) {2226java.lang.System.Logger logger =2227l.definingClass.equals(spiLoggerClass) ? spiLogger : jdkLogger;2228tester.testLevel(l, logger, l.method + "[" + logger.getName()+ "]-"2229+ nb.incrementAndGet(),2230thrown);2231tester.testLevel(l, logger, l.method + "[" + logger.getName()+ "]-"2232+ nb.incrementAndGet(),2233bundleParam, thrown);2234final int nbb = nb.incrementAndGet();2235tester.testLevel(l, logger, ()->l.method + "[" + logger.getName()+ "]-"2236+ nbb, thrown);2237}22382239java.lang.System.Logger logger = jdkLogger;22402241// test System.Logger methods2242tester.testSpiLog(logger, "[" + logger.getName()+ "]-"2243+ nb.incrementAndGet());2244tester.testSpiLog(logger, bundleParam, "[" + logger.getName()+ "]-"2245+ nb.incrementAndGet());2246tester.testSpiLog(logger, "[" + logger.getName()+ "]-({0},{1})"2247+ nb.incrementAndGet(), "One", "Two");2248tester.testSpiLog(logger, bundleParam, "[" + logger.getName()+ "]-({0},{1})"2249+ nb.incrementAndGet(), "One", "Two");2250tester.testSpiLog(logger, "[" + logger.getName()+ "]-"2251+ nb.incrementAndGet(), thrown);2252tester.testSpiLog(logger, bundleParam, "[" + logger.getName()+ "]-"2253+ nb.incrementAndGet(), thrown);2254final int nbb01 = nb.incrementAndGet();2255tester.testSpiLog(logger, () -> "[" + logger.getName()+ "]-" + nbb01);2256final int nbb02 = nb.incrementAndGet();2257tester.testSpiLog(logger, thrown, () -> "[" + logger.getName()+ "]-" + nbb02);2258final int nbb03 = nb.incrementAndGet();2259tester.testSpiLog(logger, new FooObj("[" + logger.getName()+ "]-" + nbb03));22602261// Test all log method forms:2262// jdk.internal.logging.Logger.log(...)2263tester.testLog(logger, "[" + logger.getName()+ "]-"2264+ nb.incrementAndGet());2265tester.testLogrb(logger, bundleParam, "[" + logger.getName()+ "]-"2266+ nb.incrementAndGet());2267tester.testLog(logger, "[" + logger.getName()+ "]-({0},{1})"2268+ nb.incrementAndGet(), "One", "Two");2269tester.testLogrb(logger, bundleParam, "[" + logger.getName()+ "]-({0},{1})"2270+ nb.incrementAndGet(), "One", "Two");2271tester.testLog(logger, "[" + logger.getName()+ "]-"2272+ nb.incrementAndGet(), thrown);2273tester.testLogrb(logger, bundleParam, "[" + logger.getName()+ "]-"2274+ nb.incrementAndGet(), thrown);2275final int nbb1 = nb.incrementAndGet();2276tester.testLog(logger, () -> "[" + logger.getName()+ "]-" + nbb1);2277final int nbb2 = nb.incrementAndGet();2278tester.testLog(logger, thrown, () -> "[" + logger.getName()+ "]-" + nbb2);22792280// Test all logp method forms2281// jdk.internal.logging.Logger.logp(...)2282tester.testLogp(logger, "clazz" + nb.incrementAndGet(),2283"method" + nb.incrementAndGet(),2284"[" + logger.getName()+ "]-"2285+ nb.incrementAndGet());2286tester.testLogrb(logger, "clazz" + nb.incrementAndGet(),2287"method" + nb.incrementAndGet(), bundleParam,2288"[" + logger.getName()+ "]-"2289+ nb.incrementAndGet());2290tester.testLogp(logger, "clazz" + nb.incrementAndGet(),2291"method" + nb.incrementAndGet(),2292"[" + logger.getName()+ "]-({0},{1})"2293+ nb.incrementAndGet(), "One", "Two");2294tester.testLogrb(logger, "clazz" + nb.incrementAndGet(),2295"method" + nb.incrementAndGet(), bundleParam,2296"[" + logger.getName()+ "]-({0},{1})"2297+ nb.incrementAndGet(), "One", "Two");2298tester.testLogp(logger, "clazz" + nb.incrementAndGet(),2299"method" + nb.incrementAndGet(),2300"[" + logger.getName()+ "]-"2301+ nb.incrementAndGet(), thrown);2302tester.testLogrb(logger, "clazz" + nb.incrementAndGet(),2303"method" + nb.incrementAndGet(), bundleParam,2304"[" + logger.getName()+ "]-"2305+ nb.incrementAndGet(), thrown);2306final int nbb3 = nb.incrementAndGet();2307tester.testLogp(logger, "clazz" + nb.incrementAndGet(),2308"method" + nb.incrementAndGet(),2309() -> "[" + logger.getName()+ "]-" + nbb3);2310final int nbb4 = nb.incrementAndGet();2311tester.testLogp(logger, "clazz" + nb.incrementAndGet(),2312"method" + nb.incrementAndGet(),2313thrown, () -> "[" + logger.getName()+ "]-" + nbb4);2314}23152316}231723182319