1 /* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /** 25 * @test 26 * @bug 8140364 27 * @author danielfuchs 28 * @summary JDK implementation specific unit test for JDK internal artifacts. 29 * This test tests all the public API methods defined in the {@link 30 * java.lang.System.Logger} interface, as well as all the JDK 31 * internal methods defined in the 32 * {@link sun.util.logging.PlatformLogger.Bridge} 33 * interface, with loggers returned by {@link 34 * java.lang.System.LoggerFinder#getLogger(java.lang.String, java.lang.Class)} 35 * and {@link java.lang.System.LoggerFinder#getLocalizedLogger(java.lang.String, 36 * java.util.ResourceBundle, java.lang.Class)} 37 * (using both a null resource bundle and a non null resource bundle). 38 * It calls both the {@link java.lang.System} factory methods and 39 * {@link jdk.internal.logger.LazyLoggers} to obtains those loggers, 40 * and configure them with all possible known levels. 41 * @modules java.base/sun.util.logging 42 * java.base/jdk.internal.logger 43 * java.logging/sun.util.logging.internal 44 * @build LoggerFinderBackendTest SystemClassLoader 45 * @run main/othervm -Djava.system.class.loader=SystemClassLoader -Dtest.logger.hidesProvider=true LoggerFinderBackendTest 46 * @run main/othervm -Djava.system.class.loader=SystemClassLoader -Dtest.logger.hidesProvider=false LoggerFinderBackendTest 47 */ 48 49 50 import java.lang.invoke.MethodHandle; 51 import java.lang.invoke.MethodHandles; 52 import java.lang.invoke.MethodHandles.Lookup; 53 import java.lang.invoke.MethodType; 54 import java.lang.reflect.InvocationTargetException; 55 import java.lang.reflect.Method; 56 import java.util.ArrayList; 57 import java.util.Arrays; 58 import java.util.Collections; 59 import java.util.Enumeration; 60 import java.util.HashMap; 61 import java.util.LinkedHashMap; 62 import java.util.LinkedHashSet; 63 import java.util.List; 64 import java.util.Map; 65 import java.util.Objects; 66 import java.util.ResourceBundle; 67 import java.util.concurrent.atomic.AtomicInteger; 68 import java.util.function.BiFunction; 69 import java.util.function.BooleanSupplier; 70 import java.util.function.Function; 71 import java.util.function.Supplier; 72 import java.lang.System.LoggerFinder; 73 import java.util.logging.ConsoleHandler; 74 import java.util.logging.Handler; 75 import sun.util.logging.PlatformLogger.Level; 76 import java.util.logging.LogManager; 77 import java.util.logging.LogRecord; 78 import java.util.logging.Logger; 79 import sun.util.logging.internal.LoggingProviderImpl; 80 import java.lang.reflect.Module; 81 82 /** 83 * @author danielfuchs 84 */ 85 public class LoggerFinderBackendTest { 86 87 // whether the implementation of Logger try to do a best 88 // effort for logp... If the provider is not hidden, then 89 // the logp() implementation comes from LoggerWrapper - which does a 90 // best effort. Otherwise, it comes from the default provider 91 // which does support logp. 92 static final boolean BEST_EFFORT_FOR_LOGP = 93 !Boolean.getBoolean("test.logger.hidesProvider"); 94 static final boolean VERBOSE = false; 95 96 static final Class<java.lang.System.Logger> spiLoggerClass = 97 java.lang.System.Logger.class; 98 static final Class<java.lang.System.Logger> jdkLoggerClass = 99 java.lang.System.Logger.class; 100 static final Class<sun.util.logging.PlatformLogger.Bridge> bridgeLoggerClass = 101 sun.util.logging.PlatformLogger.Bridge.class; 102 103 /** Use to retrieve the log records that were produced by the JUL backend */ 104 static class LoggerTesterHandler extends Handler { 105 public final List<LogRecord> records = 106 Collections.synchronizedList(new ArrayList<>()); 107 108 @Override 109 public void publish(LogRecord record) { 110 record.getSourceClassName(); record.getSourceMethodName(); 111 records.add(record); 112 } 113 114 @Override 115 public void flush() { 116 } 117 118 @Override 119 public void close() throws SecurityException { 120 records.clear(); 121 } 122 123 public void reset() { 124 records.clear(); 125 } 126 } 127 128 /** The {@link LoggerTesterHandler} handler is added to the root logger. */ 129 static final LoggerTesterHandler handler = new LoggerTesterHandler(); 130 static { 131 for (Handler h : Logger.getLogger("").getHandlers()) { 132 if (h instanceof ConsoleHandler) { 133 Logger.getLogger("").removeHandler(h); 134 } 135 } 136 Logger.getLogger("").addHandler(handler); 137 } 138 139 /** 140 * A resource handler parameter that will be used when calling out the 141 * logrb-like methods - as well as when calling the level-specific 142 * methods that take a ResourceBundle parameter. 143 */ 144 public static class ResourceBundeParam extends ResourceBundle { 145 Map<String, String> map = Collections.synchronizedMap(new LinkedHashMap<>()); 146 @Override 147 protected Object handleGetObject(String key) { 148 map.putIfAbsent(key, "${"+key+"}"); 149 return map.get(key); 150 } 151 152 @Override 153 public Enumeration<String> getKeys() { 154 return Collections.enumeration(new LinkedHashSet<>(map.keySet())); 155 } 156 157 } 158 159 final static ResourceBundle bundleParam = 160 ResourceBundle.getBundle(ResourceBundeParam.class.getName()); 161 162 /** 163 * A resource handler parameter that will be used when creating localized 164 * loggers by calling {@link 165 * LoggerFinder#getLocalizedLogger(java.lang.String, java.util.ResourceBundle, java.lang.Class)}. 166 */ 167 public static class ResourceBundeLocalized extends ResourceBundle { 168 Map<String, String> map = Collections.synchronizedMap(new LinkedHashMap<>()); 169 @Override 170 protected Object handleGetObject(String key) { 171 map.putIfAbsent(key, "Localized:${"+key+"}"); 172 return map.get(key); 173 } 174 175 @Override 176 public Enumeration<String> getKeys() { 177 return Collections.enumeration(new LinkedHashSet<>(map.keySet())); 178 } 179 180 } 181 182 /** 183 * The Levels enum is used to call all the level-specific methods on 184 * a logger instance. To minimize the amount of code it uses reflection 185 * to do so. 186 */ 187 static Lookup lookup = MethodHandles.lookup(); 188 public enum Levels { 189 /** Used to call all forms of Logger.log?(SEVERE, ...) */ 190 SEVERE("severe", bridgeLoggerClass, Level.SEVERE, null, "error", false), 191 /** Used to call all forms of Logger.log?(WARNING,...) */ 192 WARNING("warning", bridgeLoggerClass, Level.WARNING, "warning", "warning", false), 193 /** Used to call all forms of Logger.log?(INFO,...) */ 194 INFO("info", bridgeLoggerClass, Level.INFO, "info", "info", false), 195 /** Used to call all forms of Logger.log?(CONFIG,...) */ 196 CONFIG("config", bridgeLoggerClass, Level.CONFIG, null, "debug", false), 197 /** Used to call all forms of Logger.log?(FINE,...) */ 198 FINE("fine", bridgeLoggerClass, Level.FINE, null, "debug", false), 199 /** Used to call all forms of Logger.log?(FINER,...) */ 200 FINER("finer", bridgeLoggerClass, Level.FINER, null, "trace", false), 201 /** Used to call all forms of Logger.log?(FINEST,...) */ 202 FINEST("finest", bridgeLoggerClass, Level.FINEST, null, "trace", false), 203 ; 204 public final String method; // The name of the level-specific method to call 205 public final Class<?> definingClass; // which interface j.u.logger.Logger or j.u.logging.spi.Logger defines it 206 public final Level platformLevel; // The platform Level it will be mapped to in Jul when Jul is the backend 207 public final String jdkExtensionToJUL; // The name of the method called on the JUL logger when JUL is the backend 208 public final String julToJdkExtension; // The name of the method called in the jdk extension by the default impl in jdk.internal.logging.Logger 209 public final String enableMethod; // The name of the isXxxxEnabled method 210 public final boolean hasSpecificIsEnabled; 211 Levels(String method, Class<?> definingClass, Level defaultMapping, 212 String jdkExtensionToJUL, String julToJdkExtension, 213 boolean hasSpecificIsEnabled) { 214 this.method = method; 215 this.definingClass = definingClass; 216 this.platformLevel = defaultMapping; 217 this.jdkExtensionToJUL = jdkExtensionToJUL; 218 this.julToJdkExtension = julToJdkExtension; 219 this.hasSpecificIsEnabled = hasSpecificIsEnabled; 220 if (hasSpecificIsEnabled) { 221 this.enableMethod = "is" + method.substring(0,1).toUpperCase() 222 + method.substring(1) + "Enabled"; 223 } else { 224 this.enableMethod = "isLoggable"; 225 } 226 } 227 228 /* 229 * calls this level specific method - e.g. if this==INFO: logger.info(msg); 230 */ 231 public void level(Object logger, String msg) { 232 MethodType mt = MethodType.methodType(void.class, Level.class, String.class); 233 invoke("log", logger, mt, platformLevel, msg); 234 } 235 236 /* 237 * calls this level specific method - e.g. if this==INFO: logger.info(msgSupplier); 238 */ 239 public void level(Object logger, Supplier<String> msgSupplier) { 240 MethodType mt = MethodType.methodType(void.class, Level.class, Supplier.class); 241 invoke("log", logger, mt, platformLevel, msgSupplier); 242 } 243 244 /* 245 * calls this level specific method - e.g. if this==INFO: logger.info(msg, params); 246 */ 247 public void level(Object logger, String msg, Object... params) { 248 MethodType mt = MethodType.methodType(void.class, Level.class, String.class, 249 Object[].class); 250 invoke("log", logger, mt, platformLevel, msg, params); 251 } 252 253 /* 254 * calls this level specific method - e.g. if this==INFO: logger.info(msg, thrown); 255 */ 256 public void level(Object logger, String msg, Throwable thrown) { 257 MethodType mt = MethodType.methodType(void.class, Level.class, String.class, 258 Throwable.class); 259 invoke("log", logger, mt, platformLevel, msg, thrown); 260 } 261 262 /* 263 * calls this level specific method - e.g. if this==INFO: logger.info(msgSupplier, thrown); 264 */ 265 public void level(Object logger, Supplier<String> msgSupplier, Throwable thrown) { 266 MethodType mt = MethodType.methodType(void.class, Level.class, 267 Throwable.class, Supplier.class); 268 invoke("log", logger, mt, platformLevel, thrown, msgSupplier); 269 } 270 271 /* 272 * calls this level specific method - e.g. if this==INFO: logger.info(bundle, msg); 273 */ 274 public void level(Object logger, String msg, ResourceBundle bundle) { 275 MethodType mt = MethodType.methodType(void.class, Level.class, 276 ResourceBundle.class, String.class, Object[].class); 277 invoke("logrb", logger, mt, platformLevel, bundle, msg, null); 278 } 279 280 public void level(Object logger, String msg, ResourceBundle bundle, 281 Object... params) { 282 MethodType mt = MethodType.methodType(void.class, Level.class, 283 ResourceBundle.class, String.class, Object[].class); 284 invoke("logrb", logger, mt, platformLevel, bundle, msg, params); 285 } 286 287 public void level(Object logger, String msg, ResourceBundle bundle, 288 Throwable thrown) { 289 MethodType mt = MethodType.methodType(void.class, Level.class, 290 ResourceBundle.class, String.class, Throwable.class); 291 invoke("logrb", logger, mt, platformLevel, bundle, msg, thrown); 292 } 293 294 public boolean isEnabled(Object logger) { 295 try { 296 if (hasSpecificIsEnabled) { 297 MethodType mt = MethodType.methodType(boolean.class); 298 final MethodHandle handle = lookup.findVirtual(definingClass, 299 enableMethod, mt).bindTo(logger); 300 return Boolean.class.cast(handle.invoke()); 301 } else { 302 MethodType mt = MethodType.methodType(boolean.class, 303 Level.class); 304 final MethodHandle handle = lookup.findVirtual(definingClass, 305 enableMethod, mt).bindTo(logger); 306 return Boolean.class.cast(handle.invoke(platformLevel)); 307 } 308 } catch (Throwable ex) { 309 throw new RuntimeException(ex); 310 } 311 } 312 313 private void invoke(String method, Object logger, MethodType mt, Object... args) { 314 try { 315 final int last = mt.parameterCount()-1; 316 boolean isVarargs = mt.parameterType(last).isArray(); 317 final MethodHandle handle = lookup.findVirtual(definingClass, 318 method, mt).bindTo(logger); 319 320 final StringBuilder builder = new StringBuilder(); 321 builder.append(logger.getClass().getSimpleName()).append('.') 322 .append(method).append('('); 323 String sep = ""; 324 int offset = 0; 325 Object[] params = args; 326 for (int i=0; (i-offset) < params.length; i++) { 327 if (isVarargs && i == last) { 328 offset = last; 329 params = (Object[])args[i]; 330 if (params == null) break; 331 } 332 Object p = params[i - offset]; 333 String quote = (p instanceof String) ? "\"" : ""; 334 builder.append(sep).append(quote).append(p).append(quote); 335 sep = ", "; 336 } 337 builder.append(')'); 338 if (verbose) { 339 System.out.println(builder); 340 } 341 handle.invokeWithArguments(args); 342 } catch (Throwable ex) { 343 throw new RuntimeException(ex); 344 } 345 } 346 347 }; 348 349 static interface Checker<LogResult, L> extends BiFunction<LogResult, L, Void> {} 350 static interface JdkLogTester 351 extends BiFunction<sun.util.logging.PlatformLogger.Bridge, Level, Void> {} 352 static interface SpiLogTester 353 extends BiFunction<java.lang.System.Logger, java.lang.System.Logger.Level, Void> {} 354 355 static interface MethodInvoker<LOGGER, LEVEL> { 356 public void logX(LOGGER logger, LEVEL level, Object... args); 357 } 358 359 public enum JdkLogMethodInvoker 360 implements MethodInvoker<sun.util.logging.PlatformLogger.Bridge, Level> { 361 /** 362 * Tests {@link 363 * jdk.internal.logging.Logger#log(Level, String, Object...)}; 364 **/ 365 LOG_STRING_PARAMS("log", MethodType.methodType(void.class, 366 Level.class, String.class, Object[].class)), 367 /** 368 * Tests {@link 369 * jdk.internal.logging.Logger#log(Level, String, Throwable)}; 370 **/ 371 LOG_STRING_THROWN("log", MethodType.methodType(void.class, 372 Level.class, String.class, Throwable.class)), 373 /** 374 * Tests {@link 375 * jdk.internal.logging.Logger#log(Level, Supplier<String>)}; 376 **/ 377 LOG_SUPPLIER("log", MethodType.methodType(void.class, 378 Level.class, Supplier.class)), 379 /** 380 * Tests {@link 381 * jdk.internal.logging.Logger#log(Level, Throwable, Supplier<String>)}; 382 **/ 383 LOG_SUPPLIER_THROWN("log", MethodType.methodType(void.class, 384 Level.class, Throwable.class, Supplier.class)), 385 /** 386 * Tests {@link 387 * jdk.internal.logging.Logger#logp(Level, String, String, String)}; 388 **/ 389 LOGP_STRING("logp", MethodType.methodType(void.class, 390 Level.class, String.class, String.class, String.class)), 391 /** 392 * Tests {@link 393 * jdk.internal.logging.Logger#logp(Level, String, String, String, Object...)}; 394 **/ 395 LOGP_STRING_PARAMS("logp", MethodType.methodType(void.class, 396 Level.class, String.class, String.class, String.class, Object[].class)), 397 /** 398 * Tests {@link 399 * jdk.internal.logging.Logger#logp(Level, String, String, String, Throwable)}; 400 **/ 401 LOGP_STRING_THROWN("logp", MethodType.methodType(void.class, 402 Level.class, String.class, String.class, String.class, Throwable.class)), 403 /** 404 * Tests {@link 405 * jdk.internal.logging.Logger#logp(Level, String, String, Supplier<String>)}; 406 **/ 407 LOGP_SUPPLIER("logp", MethodType.methodType(void.class, 408 Level.class, String.class, String.class, Supplier.class)), 409 /** 410 * Tests {@link 411 * jdk.internal.logging.Logger#logp(Level, String, String, Throwable, Supplier<String>)}; 412 **/ 413 LOGP_SUPPLIER_THROWN("logp", MethodType.methodType(void.class, 414 Level.class, String.class, String.class, 415 Throwable.class, Supplier.class)), 416 /** 417 * Tests {@link 418 * jdk.internal.logging.Logger#logrb(Level, ResourceBundle, String, Object...)}; 419 **/ 420 LOGRB_STRING_PARAMS("logrb", MethodType.methodType(void.class, 421 Level.class, ResourceBundle.class, String.class, Object[].class)), 422 /** 423 * Tests {@link 424 * jdk.internal.logging.Logger#logrb(Level, ResourceBundle, String, Throwable)}; 425 **/ 426 LOGRB_STRING_THROWN("logrb", MethodType.methodType(void.class, 427 Level.class, ResourceBundle.class, String.class, Throwable.class)), 428 /** 429 * Tests {@link 430 * jdk.internal.logging.Logger#logrb(Level, String, String, ResourceBundle, String, Object...)}; 431 **/ 432 LOGRBP_STRING_PARAMS("logrb", MethodType.methodType(void.class, 433 Level.class, String.class, String.class, ResourceBundle.class, 434 String.class, Object[].class)), 435 /** 436 * Tests {@link 437 * jdk.internal.logging.Logger#logrb(Level, String, String, ResourceBundle, String, Throwable)}; 438 **/ 439 LOGRBP_STRING_THROWN("logrb", MethodType.methodType(void.class, 440 Level.class, String.class, String.class, ResourceBundle.class, 441 String.class, Throwable.class)), 442 ; 443 final MethodType mt; 444 final String method; 445 JdkLogMethodInvoker(String method, MethodType mt) { 446 this.mt = mt; 447 this.method = method; 448 } 449 Object[] makeArgs(Level level, Object... rest) { 450 List<Object> list = new ArrayList<>(rest == null ? 1 : rest.length + 1); 451 list.add(level); 452 if (rest != null) { 453 list.addAll(Arrays.asList(rest)); 454 } 455 return list.toArray(new Object[list.size()]); 456 } 457 458 @Override 459 public void logX(sun.util.logging.PlatformLogger.Bridge logger, Level level, Object... args) { 460 try { 461 MethodHandle handle = lookup.findVirtual(bridgeLoggerClass, 462 method, mt).bindTo(logger); 463 final int last = mt.parameterCount()-1; 464 boolean isVarargs = mt.parameterType(last).isArray(); 465 466 args = makeArgs(level, args); 467 468 final StringBuilder builder = new StringBuilder(); 469 builder.append(logger.getClass().getSimpleName()).append('.') 470 .append(this.method).append('('); 471 String sep = ""; 472 int offset = 0; 473 Object[] params = args; 474 for (int i=0; (i-offset) < params.length; i++) { 475 if (isVarargs && i == last) { 476 offset = last; 477 params = (Object[])args[i]; 478 if (params == null) break; 479 } 480 Object p = params[i - offset]; 481 String quote = (p instanceof String) ? "\"" : ""; 482 p = p instanceof Level ? "Level."+p : p; 483 builder.append(sep).append(quote).append(p).append(quote); 484 sep = ", "; 485 } 486 builder.append(')'); 487 if (verbose) System.out.println(builder); 488 handle.invokeWithArguments(args); 489 } catch (Throwable ex) { 490 throw new RuntimeException(ex); 491 } 492 } 493 } 494 495 496 public enum SpiLogMethodInvoker implements MethodInvoker<java.lang.System.Logger, 497 java.lang.System.Logger.Level> { 498 /** 499 * Tests {@link 500 * jdk.internal.logging.Logger#log(Level, String, Object...)}; 501 **/ 502 LOG_STRING_PARAMS("log", MethodType.methodType(void.class, 503 java.lang.System.Logger.Level.class, String.class, Object[].class)), 504 /** 505 * Tests {@link 506 * jdk.internal.logging.Logger#log(Level, String, Throwable)}; 507 **/ 508 LOG_STRING_THROWN("log", MethodType.methodType(void.class, 509 java.lang.System.Logger.Level.class, String.class, Throwable.class)), 510 /** 511 * Tests {@link 512 * jdk.internal.logging.Logger#log(Level, Supplier<String>)}; 513 **/ 514 LOG_SUPPLIER("log", MethodType.methodType(void.class, 515 java.lang.System.Logger.Level.class, Supplier.class)), 516 /** 517 * Tests {@link 518 * jdk.internal.logging.Logger#log(Level, Throwable, Supplier<String>)}; 519 **/ 520 LOG_SUPPLIER_THROWN("log", MethodType.methodType(void.class, 521 java.lang.System.Logger.Level.class, Supplier.class, Throwable.class)), 522 /** 523 * Tests {@link 524 * jdk.internal.logging.Logger#log(Level, Supplier<String>)}; 525 **/ 526 LOG_OBJECT("log", MethodType.methodType(void.class, 527 java.lang.System.Logger.Level.class, Object.class)), 528 /** 529 * Tests {@link 530 * jdk.internal.logging.Logger#logrb(Level, ResourceBundle, String, Object...)}; 531 **/ 532 LOGRB_STRING_PARAMS("log", MethodType.methodType(void.class, 533 java.lang.System.Logger.Level.class, ResourceBundle.class, 534 String.class, Object[].class)), 535 /** 536 * Tests {@link 537 * jdk.internal.logging.Logger#logrb(Level, ResourceBundle, String, Throwable)}; 538 **/ 539 LOGRB_STRING_THROWN("log", MethodType.methodType(void.class, 540 java.lang.System.Logger.Level.class, ResourceBundle.class, 541 String.class, Throwable.class)), 542 ; 543 final MethodType mt; 544 final String method; 545 SpiLogMethodInvoker(String method, MethodType mt) { 546 this.mt = mt; 547 this.method = method; 548 } 549 Object[] makeArgs(java.lang.System.Logger.Level level, Object... rest) { 550 List<Object> list = new ArrayList<>(rest == null ? 1 : rest.length + 1); 551 list.add(level); 552 if (rest != null) { 553 list.addAll(Arrays.asList(rest)); 554 } 555 return list.toArray(new Object[list.size()]); 556 } 557 558 @Override 559 public void logX(java.lang.System.Logger logger, 560 java.lang.System.Logger.Level level, Object... args) { 561 try { 562 MethodHandle handle = lookup.findVirtual(spiLoggerClass, 563 method, mt).bindTo(logger); 564 final int last = mt.parameterCount()-1; 565 boolean isVarargs = mt.parameterType(last).isArray(); 566 567 args = makeArgs(level, args); 568 569 final StringBuilder builder = new StringBuilder(); 570 builder.append(logger.getClass().getSimpleName()).append('.') 571 .append(this.method).append('('); 572 String sep = ""; 573 int offset = 0; 574 Object[] params = args; 575 for (int i=0; (i-offset) < params.length; i++) { 576 if (isVarargs && i == last) { 577 offset = last; 578 params = (Object[])args[i]; 579 if (params == null) break; 580 } 581 Object p = params[i - offset]; 582 String quote = (p instanceof String) ? "\"" : ""; 583 p = p instanceof Level ? "Level."+p : p; 584 builder.append(sep).append(quote).append(p).append(quote); 585 sep = ", "; 586 } 587 builder.append(')'); 588 if (verbose) System.out.println(builder); 589 handle.invokeWithArguments(args); 590 } catch (Throwable ex) { 591 throw new RuntimeException(ex); 592 } 593 } 594 } 595 596 597 public abstract static class BackendTester<BackendRecord> { 598 static final Level[] levelMap = {Level.ALL, Level.FINER, Level.FINE, 599 Level.INFO, Level.WARNING, Level.SEVERE, Level.OFF}; 600 601 abstract class BackendAdaptor { 602 public abstract String getLoggerName(BackendRecord res); 603 public abstract Object getLevel(BackendRecord res); 604 public abstract String getMessage(BackendRecord res); 605 public abstract String getSourceClassName(BackendRecord res); 606 public abstract String getSourceMethodName(BackendRecord res); 607 public abstract Throwable getThrown(BackendRecord res); 608 public abstract ResourceBundle getResourceBundle(BackendRecord res); 609 public abstract void setLevel(java.lang.System.Logger logger, 610 Level level); 611 public abstract void setLevel(java.lang.System.Logger logger, 612 java.lang.System.Logger.Level level); 613 public abstract List<BackendRecord> getBackendRecords(); 614 public abstract void resetBackendRecords(); 615 public boolean shouldBeLoggable(Levels level, Level loggerLevel) { 616 final Level logLevel = level.platformLevel; 617 return shouldBeLoggable(logLevel, loggerLevel); 618 } 619 public boolean shouldBeLoggable(Level logLevel, Level loggerLevel) { 620 return loggerLevel.intValue() != Level.OFF.intValue() 621 && logLevel.intValue() >= loggerLevel.intValue(); 622 } 623 public boolean shouldBeLoggable(java.lang.System.Logger.Level logLevel, 624 java.lang.System.Logger.Level loggerLevel) { 625 return loggerLevel != java.lang.System.Logger.Level.OFF 626 && logLevel.ordinal() >= loggerLevel.ordinal(); 627 } 628 public boolean isLoggable(java.lang.System.Logger logger, Level l) { 629 return bridgeLoggerClass.cast(logger).isLoggable(l); 630 } 631 public String getCallerClassName(Levels level, String clazz) { 632 return clazz != null ? clazz : Levels.class.getName(); 633 } 634 public String getCallerClassName(MethodInvoker<?,?> logMethod, 635 String clazz) { 636 return clazz != null ? clazz : logMethod.getClass().getName(); 637 } 638 public String getCallerMethodName(Levels level, String method) { 639 return method != null ? method : "invoke"; 640 } 641 public String getCallerMethodName(MethodInvoker<?,?> logMethod, 642 String method) { 643 return method != null ? method : "logX"; 644 } 645 public Object getMappedLevel(Object level) { 646 return level; 647 } 648 649 public Level toJUL(java.lang.System.Logger.Level level) { 650 return levelMap[level.ordinal()]; 651 } 652 } 653 654 public final boolean isSystem; 655 public final Class<? extends java.lang.System.Logger> restrictedTo; 656 public final ResourceBundle localized; 657 public BackendTester(boolean isSystem) { 658 this(isSystem,null,null); 659 } 660 public BackendTester(boolean isSystem, ResourceBundle localized) { 661 this(isSystem,null,localized); 662 } 663 public BackendTester(boolean isSystem, 664 Class<? extends java.lang.System.Logger> restrictedTo) { 665 this(isSystem, restrictedTo, null); 666 } 667 public BackendTester(boolean isSystem, 668 Class<? extends java.lang.System.Logger> restrictedTo, 669 ResourceBundle localized) { 670 this.isSystem = isSystem; 671 this.restrictedTo = restrictedTo; 672 this.localized = localized; 673 } 674 675 public java.lang.System.Logger convert(java.lang.System.Logger logger) { 676 return logger; 677 } 678 679 public static Level[] LEVELS = { 680 Level.OFF, 681 Level.SEVERE, Level.WARNING, Level.INFO, Level.CONFIG, 682 Level.FINE, Level.FINER, Level.FINEST, 683 Level.ALL 684 }; 685 686 abstract BackendAdaptor adaptor(); 687 688 protected void checkRecord(Levels test, BackendRecord res, String loggerName, 689 Level level, String msg, String className, String methodName, 690 Throwable thrown, ResourceBundle bundle, Object... params) { 691 checkRecord(test, res, loggerName, level, ()->msg, className, 692 methodName, thrown, bundle, params); 693 694 } 695 protected void checkRecord(Levels test, BackendRecord res, String loggerName, 696 Level level, Supplier<String> msg, String className, String methodName, 697 Throwable thrown, ResourceBundle bundle, Object... params) { 698 checkRecord(test.method, res, loggerName, level, msg, 699 className, methodName, thrown, bundle, params); 700 } 701 protected <L> void checkRecord(String logMethod, BackendRecord res, String loggerName, 702 L level, Supplier<String> msg, String className, String methodName, 703 Throwable thrown, ResourceBundle bundle, Object... params) { 704 final BackendAdaptor analyzer = adaptor(); 705 if (! Objects.equals(analyzer.getLoggerName(res), loggerName)) { 706 throw new RuntimeException(logMethod+": expected logger name " 707 + loggerName + " got " + analyzer.getLoggerName(res)); 708 } 709 if (!Objects.equals(analyzer.getLevel(res), analyzer.getMappedLevel(level))) { 710 throw new RuntimeException(logMethod+": expected level " 711 + analyzer.getMappedLevel(level) + " got " + analyzer.getLevel(res)); 712 } 713 if (!Objects.equals(analyzer.getMessage(res), msg.get())) { 714 throw new RuntimeException(logMethod+": expected message \"" 715 + msg.get() + "\" got \"" + analyzer.getMessage(res) +"\""); 716 } 717 if (!Objects.equals(analyzer.getSourceClassName(res), className)) { 718 throw new RuntimeException(logMethod 719 + ": expected class name \"" + className 720 + "\" got \"" + analyzer.getSourceClassName(res) +"\""); 721 } 722 if (!Objects.equals(analyzer.getSourceMethodName(res), methodName)) { 723 throw new RuntimeException(logMethod 724 + ": expected method name \"" + methodName 725 + "\" got \"" + analyzer.getSourceMethodName(res) +"\""); 726 } 727 final Throwable thrownRes = analyzer.getThrown(res); 728 if (!Objects.equals(thrownRes, thrown)) { 729 throw new RuntimeException(logMethod 730 + ": expected throwable \"" + thrown 731 + "\" got \"" + thrownRes + "\""); 732 } 733 if (!Objects.equals(analyzer.getResourceBundle(res), bundle)) { 734 throw new RuntimeException(logMethod 735 + ": expected bundle \"" + bundle 736 + "\" got \"" + analyzer.getResourceBundle(res) +"\""); 737 } 738 } 739 740 public void testLevel(Levels level, java.lang.System.Logger logger, 741 String msg) { 742 Runnable test = () -> level.level(logger, msg); 743 Checker<BackendRecord, Level> check = (res, l) -> { 744 checkRecord(level, res, logger.getName(), l, msg, 745 adaptor().getCallerClassName(level, Levels.class.getName()), 746 adaptor().getCallerMethodName(level, "invoke"), 747 null, localized); 748 return null; 749 }; 750 test("msg", level, logger, test, check); 751 } 752 753 public void testLevel(Levels level, java.lang.System.Logger logger, 754 String msg, Object... params) { 755 Runnable test = () -> level.level(logger, msg, (Object[])params); 756 Checker<BackendRecord, Level> check = (res, l) -> { 757 checkRecord(level, res, logger.getName(), l, msg, 758 adaptor().getCallerClassName(level, Levels.class.getName()), 759 adaptor().getCallerMethodName(level, "invoke"), 760 null, localized, (Object[])params); 761 return null; 762 }; 763 test("msg, params", level, logger, test, check); 764 } 765 766 public void testLevel(Levels level, java.lang.System.Logger logger, 767 String msg, Throwable thrown) { 768 Runnable test = () -> level.level(logger, msg, thrown); 769 Checker<BackendRecord, Level> check = (res, l) -> { 770 checkRecord(level, res, logger.getName(), l, msg, 771 adaptor().getCallerClassName(level, Levels.class.getName()), 772 adaptor().getCallerMethodName(level, "invoke"), 773 thrown, localized); 774 return null; 775 }; 776 test("msg, thrown", level, logger, test, check); 777 } 778 779 public void testLevel(Levels level, java.lang.System.Logger logger, 780 Supplier<String> msg) { 781 Runnable test = () -> level.level(logger, msg); 782 Checker<BackendRecord, Level> check = (res, l) -> { 783 checkRecord(level, res, logger.getName(), l, msg, 784 adaptor().getCallerClassName(level, Levels.class.getName()), 785 adaptor().getCallerMethodName(level, "invoke"), 786 null, null); 787 return null; 788 }; 789 test("msgSupplier", level, logger, test, check); 790 } 791 792 public void testLevel(Levels level, java.lang.System.Logger logger, 793 Supplier<String> msg, Throwable thrown) { 794 Runnable test = () -> level.level(logger, msg, thrown); 795 Checker<BackendRecord, Level> check = (res, l) -> { 796 checkRecord(level, res, logger.getName(), l, msg, 797 adaptor().getCallerClassName(level, Levels.class.getName()), 798 adaptor().getCallerMethodName(level, "invoke"), 799 thrown, null); 800 return null; 801 }; 802 test("throw, msgSupplier", level, logger, test, check); 803 } 804 805 public void testLevel(Levels level, java.lang.System.Logger logger, 806 String msg, ResourceBundle bundle) { 807 Runnable test = () -> level.level(logger, msg, bundle); 808 Checker<BackendRecord, Level> check = (res, l) -> { 809 checkRecord(level, res, logger.getName(), l, msg, 810 adaptor().getCallerClassName(level, Levels.class.getName()), 811 adaptor().getCallerMethodName(level, "invoke"), 812 null, bundle); 813 return null; 814 }; 815 test("bundle, msg", level, logger, test, check); 816 } 817 818 public void testLevel(Levels level, java.lang.System.Logger logger, 819 String msg, ResourceBundle bundle, Object... params) { 820 Runnable test = () -> level.level(logger, msg, bundle, (Object[])params); 821 Checker<BackendRecord, Level> check = (res, l) -> { 822 checkRecord(level, res, logger.getName(), l, msg, 823 adaptor().getCallerClassName(level, Levels.class.getName()), 824 adaptor().getCallerMethodName(level, "invoke"), 825 null, bundle, (Object[])params); 826 return null; 827 }; 828 test("bundle, msg, params", level, logger, test, check); 829 } 830 831 public void testLevel(Levels level, java.lang.System.Logger logger, 832 String msg, ResourceBundle bundle, Throwable thrown) { 833 Runnable test = () -> level.level(logger, msg, bundle, thrown); 834 Checker<BackendRecord, Level> check = (res, l) -> { 835 checkRecord(level, res, logger.getName(), l, msg, 836 adaptor().getCallerClassName(level, Levels.class.getName()), 837 adaptor().getCallerMethodName(level, "invoke"), 838 thrown, bundle); 839 return null; 840 }; 841 test("bundle, msg, throwable", level, logger, test, check); 842 } 843 844 // System.Logger 845 public void testSpiLog(java.lang.System.Logger logger, String msg) { 846 Checker<BackendRecord, java.lang.System.Logger.Level> check = (res, l) -> { 847 checkRecord("log", res, logger.getName(), l, () -> msg, 848 adaptor().getCallerClassName( 849 SpiLogMethodInvoker.LOG_STRING_PARAMS, 850 SpiLogMethodInvoker.class.getName()), 851 adaptor().getCallerMethodName( 852 SpiLogMethodInvoker.LOG_STRING_PARAMS, 853 "logX"), null, localized); 854 return null; 855 }; 856 SpiLogTester tester = (x, level) -> { 857 SpiLogMethodInvoker.LOG_STRING_PARAMS.logX(x, level, msg, (Object[])null); 858 return null; 859 }; 860 Function<String, String> nameProducer = (l) -> "log(Level." + l + ", \"" + msg + "\")"; 861 testSpiLog(logger, tester, check, nameProducer); 862 } 863 864 public void testSpiLog(java.lang.System.Logger logger, 865 ResourceBundle bundle, String msg) { 866 Checker<BackendRecord, java.lang.System.Logger.Level> check = (res, l) -> { 867 checkRecord("log", res, logger.getName(), l, () -> msg, 868 adaptor().getCallerClassName( 869 SpiLogMethodInvoker.LOGRB_STRING_PARAMS, 870 SpiLogMethodInvoker.class.getName()), 871 adaptor().getCallerMethodName( 872 SpiLogMethodInvoker.LOGRB_STRING_PARAMS, 873 "logX"), null, bundle); 874 return null; 875 }; 876 SpiLogTester tester = (x, level) -> { 877 SpiLogMethodInvoker.LOGRB_STRING_PARAMS.logX(x, level, bundle, msg, (Object[])null); 878 return null; 879 }; 880 Function<String, String> nameProducer = (l) -> "log(Level." + l 881 + ", bundle, \"" + msg + "\")"; 882 testSpiLog(logger, tester, check, nameProducer); 883 } 884 885 public void testSpiLog(java.lang.System.Logger logger, String msg, Object... params) { 886 Checker<BackendRecord, java.lang.System.Logger.Level> check = (res, l) -> { 887 checkRecord("log", res, logger.getName(), l, () -> msg, 888 adaptor().getCallerClassName( 889 SpiLogMethodInvoker.LOG_STRING_PARAMS, 890 SpiLogMethodInvoker.class.getName()), 891 adaptor().getCallerMethodName( 892 SpiLogMethodInvoker.LOG_STRING_PARAMS, 893 "logX"), null, localized, params); 894 return null; 895 }; 896 SpiLogTester tester = (x, level) -> { 897 SpiLogMethodInvoker.LOG_STRING_PARAMS.logX(x, level, msg, params); 898 return null; 899 }; 900 Function<String, String> nameProducer = (l) -> "log(Level." + l + ", \"" + msg + "\", params...)"; 901 testSpiLog(logger, tester, check, nameProducer); 902 } 903 904 public void testSpiLog(java.lang.System.Logger logger, 905 ResourceBundle bundle, String msg, Object... params) { 906 Checker<BackendRecord, java.lang.System.Logger.Level> check = (res, l) -> { 907 checkRecord("log", res, logger.getName(), l, () -> msg, 908 adaptor().getCallerClassName( 909 SpiLogMethodInvoker.LOGRB_STRING_PARAMS, 910 SpiLogMethodInvoker.class.getName()), 911 adaptor().getCallerMethodName( 912 SpiLogMethodInvoker.LOGRB_STRING_PARAMS, 913 "logX"), null, bundle, params); 914 return null; 915 }; 916 SpiLogTester tester = (x, level) -> { 917 SpiLogMethodInvoker.LOGRB_STRING_PARAMS.logX(x, level, bundle, msg, params); 918 return null; 919 }; 920 Function<String, String> nameProducer = (l) -> "log(Level." + l 921 + ", bundle, \"" + msg + "\", params...)"; 922 testSpiLog(logger, tester, check, nameProducer); 923 } 924 925 public void testSpiLog(java.lang.System.Logger logger, String msg, Throwable thrown) { 926 Checker<BackendRecord, java.lang.System.Logger.Level> check = (res, l) -> { 927 checkRecord("log", res, logger.getName(), l, () -> msg, 928 adaptor().getCallerClassName( 929 SpiLogMethodInvoker.LOG_STRING_THROWN, 930 SpiLogMethodInvoker.class.getName()), 931 adaptor().getCallerMethodName( 932 SpiLogMethodInvoker.LOG_STRING_THROWN, 933 "logX"), thrown, localized); 934 return null; 935 }; 936 SpiLogTester tester = (x, level) -> { 937 SpiLogMethodInvoker.LOG_STRING_THROWN.logX(x, level, msg, thrown); 938 return null; 939 }; 940 Function<String, String> nameProducer = (l) -> 941 "log(Level." + l + ", \"" + msg + "\", thrown)"; 942 testSpiLog(logger, tester, check, nameProducer); 943 } 944 945 public void testSpiLog(java.lang.System.Logger logger, 946 ResourceBundle bundle, String msg, Throwable thrown) { 947 Checker<BackendRecord, java.lang.System.Logger.Level> check = (res, l) -> { 948 checkRecord("log", res, logger.getName(), l, () -> msg, 949 adaptor().getCallerClassName( 950 SpiLogMethodInvoker.LOGRB_STRING_THROWN, 951 SpiLogMethodInvoker.class.getName()), 952 adaptor().getCallerMethodName( 953 SpiLogMethodInvoker.LOGRB_STRING_THROWN, 954 "logX"), thrown, bundle); 955 return null; 956 }; 957 SpiLogTester tester = (x, level) -> { 958 SpiLogMethodInvoker.LOGRB_STRING_THROWN.logX(x, level, bundle, msg, thrown); 959 return null; 960 }; 961 Function<String, String> nameProducer = (l) -> 962 "log(Level." + l + ", bundle, \"" + msg + "\", thrown)"; 963 testSpiLog(logger, tester, check, nameProducer); 964 } 965 966 public void testSpiLog(java.lang.System.Logger logger, Supplier<String> msg) { 967 Checker<BackendRecord, java.lang.System.Logger.Level> check = (res, l) -> { 968 checkRecord("log", res, logger.getName(), l, msg, 969 adaptor().getCallerClassName( 970 SpiLogMethodInvoker.LOG_SUPPLIER, 971 SpiLogMethodInvoker.class.getName()), 972 adaptor().getCallerMethodName( 973 SpiLogMethodInvoker.LOG_SUPPLIER, 974 "logX"), null, null); 975 return null; 976 }; 977 SpiLogTester tester = (x, level) -> { 978 SpiLogMethodInvoker.LOG_SUPPLIER.logX(x, level, msg); 979 return null; 980 }; 981 Function<String, String> nameProducer = (l) -> 982 "log(Level." + l + ", () -> \"" + msg.get() + "\")"; 983 testSpiLog(logger, tester, check, nameProducer); 984 } 985 986 public void testSpiLog(java.lang.System.Logger logger, Object obj) { 987 Checker<BackendRecord, java.lang.System.Logger.Level> check = (res, l) -> { 988 checkRecord("log", res, logger.getName(), l, () -> obj.toString(), 989 adaptor().getCallerClassName( 990 SpiLogMethodInvoker.LOG_OBJECT, 991 SpiLogMethodInvoker.class.getName()), 992 adaptor().getCallerMethodName( 993 SpiLogMethodInvoker.LOG_OBJECT, 994 "logX"), null, null); 995 return null; 996 }; 997 SpiLogTester tester = (x, level) -> { 998 SpiLogMethodInvoker.LOG_OBJECT.logX(x, level, obj); 999 return null; 1000 }; 1001 Function<String, String> nameProducer = (l) -> 1002 "log(Level." + l + ", new "+obj.getClass().getSimpleName()+"(\"" 1003 + obj.toString() + "\"))"; 1004 testSpiLog(logger, tester, check, nameProducer); 1005 } 1006 1007 public void testSpiLog(java.lang.System.Logger logger, Throwable thrown, Supplier<String> msg) { 1008 Checker<BackendRecord, java.lang.System.Logger.Level> check = (res, l) -> { 1009 checkRecord("log", res, logger.getName(), l, msg, 1010 adaptor().getCallerClassName( 1011 SpiLogMethodInvoker.LOG_SUPPLIER_THROWN, 1012 SpiLogMethodInvoker.class.getName()), 1013 adaptor().getCallerMethodName( 1014 SpiLogMethodInvoker.LOG_SUPPLIER_THROWN, 1015 "logX"), thrown, null); 1016 return null; 1017 }; 1018 SpiLogTester tester = (x, level) -> { 1019 SpiLogMethodInvoker.LOG_SUPPLIER_THROWN.logX(x, level, msg, thrown); 1020 return null; 1021 }; 1022 Function<String, String> nameProducer = (l) -> 1023 "log(Level." + l + ", () -> \"" + msg.get() + "\", thrown)"; 1024 testSpiLog(logger, tester, check, nameProducer); 1025 } 1026 1027 1028 // JDK 1029 1030 public void testLog(java.lang.System.Logger logger, String msg) { 1031 Checker<BackendRecord, Level> check = (res, l) -> { 1032 checkRecord("log", res, logger.getName(), l, () -> msg, 1033 adaptor().getCallerClassName( 1034 JdkLogMethodInvoker.LOG_STRING_PARAMS, 1035 JdkLogMethodInvoker.class.getName()), 1036 adaptor().getCallerMethodName( 1037 JdkLogMethodInvoker.LOG_STRING_PARAMS, 1038 "logX"), null, localized); 1039 return null; 1040 }; 1041 JdkLogTester tester = (x, level) -> { 1042 JdkLogMethodInvoker.LOG_STRING_PARAMS.logX(x, level, msg, (Object[])null); 1043 return null; 1044 }; 1045 Function<String, String> nameProducer = (l) -> "log(Level." + l + ", \"" + msg + "\")"; 1046 testJdkLog(logger, tester, check, nameProducer); 1047 } 1048 1049 public void testLogrb(java.lang.System.Logger logger, 1050 ResourceBundle bundle, String msg) { 1051 Checker<BackendRecord, Level> check = (res, l) -> { 1052 checkRecord("log", res, logger.getName(), l, () -> msg, 1053 adaptor().getCallerClassName( 1054 JdkLogMethodInvoker.LOGRB_STRING_PARAMS, 1055 JdkLogMethodInvoker.class.getName()), 1056 adaptor().getCallerMethodName( 1057 JdkLogMethodInvoker.LOGRB_STRING_PARAMS, 1058 "logX"), null, bundle); 1059 return null; 1060 }; 1061 JdkLogTester tester = (x, level) -> { 1062 JdkLogMethodInvoker.LOGRB_STRING_PARAMS.logX(x, level, bundle, msg, (Object[])null); 1063 return null; 1064 }; 1065 Function<String, String> nameProducer = (l) -> "logrb(Level." + l 1066 + ", bundle, \"" + msg + "\")"; 1067 testJdkLog(logger, tester, check, nameProducer); 1068 } 1069 1070 public void testLog(java.lang.System.Logger logger, String msg, Object... params) { 1071 Checker<BackendRecord, Level> check = (res, l) -> { 1072 checkRecord("log", res, logger.getName(), l, () -> msg, 1073 adaptor().getCallerClassName( 1074 JdkLogMethodInvoker.LOG_STRING_PARAMS, 1075 JdkLogMethodInvoker.class.getName()), 1076 adaptor().getCallerMethodName( 1077 JdkLogMethodInvoker.LOG_STRING_PARAMS, 1078 "logX"), null, localized, params); 1079 return null; 1080 }; 1081 JdkLogTester tester = (x, level) -> { 1082 JdkLogMethodInvoker.LOG_STRING_PARAMS.logX(x, level, msg, params); 1083 return null; 1084 }; 1085 Function<String, String> nameProducer = (l) -> "log(Level." + l + ", \"" + msg + "\", params...)"; 1086 testJdkLog(logger, tester, check, nameProducer); 1087 } 1088 1089 public void testLogrb(java.lang.System.Logger logger, 1090 ResourceBundle bundle, String msg, Object... params) { 1091 Checker<BackendRecord, Level> check = (res, l) -> { 1092 checkRecord("log", res, logger.getName(), l, () -> msg, 1093 adaptor().getCallerClassName( 1094 JdkLogMethodInvoker.LOGRB_STRING_PARAMS, 1095 JdkLogMethodInvoker.class.getName()), 1096 adaptor().getCallerMethodName( 1097 JdkLogMethodInvoker.LOGRB_STRING_PARAMS, 1098 "logX"), null, bundle, params); 1099 return null; 1100 }; 1101 JdkLogTester tester = (x, level) -> { 1102 JdkLogMethodInvoker.LOGRB_STRING_PARAMS.logX(x, level, bundle, msg, params); 1103 return null; 1104 }; 1105 Function<String, String> nameProducer = (l) -> "log(Level." + l 1106 + ", bundle, \"" + msg + "\", params...)"; 1107 testJdkLog(logger, tester, check, nameProducer); 1108 } 1109 1110 public void testLog(java.lang.System.Logger logger, String msg, Throwable thrown) { 1111 Checker<BackendRecord, Level> check = (res, l) -> { 1112 checkRecord("log", res, logger.getName(), l, () -> msg, 1113 adaptor().getCallerClassName( 1114 JdkLogMethodInvoker.LOG_STRING_THROWN, 1115 JdkLogMethodInvoker.class.getName()), 1116 adaptor().getCallerMethodName( 1117 JdkLogMethodInvoker.LOG_STRING_THROWN, 1118 "logX"), thrown, localized); 1119 return null; 1120 }; 1121 JdkLogTester tester = (x, level) -> { 1122 JdkLogMethodInvoker.LOG_STRING_THROWN.logX(x, level, msg, thrown); 1123 return null; 1124 }; 1125 Function<String, String> nameProducer = (l) -> 1126 "log(Level." + l + ", \"" + msg + "\", thrown)"; 1127 testJdkLog(logger, tester, check, nameProducer); 1128 } 1129 1130 public void testLogrb(java.lang.System.Logger logger, 1131 ResourceBundle bundle, String msg, Throwable thrown) { 1132 Checker<BackendRecord, Level> check = (res, l) -> { 1133 checkRecord("log", res, logger.getName(), l, () -> msg, 1134 adaptor().getCallerClassName( 1135 JdkLogMethodInvoker.LOGRB_STRING_THROWN, 1136 JdkLogMethodInvoker.class.getName()), 1137 adaptor().getCallerMethodName( 1138 JdkLogMethodInvoker.LOGRB_STRING_THROWN, 1139 "logX"), thrown, bundle); 1140 return null; 1141 }; 1142 JdkLogTester tester = (x, level) -> { 1143 JdkLogMethodInvoker.LOGRB_STRING_THROWN.logX(x, level, bundle, msg, thrown); 1144 return null; 1145 }; 1146 Function<String, String> nameProducer = (l) -> 1147 "log(Level." + l + ", bundle, \"" + msg + "\", thrown)"; 1148 testJdkLog(logger, tester, check, nameProducer); 1149 } 1150 1151 public void testLog(java.lang.System.Logger logger, Supplier<String> msg) { 1152 Checker<BackendRecord, Level> check = (res, l) -> { 1153 checkRecord("log", res, logger.getName(), l, msg, 1154 adaptor().getCallerClassName( 1155 JdkLogMethodInvoker.LOG_SUPPLIER, 1156 JdkLogMethodInvoker.class.getName()), 1157 adaptor().getCallerMethodName( 1158 JdkLogMethodInvoker.LOG_SUPPLIER, 1159 "logX"), null, null); 1160 return null; 1161 }; 1162 JdkLogTester tester = (x, level) -> { 1163 JdkLogMethodInvoker.LOG_SUPPLIER.logX(x, level, msg); 1164 return null; 1165 }; 1166 Function<String, String> nameProducer = (l) -> 1167 "log(Level." + l + ", () -> \"" + msg.get() + "\")"; 1168 testJdkLog(logger, tester, check, nameProducer); 1169 } 1170 1171 public void testLog(java.lang.System.Logger logger, Throwable thrown, Supplier<String> msg) { 1172 Checker<BackendRecord, Level> check = (res, l) -> { 1173 checkRecord("log", res, logger.getName(), l, msg, 1174 adaptor().getCallerClassName( 1175 JdkLogMethodInvoker.LOG_SUPPLIER_THROWN, 1176 JdkLogMethodInvoker.class.getName()), 1177 adaptor().getCallerMethodName( 1178 JdkLogMethodInvoker.LOG_SUPPLIER_THROWN, 1179 "logX"), thrown, null); 1180 return null; 1181 }; 1182 JdkLogTester tester = (x, level) -> { 1183 JdkLogMethodInvoker.LOG_SUPPLIER_THROWN.logX(x, level, thrown, msg); 1184 return null; 1185 }; 1186 Function<String, String> nameProducer = (l) -> 1187 "log(Level." + l + ", () -> \"" + msg.get() + "\", thrown)"; 1188 testJdkLog(logger, tester, check, nameProducer); 1189 } 1190 1191 static Supplier<String> logpMessage(ResourceBundle bundle, 1192 String className, String methodName, Supplier<String> msg) { 1193 if (BEST_EFFORT_FOR_LOGP && bundle == null 1194 && (className != null || methodName != null)) { 1195 final String cName = className == null ? "" : className; 1196 final String mName = methodName == null ? "" : methodName; 1197 return () -> { 1198 String m = msg.get(); 1199 return String.format("[%s %s] %s", cName, mName, m == null ? "" : m); 1200 }; 1201 } else { 1202 return msg; 1203 } 1204 } 1205 1206 public void testLogp(java.lang.System.Logger logger, String className, 1207 String methodName, String msg) { 1208 Checker<BackendRecord, Level> check = (res, l) -> { 1209 checkRecord("logp", res, logger.getName(), l, 1210 logpMessage(localized, className, methodName, () -> msg), 1211 adaptor().getCallerClassName( 1212 JdkLogMethodInvoker.LOGP_STRING, className), 1213 adaptor().getCallerClassName( 1214 JdkLogMethodInvoker.LOGP_STRING, methodName), 1215 null, localized); 1216 return null; 1217 }; 1218 JdkLogTester tester = (x, level) -> { 1219 JdkLogMethodInvoker.LOGP_STRING.logX(x, level, 1220 className, methodName, msg); 1221 return null; 1222 }; 1223 Function<String, String> nameProducer = (l) -> 1224 "logp(Level." + l + ", class, method, \"" + msg + "\")"; 1225 testJdkLog(logger, tester, check, nameProducer); 1226 } 1227 1228 public void testLogrb(java.lang.System.Logger logger, String className, 1229 String methodName, ResourceBundle bundle, String msg) { 1230 Checker<BackendRecord, Level> check = (res, l) -> { 1231 checkRecord("logp", res, logger.getName(), l, () -> msg, 1232 adaptor().getCallerClassName( 1233 JdkLogMethodInvoker.LOGRBP_STRING_PARAMS, className), 1234 adaptor().getCallerClassName( 1235 JdkLogMethodInvoker.LOGRBP_STRING_PARAMS, methodName), 1236 null, bundle); 1237 return null; 1238 }; 1239 JdkLogTester tester = (x, level) -> { 1240 JdkLogMethodInvoker.LOGRBP_STRING_PARAMS.logX(x, level, 1241 className, methodName, bundle, msg, (Object[])null); 1242 return null; 1243 }; 1244 Function<String, String> nameProducer = (l) -> 1245 "logp(Level." + l + ", class, method, bundle, \"" + msg + "\")"; 1246 testJdkLog(logger, tester, check, nameProducer); 1247 } 1248 1249 public void testLogp(java.lang.System.Logger logger, String className, 1250 String methodName, String msg, Object... params) { 1251 Checker<BackendRecord, Level> check = (res, l) -> { 1252 checkRecord("logp", res, logger.getName(), l, 1253 logpMessage(localized, className, methodName, () -> msg), 1254 adaptor().getCallerClassName( 1255 JdkLogMethodInvoker.LOGP_STRING_PARAMS, className), 1256 adaptor().getCallerClassName( 1257 JdkLogMethodInvoker.LOGP_STRING_PARAMS, methodName), 1258 null, localized, params); 1259 return null; 1260 }; 1261 JdkLogTester tester = (x, level) -> { 1262 JdkLogMethodInvoker.LOGP_STRING_PARAMS.logX(x, level, 1263 className, methodName, msg, params); 1264 return null; 1265 }; 1266 Function<String, String> nameProducer = (l) -> 1267 "log(Level." + l + ", class, method, \"" + msg + "\", params...)"; 1268 testJdkLog(logger, tester, check, nameProducer); 1269 } 1270 1271 public void testLogrb(java.lang.System.Logger logger, String className, 1272 String methodName, ResourceBundle bundle, String msg, 1273 Object... params) { 1274 Checker<BackendRecord, Level> check = (res, l) -> { 1275 checkRecord("logp", res, logger.getName(), l, () -> msg, 1276 adaptor().getCallerClassName( 1277 JdkLogMethodInvoker.LOGRBP_STRING_PARAMS, className), 1278 adaptor().getCallerClassName( 1279 JdkLogMethodInvoker.LOGRBP_STRING_PARAMS, methodName), 1280 null, bundle, params); 1281 return null; 1282 }; 1283 JdkLogTester tester = (x, level) -> { 1284 JdkLogMethodInvoker.LOGRBP_STRING_PARAMS.logX(x, level, 1285 className, methodName, bundle, msg, params); 1286 return null; 1287 }; 1288 Function<String, String> nameProducer = (l) -> 1289 "log(Level." + l + ", class, method, bundle, \"" 1290 + msg + "\", params...)"; 1291 testJdkLog(logger, tester, check, nameProducer); 1292 } 1293 1294 public void testLogp(java.lang.System.Logger logger, String className, 1295 String methodName, String msg, Throwable thrown) { 1296 Checker<BackendRecord, Level> check = (res, l) -> { 1297 checkRecord("log", res, logger.getName(), l, 1298 logpMessage(localized, className, methodName, () -> msg), 1299 adaptor().getCallerClassName( 1300 JdkLogMethodInvoker.LOGP_STRING_THROWN, className), 1301 adaptor().getCallerClassName( 1302 JdkLogMethodInvoker.LOGP_STRING_THROWN, methodName), 1303 thrown, localized); 1304 return null; 1305 }; 1306 JdkLogTester tester = (x, level) -> { 1307 JdkLogMethodInvoker.LOGP_STRING_THROWN.logX(x, level, 1308 className, methodName, msg, thrown); 1309 return null; 1310 }; 1311 Function<String, String> nameProducer = (l) -> 1312 "log(Level." + l + ", class, method, \"" + msg + "\", thrown)"; 1313 testJdkLog(logger, tester, check, nameProducer); 1314 } 1315 1316 public void testLogrb(java.lang.System.Logger logger, String className, 1317 String methodName, ResourceBundle bundle, 1318 String msg, Throwable thrown) { 1319 Checker<BackendRecord, Level> check = (res, l) -> { 1320 checkRecord("log", res, logger.getName(), l, () -> msg, 1321 adaptor().getCallerClassName( 1322 JdkLogMethodInvoker.LOGRBP_STRING_THROWN, className), 1323 adaptor().getCallerClassName( 1324 JdkLogMethodInvoker.LOGRBP_STRING_THROWN, methodName), 1325 thrown, bundle); 1326 return null; 1327 }; 1328 JdkLogTester tester = (x, level) -> { 1329 JdkLogMethodInvoker.LOGRBP_STRING_THROWN.logX(x, level, 1330 className, methodName, bundle, msg, thrown); 1331 return null; 1332 }; 1333 Function<String, String> nameProducer = (l) -> 1334 "log(Level." + l + ", class, method, bundle, \"" + msg + "\", thrown)"; 1335 testJdkLog(logger, tester, check, nameProducer); 1336 1337 } 1338 1339 public void testLogp(java.lang.System.Logger logger, String className, 1340 String methodName, Supplier<String> msg) { 1341 Checker<BackendRecord, Level> check = (res, l) -> { 1342 checkRecord("log", res, logger.getName(), l, 1343 logpMessage(null, className, methodName, msg), 1344 adaptor().getCallerClassName( 1345 JdkLogMethodInvoker.LOGP_SUPPLIER, className), 1346 adaptor().getCallerClassName( 1347 JdkLogMethodInvoker.LOGP_SUPPLIER, methodName), 1348 null, null); 1349 return null; 1350 }; 1351 JdkLogTester tester = (x, level) -> { 1352 JdkLogMethodInvoker.LOGP_SUPPLIER.logX(x, level, 1353 className, methodName, msg); 1354 return null; 1355 }; 1356 Function<String, String> nameProducer = (l) -> 1357 "log(Level." + l + ", class, method, () -> \"" + msg.get() + "\")"; 1358 testJdkLog(logger, tester, check, nameProducer); 1359 } 1360 1361 public void testLogp(java.lang.System.Logger logger, String className, 1362 String methodName, Throwable thrown, Supplier<String> msg) { 1363 Checker<BackendRecord, Level> check = (res, l) -> { 1364 checkRecord("log", res, logger.getName(), l, 1365 logpMessage(null, className, methodName, msg), 1366 adaptor().getCallerClassName( 1367 JdkLogMethodInvoker.LOGP_SUPPLIER_THROWN, className), 1368 adaptor().getCallerClassName( 1369 JdkLogMethodInvoker.LOGP_SUPPLIER_THROWN, methodName), 1370 thrown, null); 1371 return null; 1372 }; 1373 JdkLogTester tester = (x, level) -> { 1374 JdkLogMethodInvoker.LOGP_SUPPLIER_THROWN.logX(x, level, 1375 className, methodName, thrown, msg); 1376 return null; 1377 }; 1378 Function<String, String> nameProducer = (l) -> 1379 "log(Level." + l + ", class, method, () -> \"" + msg.get() + "\", thrown)"; 1380 testJdkLog(logger, tester, check, nameProducer); 1381 } 1382 1383 private void testJdkLog(java.lang.System.Logger logger, 1384 JdkLogTester log, Checker<BackendRecord,Level> check, 1385 Function<String, String> nameProducer) { 1386 if (restrictedTo != null) { 1387 if (!bridgeLoggerClass.isAssignableFrom(restrictedTo)) { 1388 if (VERBOSE) { 1389 System.out.println("Skipping method from " 1390 + bridgeLoggerClass); 1391 } 1392 return; 1393 } 1394 } 1395 System.out.println("Testing Logger." + nameProducer.apply("*") 1396 + " on " + logger); 1397 final BackendAdaptor adaptor = adaptor(); 1398 for (Level loggerLevel : LEVELS) { 1399 adaptor.setLevel(logger, loggerLevel); 1400 for (Level l : LEVELS) { 1401 check(logger, () -> log.apply(bridgeLoggerClass.cast(logger), l), 1402 check, () -> adaptor.isLoggable(logger, l), 1403 () -> adaptor.shouldBeLoggable(l, loggerLevel), 1404 l, loggerLevel, nameProducer.apply(l.toString())); 1405 } 1406 } 1407 } 1408 1409 private void testSpiLog(java.lang.System.Logger logger, 1410 SpiLogTester log, Checker<BackendRecord, java.lang.System.Logger.Level> check, 1411 Function<String, String> nameProducer) { 1412 System.out.println("Testing System.Logger." + nameProducer.apply("*") 1413 + " on " + logger); 1414 final BackendAdaptor adaptor = adaptor(); 1415 for (java.lang.System.Logger.Level loggerLevel : java.lang.System.Logger.Level.values()) { 1416 1417 adaptor.setLevel(logger, loggerLevel); 1418 for (java.lang.System.Logger.Level l : java.lang.System.Logger.Level.values()) { 1419 check(logger, () -> log.apply(logger, l), 1420 check, () -> logger.isLoggable(l), 1421 () -> adaptor.shouldBeLoggable(l, loggerLevel), 1422 l, loggerLevel, nameProducer.apply(l.toString())); 1423 } 1424 } 1425 } 1426 1427 private void test(String args, Levels level, java.lang.System.Logger logger, 1428 Runnable test, Checker<BackendRecord, Level> check) { 1429 if (restrictedTo != null) { 1430 if (!level.definingClass.isAssignableFrom(restrictedTo)) { 1431 if (VERBOSE) { 1432 System.out.println("Skipping method from " 1433 + level.definingClass); 1434 } 1435 return; 1436 } 1437 } 1438 String method = args.contains("bundle") ? "logrb" : "log"; 1439 System.out.println("Testing Logger." 1440 + method + "(Level." + level.platformLevel 1441 + ", "+ args + ")" + " on " + logger); 1442 final BackendAdaptor adaptor = adaptor(); 1443 for (Level loggerLevel : LEVELS) { 1444 adaptor.setLevel(logger, loggerLevel); 1445 check(logger, test, check, 1446 () -> level.isEnabled(logger), 1447 () -> adaptor.shouldBeLoggable(level, loggerLevel), 1448 level.platformLevel, loggerLevel, level.method); 1449 } 1450 } 1451 1452 private <L> void check(java.lang.System.Logger logger, 1453 Runnable test, Checker<BackendRecord,L> check, 1454 BooleanSupplier checkLevelEnabled, 1455 BooleanSupplier shouldBeLoggable, 1456 L logLevel, L loggerLevel, String logMethod) { 1457 final BackendAdaptor adaptor = adaptor(); 1458 adaptor.resetBackendRecords(); 1459 test.run(); 1460 final List<BackendRecord> records = adaptor.getBackendRecords(); 1461 if (shouldBeLoggable.getAsBoolean()) { 1462 if (!checkLevelEnabled.getAsBoolean()) { 1463 throw new RuntimeException("Logger is not enabled for " 1464 + logMethod 1465 + " although logger level is " + loggerLevel); 1466 } 1467 if (records.size() != 1) { 1468 throw new RuntimeException(loggerLevel + " [" + 1469 logLevel + "] : Unexpected record sizes: " 1470 + records.toString()); 1471 } 1472 BackendRecord res = records.get(0); 1473 check.apply(res, logLevel); 1474 } else { 1475 if (checkLevelEnabled.getAsBoolean()) { 1476 throw new RuntimeException("Logger is enabled for " 1477 + logMethod 1478 + " although logger level is " + loggerLevel); 1479 } 1480 if (!records.isEmpty()) { 1481 throw new RuntimeException(loggerLevel + " [" + 1482 logLevel + "] : Unexpected record sizes: " 1483 + records.toString()); 1484 } 1485 } 1486 } 1487 } 1488 1489 public static class JULBackendTester extends BackendTester<LogRecord>{ 1490 1491 public JULBackendTester(boolean isSystem) { 1492 this(isSystem,null,null); 1493 } 1494 public JULBackendTester(boolean isSystem, ResourceBundle localized) { 1495 this(isSystem,null,localized); 1496 } 1497 public JULBackendTester(boolean isSystem, 1498 Class<? extends java.lang.System.Logger> restrictedTo) { 1499 this(isSystem, restrictedTo, null); 1500 } 1501 public JULBackendTester(boolean isSystem, 1502 Class<? extends java.lang.System.Logger> restrictedTo, 1503 ResourceBundle localized) { 1504 super(isSystem, restrictedTo, localized); 1505 } 1506 1507 Logger getBackendLogger(String name) { 1508 if (isSystem) { 1509 return LoggingProviderImpl.getLogManagerAccess().demandLoggerFor( 1510 LogManager.getLogManager(), name, Thread.class.getModule()); 1511 } else { 1512 return Logger.getLogger(name); 1513 } 1514 } 1515 1516 class JULBackendAdaptor extends BackendAdaptor { 1517 @Override 1518 public String getLoggerName(LogRecord res) { 1519 return res.getLoggerName(); 1520 } 1521 @Override 1522 public Level getLevel(LogRecord res) { 1523 return Level.valueOf(res.getLevel().getName()); 1524 } 1525 @Override 1526 public String getMessage(LogRecord res) { 1527 return res.getMessage(); 1528 } 1529 @Override 1530 public String getSourceClassName(LogRecord res) { 1531 return res.getSourceClassName(); 1532 } 1533 @Override 1534 public String getSourceMethodName(LogRecord res) { 1535 return res.getSourceMethodName(); 1536 } 1537 @Override 1538 public Throwable getThrown(LogRecord res) { 1539 return res.getThrown(); 1540 } 1541 @Override 1542 public ResourceBundle getResourceBundle(LogRecord res) { 1543 return res.getResourceBundle(); 1544 } 1545 @Override 1546 public void setLevel(java.lang.System.Logger logger, Level level) { 1547 Logger backend = getBackendLogger(logger.getName()); 1548 backend.setLevel(java.util.logging.Level.parse(level.name())); 1549 } 1550 @Override 1551 public void setLevel(java.lang.System.Logger logger, java.lang.System.Logger.Level level) { 1552 setLevel(logger, toJUL(level)); 1553 } 1554 @Override 1555 public List<LogRecord> getBackendRecords() { 1556 return handler.records; 1557 } 1558 @Override 1559 public void resetBackendRecords() { 1560 handler.reset(); 1561 } 1562 @Override 1563 public Level getMappedLevel(Object level) { 1564 if (level instanceof java.lang.System.Logger.Level) { 1565 return toJUL((java.lang.System.Logger.Level)level); 1566 } 1567 return (Level)level; 1568 } 1569 } 1570 1571 final JULBackendAdaptor julAdaptor = new JULBackendAdaptor(); 1572 1573 @Override 1574 BackendAdaptor adaptor() { 1575 return julAdaptor; 1576 } 1577 1578 } 1579 1580 public abstract static class BackendTesterFactory { 1581 public abstract BackendTester createBackendTester(boolean isSystem); 1582 public abstract BackendTester createBackendTester(boolean isSystem, 1583 Class<? extends java.lang.System.Logger> restrictedTo); 1584 public abstract BackendTester createBackendTester(boolean isSystem, 1585 Class<? extends java.lang.System.Logger> restrictedTo, 1586 ResourceBundle bundle); 1587 public abstract BackendTester createBackendTester(boolean isSystem, 1588 ResourceBundle bundle); 1589 } 1590 1591 public static class JULBackendTesterFactory extends BackendTesterFactory { 1592 1593 @Override 1594 public BackendTester createBackendTester(boolean isSystem) { 1595 return new JULBackendTester(isSystem); 1596 } 1597 1598 @Override 1599 public BackendTester createBackendTester(boolean isSystem, 1600 Class<? extends java.lang.System.Logger> restrictedTo) { 1601 return new JULBackendTester(isSystem, restrictedTo); 1602 } 1603 1604 @Override 1605 public BackendTester createBackendTester(boolean isSystem, 1606 Class<? extends java.lang.System.Logger> restrictedTo, 1607 ResourceBundle bundle) { 1608 return new JULBackendTester(isSystem, restrictedTo, bundle); 1609 } 1610 1611 @Override 1612 public BackendTester createBackendTester(boolean isSystem, 1613 ResourceBundle bundle) { 1614 return new JULBackendTester(isSystem, bundle); 1615 } 1616 } 1617 1618 public static class CustomLoggerFinder extends LoggerFinder { 1619 1620 static enum CustomLevel { OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE, ALL }; 1621 static CustomLevel[] customLevelMap = { CustomLevel.ALL, 1622 CustomLevel.TRACE, CustomLevel.DEBUG, CustomLevel.INFO, 1623 CustomLevel.WARN, CustomLevel.ERROR, CustomLevel.OFF 1624 }; 1625 static class CustomLogRecord { 1626 public final CustomLevel logLevel; 1627 public final java.lang.System.Logger logger; 1628 public final String msg; 1629 public final Object[] params; 1630 public final Throwable thrown; 1631 public final ResourceBundle bundle; 1632 1633 CustomLogRecord(java.lang.System.Logger producer, 1634 CustomLevel level, String msg) { 1635 this(producer, level, msg, (ResourceBundle)null, (Throwable)null, (Object[])null); 1636 } 1637 1638 CustomLogRecord(java.lang.System.Logger producer, 1639 CustomLevel level, String msg, ResourceBundle bundle, 1640 Throwable thrown, Object... params) { 1641 this.logger = producer; 1642 this.logLevel = level; 1643 this.msg = msg; 1644 this.params = params; 1645 this.thrown = thrown; 1646 this.bundle = bundle; 1647 } 1648 } 1649 1650 static final List<CustomLogRecord> records = 1651 Collections.synchronizedList(new ArrayList<>()); 1652 1653 static class CustomLogger implements java.lang.System.Logger { 1654 1655 final String name; 1656 volatile CustomLevel level; 1657 CustomLogger(String name) { 1658 this.name = name; 1659 this.level = CustomLevel.INFO; 1660 } 1661 1662 @Override 1663 public String getName() { 1664 return name; 1665 } 1666 1667 public void setLevel(CustomLevel level) { 1668 this.level = level; 1669 } 1670 1671 1672 @Override 1673 public boolean isLoggable(java.lang.System.Logger.Level level) { 1674 1675 return this.level != CustomLevel.OFF && this.level.ordinal() 1676 >= customLevelMap[level.ordinal()].ordinal(); 1677 } 1678 1679 @Override 1680 public void log(java.lang.System.Logger.Level level, ResourceBundle bundle, String key, Throwable thrown) { 1681 if (isLoggable(level)) { 1682 records.add(new CustomLogRecord(this, customLevelMap[level.ordinal()], 1683 key, bundle, thrown)); 1684 } 1685 } 1686 1687 @Override 1688 public void log(java.lang.System.Logger.Level level, ResourceBundle bundle, String format, Object... params) { 1689 if (isLoggable(level)) { 1690 records.add(new CustomLogRecord(this, customLevelMap[level.ordinal()], 1691 format, bundle, null, params)); 1692 } 1693 } 1694 1695 } 1696 1697 final Map<String, java.lang.System.Logger> applicationLoggers = 1698 Collections.synchronizedMap(new HashMap<>()); 1699 final Map<String, java.lang.System.Logger> systemLoggers = 1700 Collections.synchronizedMap(new HashMap<>()); 1701 1702 @Override 1703 public java.lang.System.Logger getLogger(String name, Module caller) { 1704 ClassLoader callerLoader = caller.getClassLoader(); 1705 if (callerLoader == null) { 1706 systemLoggers.putIfAbsent(name, new CustomLogger(name)); 1707 return systemLoggers.get(name); 1708 } else { 1709 applicationLoggers.putIfAbsent(name, new CustomLogger(name)); 1710 return applicationLoggers.get(name); 1711 } 1712 } 1713 1714 CustomLevel fromJul(Level level) { 1715 if (level.intValue() == Level.OFF.intValue()) { 1716 return CustomLevel.OFF; 1717 } else if (level.intValue() > Level.SEVERE.intValue()) { 1718 return CustomLevel.ERROR; 1719 } else if (level.intValue() > Level.WARNING.intValue()) { 1720 return CustomLevel.ERROR; 1721 } else if (level.intValue() > Level.INFO.intValue()) { 1722 return CustomLevel.WARN; 1723 } else if (level.intValue() > Level.CONFIG.intValue()) { 1724 return CustomLevel.INFO; 1725 } else if (level.intValue() > Level.FINER.intValue()) { 1726 return CustomLevel.DEBUG; 1727 } else if (level.intValue() > Level.FINEST.intValue()) { 1728 return CustomLevel.TRACE; 1729 } else if (level.intValue() == Level.ALL.intValue()) { 1730 return CustomLevel.ALL; 1731 } else { 1732 return CustomLevel.TRACE; 1733 } 1734 } 1735 1736 Level toJul(CustomLevel level) { 1737 switch(level) { 1738 case OFF: return Level.OFF; 1739 case FATAL: return Level.SEVERE; 1740 case ERROR: return Level.SEVERE; 1741 case WARN: return Level.WARNING; 1742 case INFO: return Level.INFO; 1743 case DEBUG: return Level.FINE; 1744 case TRACE: return Level.FINER; 1745 case ALL: return Level.ALL; 1746 default: throw new InternalError("No such level: "+level); 1747 } 1748 } 1749 1750 } 1751 1752 public static class CustomBackendTester extends 1753 BackendTester<CustomLoggerFinder.CustomLogRecord> { 1754 1755 public final CustomLoggerFinder provider; 1756 1757 public CustomBackendTester(boolean isSystem) { 1758 this(isSystem, null, null); 1759 } 1760 1761 public CustomBackendTester(boolean isSystem, 1762 Class<? extends java.lang.System.Logger> restrictedTo) { 1763 this(isSystem, restrictedTo, null); 1764 } 1765 1766 public CustomBackendTester(boolean isSystem, 1767 ResourceBundle localized) { 1768 this(isSystem, null, localized); 1769 } 1770 1771 public CustomBackendTester(boolean isSystem, 1772 Class<? extends java.lang.System.Logger> restrictedTo, 1773 ResourceBundle localized) { 1774 super(isSystem, restrictedTo, localized); 1775 provider = (CustomLoggerFinder)java.lang.System.LoggerFinder.getLoggerFinder(); 1776 } 1777 1778 @Override 1779 public java.lang.System.Logger convert(java.lang.System.Logger logger) { 1780 if (restrictedTo != null && restrictedTo.isInstance(logger)) { 1781 return logger; 1782 } else if (restrictedTo == jdkLoggerClass) { 1783 return logger; 1784 } else { 1785 return java.lang.System.Logger.class.cast( 1786 sun.util.logging.PlatformLogger.Bridge.convert(logger)); 1787 } 1788 } 1789 1790 class CustomBackendAdaptor extends BackendAdaptor { 1791 1792 @Override 1793 public String getLoggerName(CustomLoggerFinder.CustomLogRecord res) { 1794 return res.logger.getName(); 1795 } 1796 1797 @Override 1798 public CustomLoggerFinder.CustomLevel getLevel(CustomLoggerFinder.CustomLogRecord res) { 1799 return res.logLevel; 1800 } 1801 1802 @Override 1803 public String getMessage(CustomLoggerFinder.CustomLogRecord res) { 1804 return res.msg; 1805 } 1806 1807 @Override // we don't support source class name in our custom provider implementation 1808 public String getSourceClassName(CustomLoggerFinder.CustomLogRecord res) { 1809 return null; 1810 } 1811 1812 @Override // we don't support source method name in our custom provider implementation 1813 public String getSourceMethodName(CustomLoggerFinder.CustomLogRecord res) { 1814 return null; 1815 } 1816 1817 @Override 1818 public Throwable getThrown(CustomLoggerFinder.CustomLogRecord res) { 1819 return res.thrown; 1820 } 1821 1822 @Override 1823 public ResourceBundle getResourceBundle(CustomLoggerFinder.CustomLogRecord res) { 1824 return res.bundle; 1825 } 1826 1827 @Override 1828 public void setLevel(java.lang.System.Logger logger, Level level) { 1829 final CustomLoggerFinder.CustomLogger l = 1830 (CustomLoggerFinder.CustomLogger) 1831 (isSystem ? provider.getLogger(logger.getName(), Thread.class.getModule()) : 1832 provider.getLogger(logger.getName(), LoggerFinderBackendTest.class.getModule())); 1833 l.setLevel(provider.fromJul(level)); 1834 } 1835 @Override 1836 public void setLevel(java.lang.System.Logger logger, 1837 java.lang.System.Logger.Level level) { 1838 setLevel(logger, toJUL(level)); 1839 } 1840 1841 CustomLoggerFinder.CustomLevel getLevel(java.lang.System.Logger logger) { 1842 final CustomLoggerFinder.CustomLogger l = 1843 (CustomLoggerFinder.CustomLogger) 1844 (isSystem ? provider.getLogger(logger.getName(), Thread.class.getModule()) : 1845 provider.getLogger(logger.getName(), LoggerFinderBackendTest.class.getModule())); 1846 return l.level; 1847 } 1848 1849 @Override 1850 public List<CustomLoggerFinder.CustomLogRecord> getBackendRecords() { 1851 return CustomLoggerFinder.records; 1852 } 1853 1854 @Override 1855 public void resetBackendRecords() { 1856 CustomLoggerFinder.records.clear(); 1857 } 1858 1859 @Override 1860 public boolean shouldBeLoggable(Levels level, Level loggerLevel) { 1861 return loggerLevel != Level.OFF && 1862 fromLevels(level).ordinal() <= provider.fromJul(loggerLevel).ordinal(); 1863 } 1864 1865 @Override 1866 public boolean isLoggable(java.lang.System.Logger logger, Level l) { 1867 return super.isLoggable(logger, l); 1868 } 1869 1870 @Override 1871 public boolean shouldBeLoggable(Level logLevel, Level loggerLevel) { 1872 return loggerLevel != Level.OFF && 1873 provider.fromJul(logLevel).ordinal() <= provider.fromJul(loggerLevel).ordinal(); 1874 } 1875 1876 @Override // we don't support source class name in our custom provider implementation 1877 public String getCallerClassName(Levels level, String clazz) { 1878 return null; 1879 } 1880 1881 @Override // we don't support source method name in our custom provider implementation 1882 public String getCallerMethodName(Levels level, String method) { 1883 return null; 1884 } 1885 1886 @Override // we don't support source class name in our custom provider implementation 1887 public String getCallerClassName(MethodInvoker<?,?> logMethod, String clazz) { 1888 return null; 1889 } 1890 1891 @Override // we don't support source method name in our custom provider implementation 1892 public String getCallerMethodName(MethodInvoker<?,?> logMethod, String method) { 1893 return null; 1894 } 1895 1896 @Override 1897 public CustomLoggerFinder.CustomLevel getMappedLevel(Object level) { 1898 if (level instanceof java.lang.System.Logger.Level) { 1899 final int index = ((java.lang.System.Logger.Level)level).ordinal(); 1900 return CustomLoggerFinder.customLevelMap[index]; 1901 } else if (level instanceof Level) { 1902 return provider.fromJul((Level)level); 1903 } 1904 return (CustomLoggerFinder.CustomLevel) level; 1905 } 1906 1907 CustomLoggerFinder.CustomLevel fromLevels(Levels level) { 1908 switch(level) { 1909 case SEVERE: 1910 return CustomLoggerFinder.CustomLevel.ERROR; 1911 case WARNING: 1912 return CustomLoggerFinder.CustomLevel.WARN; 1913 case INFO: 1914 return CustomLoggerFinder.CustomLevel.INFO; 1915 case CONFIG: case FINE: 1916 return CustomLoggerFinder.CustomLevel.DEBUG; 1917 case FINER: case FINEST: 1918 return CustomLoggerFinder.CustomLevel.TRACE; 1919 } 1920 throw new InternalError("No such level "+level); 1921 } 1922 1923 } 1924 1925 @Override 1926 BackendAdaptor adaptor() { 1927 return new CustomBackendAdaptor(); 1928 } 1929 1930 } 1931 1932 public static class CustomBackendTesterFactory extends BackendTesterFactory { 1933 1934 @Override 1935 public BackendTester createBackendTester(boolean isSystem) { 1936 return new CustomBackendTester(isSystem); 1937 } 1938 1939 @Override 1940 public BackendTester createBackendTester(boolean isSystem, 1941 Class<? extends java.lang.System.Logger> restrictedTo) { 1942 return new CustomBackendTester(isSystem, restrictedTo); 1943 } 1944 1945 @Override 1946 public BackendTester createBackendTester(boolean isSystem, 1947 Class<? extends java.lang.System.Logger> restrictedTo, 1948 ResourceBundle bundle) { 1949 return new CustomBackendTester(isSystem, restrictedTo, bundle); 1950 } 1951 1952 @Override 1953 public BackendTester createBackendTester(boolean isSystem, 1954 ResourceBundle bundle) { 1955 return new CustomBackendTester(isSystem, bundle); 1956 } 1957 } 1958 1959 static final Method getLazyLogger; 1960 static final Method accessLoggerFinder; 1961 static { 1962 // jdk.internal.logger.LazyLoggers.getLazyLogger(name, caller); 1963 try { 1964 Class<?> lazyLoggers = jdk.internal.logger.LazyLoggers.class; 1965 getLazyLogger = lazyLoggers.getMethod("getLazyLogger", 1966 String.class, Module.class); 1967 getLazyLogger.setAccessible(true); 1968 Class<?> loggerFinderLoader = 1969 Class.forName("java.lang.System$LoggerFinder"); 1970 accessLoggerFinder = loggerFinderLoader.getDeclaredMethod("accessProvider"); 1971 accessLoggerFinder.setAccessible(true); 1972 } catch (Throwable ex) { 1973 throw new ExceptionInInitializerError(ex); 1974 } 1975 } 1976 1977 static java.lang.System.Logger getSystemLogger(String name, Module caller) throws Exception { 1978 try { 1979 return java.lang.System.Logger.class.cast(getLazyLogger.invoke(null, name, caller)); 1980 } catch (InvocationTargetException x) { 1981 Throwable t = x.getTargetException(); 1982 if (t instanceof Exception) { 1983 throw (Exception)t; 1984 } else { 1985 throw (Error)t; 1986 } 1987 } 1988 } 1989 static java.lang.System.Logger getSystemLogger(String name, 1990 ResourceBundle bundle, Module caller) throws Exception { 1991 try { 1992 LoggerFinder provider = LoggerFinder.class.cast(accessLoggerFinder.invoke(null)); 1993 return provider.getLocalizedLogger(name, bundle, caller); 1994 } catch (InvocationTargetException x) { 1995 Throwable t = x.getTargetException(); 1996 if (t instanceof Exception) { 1997 throw (Exception)t; 1998 } else { 1999 throw (Error)t; 2000 } 2001 } 2002 } 2003 2004 // Change this to 'true' to get more traces... 2005 public static boolean verbose = false; 2006 2007 public static void main(String[] argv) throws Exception { 2008 2009 final AtomicInteger nb = new AtomicInteger(0); 2010 final boolean hidesProvider = Boolean.getBoolean("test.logger.hidesProvider"); 2011 System.out.println(ClassLoader.getSystemClassLoader()); 2012 final BackendTesterFactory factory; 2013 if (java.lang.System.LoggerFinder.getLoggerFinder() instanceof CustomLoggerFinder) { 2014 if (hidesProvider) { 2015 System.err.println("Custom backend " 2016 + java.lang.System.LoggerFinder.getLoggerFinder() 2017 + " should have been hidden!"); 2018 throw new RuntimeException( 2019 "Custom backend should have been hidden: " 2020 + "check value of java.system.class.loader property"); 2021 } 2022 System.out.println("Using custom backend"); 2023 factory = new CustomBackendTesterFactory(); 2024 } else { 2025 if (!hidesProvider) { 2026 System.err.println("Default JUL backend " 2027 + java.lang.System.LoggerFinder.getLoggerFinder() 2028 + " should have been hidden!"); 2029 throw new RuntimeException( 2030 "Default JUL backend should have been hidden: " 2031 + "check value of java.system.class.loader property"); 2032 } 2033 System.out.println("Using JUL backend"); 2034 factory = new JULBackendTesterFactory(); 2035 } 2036 2037 testBackend(nb, factory); 2038 } 2039 2040 public static void testBackend(AtomicInteger nb, BackendTesterFactory factory) throws Exception { 2041 2042 // Tests all level specifics methods with loggers configured with 2043 // all possible levels and loggers obtained with all possible 2044 // entry points from LoggerFactory and JdkLoggerFactory, with 2045 // JUL as backend. 2046 2047 // Test a simple application logger with JUL backend 2048 final BackendTester tester = factory.createBackendTester(false); 2049 final java.lang.System.Logger logger = 2050 java.lang.System.LoggerFinder.getLoggerFinder() 2051 .getLogger("foo", LoggerFinderBackendTest.class.getModule()); 2052 2053 testLogger(tester, logger, nb); 2054 2055 // Test a simple system logger with JUL backend 2056 final java.lang.System.Logger system = 2057 java.lang.System.LoggerFinder.getLoggerFinder() 2058 .getLogger("bar", Thread.class.getModule()); 2059 final BackendTester systemTester = factory.createBackendTester(true); 2060 testLogger(systemTester, system, nb); 2061 2062 // Test a localized application logger with null resource bundle and 2063 // JUL backend 2064 final java.lang.System.Logger noBundleLogger = 2065 java.lang.System.LoggerFinder.getLoggerFinder() 2066 .getLocalizedLogger("baz", null, LoggerFinderBackendTest.class.getModule()); 2067 final BackendTester noBundleTester = 2068 factory.createBackendTester(false, spiLoggerClass); 2069 testLogger(noBundleTester, noBundleLogger, nb); 2070 2071 // Test a localized system logger with null resource bundle and JUL 2072 // backend 2073 final java.lang.System.Logger noBundleSysLogger = 2074 java.lang.System.LoggerFinder.getLoggerFinder() 2075 .getLocalizedLogger("oof", null, Thread.class.getModule()); 2076 final BackendTester noBundleSysTester = 2077 factory.createBackendTester(true, spiLoggerClass); 2078 testLogger(noBundleSysTester, noBundleSysLogger, nb); 2079 2080 // Test a localized application logger with null resource bundle and 2081 // JUL backend 2082 try { 2083 System.getLogger("baz", null); 2084 throw new RuntimeException("Expected NullPointerException not thrown"); 2085 } catch (NullPointerException x) { 2086 System.out.println("System.Loggers.getLogger(\"baz\", null): got expected " + x); 2087 } 2088 final java.lang.System.Logger noBundleExtensionLogger = 2089 getSystemLogger("baz", null, LoggerFinderBackendTest.class.getModule()); 2090 final BackendTester noBundleExtensionTester = 2091 factory.createBackendTester(false, jdkLoggerClass); 2092 testLogger(noBundleExtensionTester, noBundleExtensionLogger, nb); 2093 2094 // Test a simple system logger with JUL backend 2095 final java.lang.System.Logger sysExtensionLogger = 2096 getSystemLogger("oof", Thread.class.getModule()); 2097 final BackendTester sysExtensionTester = 2098 factory.createBackendTester(true, jdkLoggerClass); 2099 testLogger(sysExtensionTester, sysExtensionLogger, nb); 2100 2101 // Test a localized system logger with null resource bundle and JUL 2102 // backend 2103 final java.lang.System.Logger noBundleSysExtensionLogger = 2104 getSystemLogger("oof", null, Thread.class.getModule()); 2105 final BackendTester noBundleSysExtensionTester = 2106 factory.createBackendTester(true, jdkLoggerClass); 2107 testLogger(noBundleSysExtensionTester, noBundleSysExtensionLogger, nb); 2108 2109 // Test a localized application logger converted to JDK with null 2110 // resource bundle and JUL backend 2111 final java.lang.System.Logger noBundleConvertedLogger = 2112 (java.lang.System.Logger) 2113 sun.util.logging.PlatformLogger.Bridge.convert(noBundleLogger); 2114 final BackendTester noBundleJdkTester = factory.createBackendTester(false); 2115 testLogger(noBundleJdkTester, noBundleConvertedLogger, nb); 2116 2117 // Test a localized system logger converted to JDK with null resource 2118 // bundle and JUL backend 2119 final java.lang.System.Logger noBundleConvertedSysLogger = 2120 (java.lang.System.Logger) 2121 sun.util.logging.PlatformLogger.Bridge.convert(noBundleSysLogger); 2122 final BackendTester noBundleJdkSysTester = factory.createBackendTester(true); 2123 testLogger(noBundleJdkSysTester, noBundleConvertedSysLogger, nb); 2124 2125 // Test a localized application logger with resource bundle and JUL 2126 // backend 2127 final ResourceBundle bundle = 2128 ResourceBundle.getBundle(ResourceBundeLocalized.class.getName()); 2129 final java.lang.System.Logger bundleLogger = 2130 java.lang.System.LoggerFinder.getLoggerFinder() 2131 .getLocalizedLogger("toto", bundle, LoggerFinderBackendTest.class.getModule()); 2132 final BackendTester bundleTester = 2133 factory.createBackendTester(false, spiLoggerClass, bundle); 2134 testLogger(bundleTester, bundleLogger, nb); 2135 2136 // Test a localized system logger with resource bundle and JUL backend 2137 final java.lang.System.Logger bundleSysLogger = 2138 java.lang.System.LoggerFinder.getLoggerFinder() 2139 .getLocalizedLogger("titi", bundle, Thread.class.getModule()); 2140 final BackendTester bundleSysTester = 2141 factory.createBackendTester(true, spiLoggerClass, bundle); 2142 testLogger(bundleSysTester, bundleSysLogger, nb); 2143 2144 // Test a localized Jdk application logger with resource bundle and JUL 2145 // backend 2146 final java.lang.System.Logger bundleExtensionLogger = 2147 System.getLogger("tita", bundle); 2148 final BackendTester bundleExtensionTester = 2149 factory.createBackendTester(false, jdkLoggerClass, bundle); 2150 testLogger(bundleExtensionTester, bundleExtensionLogger, nb); 2151 2152 // Test a localized Jdk system logger with resource bundle and JUL 2153 // backend 2154 final java.lang.System.Logger bundleExtensionSysLogger = 2155 getSystemLogger("titu", bundle, Thread.class.getModule()); 2156 final BackendTester bundleExtensionSysTester = 2157 factory.createBackendTester(true, jdkLoggerClass, bundle); 2158 testLogger(bundleExtensionSysTester, bundleExtensionSysLogger, nb); 2159 2160 // Test a localized application logger converted to JDK with resource 2161 // bundle and JUL backend 2162 final BackendTester bundleJdkTester = 2163 factory.createBackendTester(false, bundle); 2164 final java.lang.System.Logger bundleConvertedLogger = 2165 (java.lang.System.Logger) 2166 sun.util.logging.PlatformLogger.Bridge.convert(bundleLogger); 2167 testLogger(bundleJdkTester, bundleConvertedLogger, nb); 2168 2169 // Test a localized Jdk system logger converted to JDK with resource 2170 // bundle and JUL backend 2171 final BackendTester bundleJdkSysTester = 2172 factory.createBackendTester(true, bundle); 2173 final java.lang.System.Logger bundleConvertedSysLogger = 2174 (java.lang.System.Logger) 2175 sun.util.logging.PlatformLogger.Bridge.convert(bundleSysLogger); 2176 testLogger(bundleJdkSysTester, bundleConvertedSysLogger, nb); 2177 2178 // Now need to add tests for all the log/logp/logrb methods... 2179 2180 } 2181 2182 private static class FooObj { 2183 final String s; 2184 FooObj(String s) { 2185 this.s = s; 2186 } 2187 2188 @Override 2189 public String toString() { 2190 return super.toString() +": "+s; 2191 } 2192 2193 } 2194 2195 public static void testLogger(BackendTester tester, 2196 java.lang.System.Logger spiLogger, AtomicInteger nb) { 2197 2198 // Test all level-specific method forms: 2199 // fatal(...) error(...) severe(...) etc... 2200 java.lang.System.Logger jdkLogger = tester.convert(spiLogger); 2201 for (Levels l : Levels.values()) { 2202 java.lang.System.Logger logger = 2203 l.definingClass.equals(spiLoggerClass) ? spiLogger : jdkLogger; 2204 tester.testLevel(l, logger, l.method + "[" + logger.getName()+ "]-" 2205 + nb.incrementAndGet()); 2206 tester.testLevel(l, logger, l.method + "[" + logger.getName()+ "]-" 2207 + nb.incrementAndGet(), 2208 bundleParam); 2209 final int nbb = nb.incrementAndGet(); 2210 tester.testLevel(l, logger, () -> l.method + "[" + logger.getName() 2211 + "]-" + nbb); 2212 } 2213 for (Levels l : Levels.values()) { 2214 java.lang.System.Logger logger = 2215 l.definingClass.equals(spiLoggerClass) ? spiLogger : jdkLogger; 2216 tester.testLevel(l, logger, 2217 l.method + "[" + logger.getName()+ "]({0},{1})-" 2218 + nb.incrementAndGet(), 2219 "One", "Two"); 2220 tester.testLevel(l, logger, 2221 l.method + "[" + logger.getName()+ "]({0},{1})-" 2222 + nb.incrementAndGet(), 2223 bundleParam, "One", "Two"); 2224 } 2225 final Throwable thrown = new RuntimeException("Test"); 2226 for (Levels l : Levels.values()) { 2227 java.lang.System.Logger logger = 2228 l.definingClass.equals(spiLoggerClass) ? spiLogger : jdkLogger; 2229 tester.testLevel(l, logger, l.method + "[" + logger.getName()+ "]-" 2230 + nb.incrementAndGet(), 2231 thrown); 2232 tester.testLevel(l, logger, l.method + "[" + logger.getName()+ "]-" 2233 + nb.incrementAndGet(), 2234 bundleParam, thrown); 2235 final int nbb = nb.incrementAndGet(); 2236 tester.testLevel(l, logger, ()->l.method + "[" + logger.getName()+ "]-" 2237 + nbb, thrown); 2238 } 2239 2240 java.lang.System.Logger logger = jdkLogger; 2241 2242 // test System.Logger methods 2243 tester.testSpiLog(logger, "[" + logger.getName()+ "]-" 2244 + nb.incrementAndGet()); 2245 tester.testSpiLog(logger, bundleParam, "[" + logger.getName()+ "]-" 2246 + nb.incrementAndGet()); 2247 tester.testSpiLog(logger, "[" + logger.getName()+ "]-({0},{1})" 2248 + nb.incrementAndGet(), "One", "Two"); 2249 tester.testSpiLog(logger, bundleParam, "[" + logger.getName()+ "]-({0},{1})" 2250 + nb.incrementAndGet(), "One", "Two"); 2251 tester.testSpiLog(logger, "[" + logger.getName()+ "]-" 2252 + nb.incrementAndGet(), thrown); 2253 tester.testSpiLog(logger, bundleParam, "[" + logger.getName()+ "]-" 2254 + nb.incrementAndGet(), thrown); 2255 final int nbb01 = nb.incrementAndGet(); 2256 tester.testSpiLog(logger, () -> "[" + logger.getName()+ "]-" + nbb01); 2257 final int nbb02 = nb.incrementAndGet(); 2258 tester.testSpiLog(logger, thrown, () -> "[" + logger.getName()+ "]-" + nbb02); 2259 final int nbb03 = nb.incrementAndGet(); 2260 tester.testSpiLog(logger, new FooObj("[" + logger.getName()+ "]-" + nbb03)); 2261 2262 // Test all log method forms: 2263 // jdk.internal.logging.Logger.log(...) 2264 tester.testLog(logger, "[" + logger.getName()+ "]-" 2265 + nb.incrementAndGet()); 2266 tester.testLogrb(logger, bundleParam, "[" + logger.getName()+ "]-" 2267 + nb.incrementAndGet()); 2268 tester.testLog(logger, "[" + logger.getName()+ "]-({0},{1})" 2269 + nb.incrementAndGet(), "One", "Two"); 2270 tester.testLogrb(logger, bundleParam, "[" + logger.getName()+ "]-({0},{1})" 2271 + nb.incrementAndGet(), "One", "Two"); 2272 tester.testLog(logger, "[" + logger.getName()+ "]-" 2273 + nb.incrementAndGet(), thrown); 2274 tester.testLogrb(logger, bundleParam, "[" + logger.getName()+ "]-" 2275 + nb.incrementAndGet(), thrown); 2276 final int nbb1 = nb.incrementAndGet(); 2277 tester.testLog(logger, () -> "[" + logger.getName()+ "]-" + nbb1); 2278 final int nbb2 = nb.incrementAndGet(); 2279 tester.testLog(logger, thrown, () -> "[" + logger.getName()+ "]-" + nbb2); 2280 2281 // Test all logp method forms 2282 // jdk.internal.logging.Logger.logp(...) 2283 tester.testLogp(logger, "clazz" + nb.incrementAndGet(), 2284 "method" + nb.incrementAndGet(), 2285 "[" + logger.getName()+ "]-" 2286 + nb.incrementAndGet()); 2287 tester.testLogrb(logger, "clazz" + nb.incrementAndGet(), 2288 "method" + nb.incrementAndGet(), bundleParam, 2289 "[" + logger.getName()+ "]-" 2290 + nb.incrementAndGet()); 2291 tester.testLogp(logger, "clazz" + nb.incrementAndGet(), 2292 "method" + nb.incrementAndGet(), 2293 "[" + logger.getName()+ "]-({0},{1})" 2294 + nb.incrementAndGet(), "One", "Two"); 2295 tester.testLogrb(logger, "clazz" + nb.incrementAndGet(), 2296 "method" + nb.incrementAndGet(), bundleParam, 2297 "[" + logger.getName()+ "]-({0},{1})" 2298 + nb.incrementAndGet(), "One", "Two"); 2299 tester.testLogp(logger, "clazz" + nb.incrementAndGet(), 2300 "method" + nb.incrementAndGet(), 2301 "[" + logger.getName()+ "]-" 2302 + nb.incrementAndGet(), thrown); 2303 tester.testLogrb(logger, "clazz" + nb.incrementAndGet(), 2304 "method" + nb.incrementAndGet(), bundleParam, 2305 "[" + logger.getName()+ "]-" 2306 + nb.incrementAndGet(), thrown); 2307 final int nbb3 = nb.incrementAndGet(); 2308 tester.testLogp(logger, "clazz" + nb.incrementAndGet(), 2309 "method" + nb.incrementAndGet(), 2310 () -> "[" + logger.getName()+ "]-" + nbb3); 2311 final int nbb4 = nb.incrementAndGet(); 2312 tester.testLogp(logger, "clazz" + nb.incrementAndGet(), 2313 "method" + nb.incrementAndGet(), 2314 thrown, () -> "[" + logger.getName()+ "]-" + nbb4); 2315 } 2316 2317 }