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 import java.security.AccessControlException; 24 import java.security.CodeSource; 25 import java.security.Permission; 26 import java.security.PermissionCollection; 27 import java.security.Permissions; 28 import java.security.Policy; 29 import java.security.ProtectionDomain; 30 import java.util.Arrays; 31 import java.util.Collections; 32 import java.util.Enumeration; 33 import java.util.HashMap; 34 import java.util.Map; 35 import java.util.Objects; 36 import java.util.Queue; 37 import java.util.ResourceBundle; 38 import java.util.concurrent.ArrayBlockingQueue; 39 import java.util.concurrent.ConcurrentHashMap; 40 import java.util.concurrent.atomic.AtomicBoolean; 41 import java.util.concurrent.atomic.AtomicLong; 42 import java.util.function.Supplier; 43 import java.util.logging.Handler; 44 import java.util.logging.LogManager; 45 import sun.util.logging.PlatformLogger; 46 import java.util.logging.LogRecord; 47 import java.lang.System.LoggerFinder; 48 import java.lang.System.Logger; 49 import java.util.stream.Stream; 50 import sun.util.logging.internal.LoggingProviderImpl; 51 52 /** 53 * @test 54 * @bug 8140364 55 * @summary JDK implementation specific unit test for JDK internal artifacts. 56 * Tests all internal bridge methods with the default LoggerFinder 57 * JUL backend. 58 * @modules java.base/sun.util.logging 59 * java.base/jdk.internal.logger 60 * java.logging/sun.util.logging.internal 61 * @run main/othervm DefaultLoggerBridgeTest 62 * @author danielfuchs 63 */ 64 public class DefaultLoggerBridgeTest { 65 66 final static AtomicLong sequencer = new AtomicLong(); 67 final static boolean VERBOSE = false; 68 static final ThreadLocal<AtomicBoolean> allowControl = new ThreadLocal<AtomicBoolean>() { 69 @Override 70 protected AtomicBoolean initialValue() { 71 return new AtomicBoolean(false); 72 } 73 }; 74 static final ThreadLocal<AtomicBoolean> allowAccess = new ThreadLocal<AtomicBoolean>() { 75 @Override 76 protected AtomicBoolean initialValue() { 77 return new AtomicBoolean(false); 78 } 79 }; 80 static final ThreadLocal<AtomicBoolean> allowAll = new ThreadLocal<AtomicBoolean>() { 81 @Override 82 protected AtomicBoolean initialValue() { 83 return new AtomicBoolean(false); 84 } 85 }; 86 87 public static final Queue<LogEvent> eventQueue = new ArrayBlockingQueue<>(128); 88 89 public static final class LogEvent implements Cloneable { 90 91 public LogEvent() { 92 this(sequencer.getAndIncrement()); 93 } 94 95 LogEvent(long sequenceNumber) { 96 this.sequenceNumber = sequenceNumber; 97 } 98 99 long sequenceNumber; 100 boolean isLoggable; 101 String loggerName; 102 java.util.logging.Level level; 103 ResourceBundle bundle; 104 Throwable thrown; 105 Object[] args; 106 String msg; 107 String className; 108 String methodName; 109 110 Object[] toArray() { 111 return new Object[] { 112 sequenceNumber, 113 isLoggable, 114 loggerName, 115 level, 116 bundle, 117 thrown, 118 args, 119 msg, 120 className, 121 methodName, 122 }; 123 } 124 125 @Override 126 public String toString() { 127 return Arrays.deepToString(toArray()); 128 } 129 130 @Override 131 public boolean equals(Object obj) { 132 return obj instanceof LogEvent 133 && Objects.deepEquals(this.toArray(), ((LogEvent)obj).toArray()); 134 } 135 136 @Override 137 public int hashCode() { 138 return Objects.hash(toArray()); 139 } 140 141 public LogEvent cloneWith(long sequenceNumber) 142 throws CloneNotSupportedException { 143 LogEvent cloned = (LogEvent)super.clone(); 144 cloned.sequenceNumber = sequenceNumber; 145 return cloned; 146 } 147 148 public static LogEvent of(long sequenceNumber, 149 boolean isLoggable, String name, 150 java.util.logging.Level level, ResourceBundle bundle, 151 String key, Throwable thrown, Object... params) { 152 return LogEvent.of(sequenceNumber, isLoggable, name, 153 DefaultLoggerBridgeTest.class.getName(), 154 "testLogger", level, bundle, key, 155 thrown, params); 156 } 157 public static LogEvent of(long sequenceNumber, 158 boolean isLoggable, String name, 159 String className, String methodName, 160 java.util.logging.Level level, ResourceBundle bundle, 161 String key, Throwable thrown, Object... params) { 162 LogEvent evt = new LogEvent(sequenceNumber); 163 evt.loggerName = name; 164 evt.level = level; 165 evt.args = params; 166 evt.bundle = bundle; 167 evt.thrown = thrown; 168 evt.msg = key; 169 evt.isLoggable = isLoggable; 170 evt.className = className; 171 evt.methodName = methodName; 172 return evt; 173 } 174 175 } 176 177 static final java.util.logging.Level[] julLevels = { 178 java.util.logging.Level.ALL, 179 java.util.logging.Level.FINEST, 180 java.util.logging.Level.FINER, 181 java.util.logging.Level.FINE, 182 java.util.logging.Level.CONFIG, 183 java.util.logging.Level.INFO, 184 java.util.logging.Level.WARNING, 185 java.util.logging.Level.SEVERE, 186 java.util.logging.Level.OFF, 187 }; 188 189 190 public static class MyBundle extends ResourceBundle { 191 192 final ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>(); 193 194 @Override 195 protected Object handleGetObject(String key) { 196 if (key.contains(" (translated)")) { 197 throw new RuntimeException("Unexpected key: " + key); 198 } 199 return map.computeIfAbsent(key, k -> k + " (translated)"); 200 } 201 202 @Override 203 public Enumeration<String> getKeys() { 204 return Collections.enumeration(map.keySet()); 205 } 206 207 } 208 209 public static class MyHandler extends Handler { 210 211 @Override 212 public java.util.logging.Level getLevel() { 213 return java.util.logging.Level.ALL; 214 } 215 216 @Override 217 public void publish(LogRecord record) { 218 eventQueue.add(LogEvent.of(sequencer.getAndIncrement(), 219 true, record.getLoggerName(), 220 record.getSourceClassName(), 221 record.getSourceMethodName(), 222 record.getLevel(), 223 record.getResourceBundle(), record.getMessage(), 224 record.getThrown(), record.getParameters())); 225 } 226 @Override 227 public void flush() { 228 } 229 @Override 230 public void close() throws SecurityException { 231 } 232 233 } 234 235 public static class MyLoggerBundle extends MyBundle { 236 237 } 238 239 static PlatformLogger.Bridge convert(Logger logger) { 240 boolean old = allowAccess.get().get(); 241 allowAccess.get().set(true); 242 try { 243 return PlatformLogger.Bridge.convert(logger); 244 } finally { 245 allowAccess.get().set(old); 246 } 247 } 248 249 static Logger getLogger(String name, Class<?> caller) { 250 boolean old = allowAccess.get().get(); 251 allowAccess.get().set(true); 252 try { 253 return jdk.internal.logger.LazyLoggers.getLogger(name, caller); 254 } finally { 255 allowAccess.get().set(old); 256 } 257 } 258 259 static enum TestCases {NOSECURITY, NOPERMISSIONS, WITHPERMISSIONS}; 260 261 static void setSecurityManager() { 262 if (System.getSecurityManager() == null) { 263 Policy.setPolicy(new SimplePolicy(allowControl, allowAccess, allowAll)); 264 System.setSecurityManager(new SecurityManager()); 265 } 266 } 267 268 public static void main(String[] args) { 269 if (args.length == 0) 270 args = new String[] { 271 "NOSECURITY", 272 "NOPERMISSIONS", 273 "WITHPERMISSIONS" 274 }; 275 276 Stream.of(args).map(TestCases::valueOf).forEach((testCase) -> { 277 LoggerFinder provider; 278 switch (testCase) { 279 case NOSECURITY: 280 System.out.println("\n*** Without Security Manager\n"); 281 test(true); 282 System.out.println("Tetscase count: " + sequencer.get()); 283 break; 284 case NOPERMISSIONS: 285 System.out.println("\n*** With Security Manager, without permissions\n"); 286 setSecurityManager(); 287 test(false); 288 System.out.println("Tetscase count: " + sequencer.get()); 289 break; 290 case WITHPERMISSIONS: 291 System.out.println("\n*** With Security Manager, with control permission\n"); 292 setSecurityManager(); 293 final boolean control = allowControl.get().get(); 294 try { 295 allowControl.get().set(true); 296 test(true); 297 } finally { 298 allowControl.get().set(control); 299 } 300 break; 301 default: 302 throw new RuntimeException("Unknown test case: " + testCase); 303 } 304 }); 305 System.out.println("\nPASSED: Tested " + sequencer.get() + " cases."); 306 } 307 308 public static void test(boolean hasRequiredPermissions) { 309 310 ResourceBundle loggerBundle = 311 ResourceBundle.getBundle(MyLoggerBundle.class.getName()); 312 final Map<Object, String> loggerDescMap = new HashMap<>(); 313 314 Logger sysLogger1a = getLogger("foo", Thread.class); 315 loggerDescMap.put(sysLogger1a, "jdk.internal.logger.LazyLoggers.getLogger(\"foo\", Thread.class)"); 316 317 Logger appLogger1 = System.getLogger("foo"); 318 loggerDescMap.put(appLogger1, "System.getLogger(\"foo\")"); 319 320 LoggerFinder provider; 321 try { 322 provider = LoggerFinder.getLoggerFinder(); 323 if (!hasRequiredPermissions) { 324 throw new RuntimeException("Expected exception not raised"); 325 } 326 } catch (AccessControlException x) { 327 if (hasRequiredPermissions) { 328 throw new RuntimeException("Unexpected permission check", x); 329 } 330 if (!SimplePolicy.LOGGERFINDER_PERMISSION.equals(x.getPermission())) { 331 throw new RuntimeException("Unexpected permission in exception: " + x, x); 332 } 333 final boolean control = allowControl.get().get(); 334 try { 335 allowControl.get().set(true); 336 provider = LoggerFinder.getLoggerFinder(); 337 } finally { 338 allowControl.get().set(control); 339 } 340 } 341 342 Logger sysLogger1b = null; 343 try { 344 sysLogger1b = provider.getLogger("foo", Thread.class); 345 if (sysLogger1b != sysLogger1a) { 346 loggerDescMap.put(sysLogger1b, "provider.getLogger(\"foo\", Thread.class)"); 347 } 348 if (!hasRequiredPermissions) { 349 throw new RuntimeException("Managed to obtain a system logger without permission"); 350 } 351 } catch (AccessControlException acx) { 352 if (hasRequiredPermissions) { 353 throw new RuntimeException("Unexpected security exception: ", acx); 354 } 355 if (!acx.getPermission().equals(SimplePolicy.LOGGERFINDER_PERMISSION)) { 356 throw new RuntimeException("Unexpected permission in exception: " + acx, acx); 357 } 358 System.out.println("Got expected exception for system logger: " + acx); 359 } 360 361 Logger appLogger2 = System.getLogger("foo", loggerBundle); 362 loggerDescMap.put(appLogger2, "System.getLogger(\"foo\", loggerBundle)"); 363 364 if (appLogger2 == appLogger1) { 365 throw new RuntimeException("identical loggers"); 366 } 367 368 Logger sysLogger2 = null; 369 try { 370 sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class); 371 loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class)"); 372 if (!hasRequiredPermissions) { 373 throw new RuntimeException("Managed to obtain a system logger without permission"); 374 } 375 } catch (AccessControlException acx) { 376 if (hasRequiredPermissions) { 377 throw new RuntimeException("Unexpected security exception: ", acx); 378 } 379 if (!acx.getPermission().equals(SimplePolicy.LOGGERFINDER_PERMISSION)) { 380 throw new RuntimeException("Unexpected permission in exception: " + acx, acx); 381 } 382 System.out.println("Got expected exception for localized system logger: " + acx); 383 } 384 if (hasRequiredPermissions && appLogger2 == sysLogger2) { 385 throw new RuntimeException("identical loggers"); 386 } 387 if (hasRequiredPermissions && sysLogger2 == sysLogger1a) { 388 throw new RuntimeException("identical loggers"); 389 } 390 391 final java.util.logging.Logger appSink; 392 final java.util.logging.Logger sysSink; 393 final MyHandler appHandler; 394 final MyHandler sysHandler; 395 final boolean old = allowAll.get().get(); 396 allowAll.get().set(true); 397 try { 398 sysSink = LoggingProviderImpl.getLogManagerAccess().demandLoggerFor( 399 LogManager.getLogManager(), "foo", Thread.class); 400 appSink = LoggingProviderImpl.getLogManagerAccess().demandLoggerFor( 401 LogManager.getLogManager(), "foo", DefaultLoggerBridgeTest.class); 402 if (appSink == sysSink) { 403 throw new RuntimeException("identical backend loggers"); 404 } 405 appSink.addHandler(appHandler = new MyHandler()); 406 sysSink.addHandler(sysHandler = new MyHandler()); 407 appSink.setUseParentHandlers(VERBOSE); 408 sysSink.setUseParentHandlers(VERBOSE); 409 } finally { 410 allowAll.get().set(old); 411 } 412 413 try { 414 testLogger(provider, loggerDescMap, "foo", null, convert(sysLogger1a), sysSink); 415 testLogger(provider, loggerDescMap, "foo", null, convert(appLogger1), appSink); 416 testLogger(provider, loggerDescMap, "foo", loggerBundle, convert(appLogger2), appSink); 417 if (sysLogger1b != null && sysLogger1b != sysLogger1a) { 418 testLogger(provider, loggerDescMap, "foo", null, convert(sysLogger1b), sysSink); 419 } 420 if (sysLogger2 != null) { 421 testLogger(provider, loggerDescMap, "foo", loggerBundle, convert(sysLogger2), sysSink); 422 } 423 } finally { 424 allowAll.get().set(true); 425 try { 426 appSink.removeHandler(appHandler); 427 sysSink.removeHandler(sysHandler); 428 } finally { 429 allowAll.get().set(old); 430 } 431 } 432 } 433 434 public static class Foo { 435 436 } 437 438 static void verbose(String msg) { 439 if (VERBOSE) { 440 System.out.println(msg); 441 } 442 } 443 444 static void checkLogEvent(LoggerFinder provider, String desc, 445 LogEvent expected) { 446 LogEvent actual = eventQueue.poll(); 447 if (!expected.equals(actual)) { 448 throw new RuntimeException("mismatch for " + desc 449 + "\n\texpected=" + expected 450 + "\n\t actual=" + actual); 451 } else { 452 verbose("Got expected results for " 453 + desc + "\n\t" + expected); 454 } 455 } 456 457 static void checkLogEvent(LoggerFinder provider, String desc, 458 LogEvent expected, boolean expectNotNull) { 459 LogEvent actual = eventQueue.poll(); 460 if (actual == null && !expectNotNull) return; 461 if (actual != null && !expectNotNull) { 462 throw new RuntimeException("Unexpected log event found for " + desc 463 + "\n\tgot: " + actual); 464 } 465 if (!expected.equals(actual)) { 466 throw new RuntimeException("mismatch for " + desc 467 + "\n\texpected=" + expected 468 + "\n\t actual=" + actual); 469 } else { 470 verbose("Got expected results for " 471 + desc + "\n\t" + expected); 472 } 473 } 474 475 static void setLevel(java.util.logging.Logger sink, java.util.logging.Level loggerLevel) { 476 boolean before = allowAll.get().get(); 477 try { 478 allowAll.get().set(true); 479 sink.setLevel(loggerLevel); 480 } finally { 481 allowAll.get().set(before); 482 } 483 } 484 485 static sun.util.logging.PlatformLogger.Level toPlatformLevel(java.util.logging.Level level) { 486 boolean old = allowAccess.get().get(); 487 allowAccess.get().set(true); 488 try { 489 return sun.util.logging.PlatformLogger.Level.valueOf(level.getName()); 490 } finally { 491 allowAccess.get().set(old); 492 } 493 } 494 495 // Calls the methods defined on LogProducer and verify the 496 // parameters received by the underlying logger. 497 private static void testLogger(LoggerFinder provider, 498 Map<Object, String> loggerDescMap, 499 String name, 500 ResourceBundle loggerBundle, 501 PlatformLogger.Bridge logger, 502 java.util.logging.Logger sink) { 503 504 if (loggerDescMap.get(logger) == null) { 505 throw new RuntimeException("Missing description for " + logger); 506 } 507 System.out.println("Testing " + loggerDescMap.get(logger) + " [" + logger + "]"); 508 final java.util.logging.Level OFF = java.util.logging.Level.OFF; 509 510 Foo foo = new Foo(); 511 String fooMsg = foo.toString(); 512 System.out.println("\tlogger.log(messageLevel, fooMsg)"); 513 System.out.println("\tlogger.<level>(fooMsg)"); 514 for (java.util.logging.Level loggerLevel : julLevels) { 515 setLevel(sink, loggerLevel); 516 for (java.util.logging.Level messageLevel :julLevels) { 517 String desc = "logger.log(messageLevel, fooMsg): loggerLevel=" 518 + loggerLevel+", messageLevel="+messageLevel; 519 LogEvent expected = 520 LogEvent.of( 521 sequencer.get(), 522 loggerLevel != OFF && messageLevel.intValue() >= loggerLevel.intValue(), 523 name, messageLevel, loggerBundle, 524 fooMsg, (Throwable)null, (Object[])null); 525 logger.log(toPlatformLevel(messageLevel), fooMsg); 526 checkLogEvent(provider, desc, expected, expected.isLoggable); 527 } 528 } 529 530 Supplier<String> supplier = new Supplier<String>() { 531 @Override 532 public String get() { 533 return this.toString(); 534 } 535 }; 536 System.out.println("\tlogger.log(messageLevel, supplier)"); 537 System.out.println("\tlogger.<level>(supplier)"); 538 for (java.util.logging.Level loggerLevel : julLevels) { 539 setLevel(sink, loggerLevel); 540 for (java.util.logging.Level messageLevel :julLevels) { 541 String desc = "logger.log(messageLevel, supplier): loggerLevel=" 542 + loggerLevel+", messageLevel="+messageLevel; 543 LogEvent expected = 544 LogEvent.of( 545 sequencer.get(), 546 loggerLevel != OFF && messageLevel.intValue() >= loggerLevel.intValue(), 547 name, messageLevel, null, 548 supplier.get(), (Throwable)null, (Object[])null); 549 logger.log(toPlatformLevel(messageLevel), supplier); 550 checkLogEvent(provider, desc, expected, expected.isLoggable); 551 } 552 } 553 554 String format = "two params [{1} {2}]"; 555 Object arg1 = foo; 556 Object arg2 = fooMsg; 557 System.out.println("\tlogger.log(messageLevel, format, arg1, arg2)"); 558 for (java.util.logging.Level loggerLevel : julLevels) { 559 setLevel(sink, loggerLevel); 560 for (java.util.logging.Level messageLevel :julLevels) { 561 String desc = "logger.log(messageLevel, format, foo, fooMsg): loggerLevel=" 562 + loggerLevel+", messageLevel="+messageLevel; 563 LogEvent expected = 564 LogEvent.of( 565 sequencer.get(), 566 loggerLevel != OFF && messageLevel.intValue() >= loggerLevel.intValue(), 567 name, messageLevel, loggerBundle, 568 format, (Throwable)null, arg1, arg2); 569 logger.log(toPlatformLevel(messageLevel), format, arg1, arg2); 570 checkLogEvent(provider, desc, expected, expected.isLoggable); 571 } 572 } 573 574 Throwable thrown = new Exception("OK: log me!"); 575 System.out.println("\tlogger.log(messageLevel, fooMsg, thrown)"); 576 for (java.util.logging.Level loggerLevel : julLevels) { 577 setLevel(sink, loggerLevel); 578 for (java.util.logging.Level messageLevel :julLevels) { 579 String desc = "logger.log(messageLevel, fooMsg, thrown): loggerLevel=" 580 + loggerLevel+", messageLevel="+messageLevel; 581 LogEvent expected = 582 LogEvent.of( 583 sequencer.get(), 584 loggerLevel != OFF && messageLevel.intValue() >= loggerLevel.intValue(), 585 name, messageLevel, loggerBundle, 586 fooMsg, thrown, (Object[])null); 587 logger.log(toPlatformLevel(messageLevel), fooMsg, thrown); 588 checkLogEvent(provider, desc, expected, expected.isLoggable); 589 } 590 } 591 592 System.out.println("\tlogger.log(messageLevel, thrown, supplier)"); 593 for (java.util.logging.Level loggerLevel : julLevels) { 594 setLevel(sink, loggerLevel); 595 for (java.util.logging.Level messageLevel :julLevels) { 596 String desc = "logger.log(messageLevel, thrown, supplier): loggerLevel=" 597 + loggerLevel+", messageLevel="+messageLevel; 598 LogEvent expected = 599 LogEvent.of( 600 sequencer.get(), 601 loggerLevel != OFF && messageLevel.intValue() >= loggerLevel.intValue(), 602 name, messageLevel, null, 603 supplier.get(), thrown, (Object[])null); 604 logger.log(toPlatformLevel(messageLevel), thrown, supplier); 605 checkLogEvent(provider, desc, expected, expected.isLoggable); 606 } 607 } 608 609 String sourceClass = "blah.Blah"; 610 String sourceMethod = "blih"; 611 System.out.println("\tlogger.logp(messageLevel, sourceClass, sourceMethod, fooMsg)"); 612 for (java.util.logging.Level loggerLevel : julLevels) { 613 setLevel(sink, loggerLevel); 614 for (java.util.logging.Level messageLevel :julLevels) { 615 String desc = "logger.logp(messageLevel, sourceClass, sourceMethod, fooMsg): loggerLevel=" 616 + loggerLevel+", messageLevel="+messageLevel; 617 LogEvent expected = 618 LogEvent.of( 619 sequencer.get(), 620 loggerLevel != OFF && messageLevel.intValue() >= loggerLevel.intValue(), 621 name, sourceClass, sourceMethod, messageLevel, loggerBundle, 622 fooMsg, (Throwable)null, (Object[])null); 623 logger.logp(toPlatformLevel(messageLevel), sourceClass, sourceMethod, fooMsg); 624 checkLogEvent(provider, desc, expected, expected.isLoggable); 625 } 626 } 627 628 System.out.println("\tlogger.logp(messageLevel, sourceClass, sourceMethod, supplier)"); 629 for (java.util.logging.Level loggerLevel : julLevels) { 630 setLevel(sink, loggerLevel); 631 for (java.util.logging.Level messageLevel :julLevels) { 632 String desc = "logger.logp(messageLevel, sourceClass, sourceMethod, supplier): loggerLevel=" 633 + loggerLevel+", messageLevel="+messageLevel; 634 LogEvent expected = 635 LogEvent.of( 636 sequencer.get(), 637 loggerLevel != OFF && messageLevel.intValue() >= loggerLevel.intValue(), 638 name, sourceClass, sourceMethod, messageLevel, null, 639 supplier.get(), (Throwable)null, (Object[])null); 640 logger.logp(toPlatformLevel(messageLevel), sourceClass, sourceMethod, supplier); 641 checkLogEvent(provider, desc, expected, expected.isLoggable); 642 } 643 } 644 645 System.out.println("\tlogger.logp(messageLevel, sourceClass, sourceMethod, format, arg1, arg2)"); 646 for (java.util.logging.Level loggerLevel : julLevels) { 647 setLevel(sink, loggerLevel); 648 for (java.util.logging.Level messageLevel :julLevels) { 649 String desc = "logger.logp(messageLevel, sourceClass, sourceMethod, format, arg1, arg2): loggerLevel=" 650 + loggerLevel+", messageLevel="+messageLevel; 651 LogEvent expected = 652 LogEvent.of( 653 sequencer.get(), 654 loggerLevel != OFF && messageLevel.intValue() >= loggerLevel.intValue(), 655 name, sourceClass, sourceMethod, messageLevel, loggerBundle, 656 format, (Throwable)null, arg1, arg2); 657 logger.logp(toPlatformLevel(messageLevel), sourceClass, sourceMethod, format, arg1, arg2); 658 checkLogEvent(provider, desc, expected, expected.isLoggable); 659 } 660 } 661 662 System.out.println("\tlogger.logp(messageLevel, sourceClass, sourceMethod, fooMsg, thrown)"); 663 for (java.util.logging.Level loggerLevel : julLevels) { 664 setLevel(sink, loggerLevel); 665 for (java.util.logging.Level messageLevel :julLevels) { 666 String desc = "logger.logp(messageLevel, sourceClass, sourceMethod, fooMsg, thrown): loggerLevel=" 667 + loggerLevel+", messageLevel="+messageLevel; 668 LogEvent expected = 669 LogEvent.of( 670 sequencer.get(), 671 loggerLevel != OFF && messageLevel.intValue() >= loggerLevel.intValue(), 672 name, sourceClass, sourceMethod, messageLevel, loggerBundle, 673 fooMsg, thrown, (Object[])null); 674 logger.logp(toPlatformLevel(messageLevel), sourceClass, sourceMethod, fooMsg, thrown); 675 checkLogEvent(provider, desc, expected, expected.isLoggable); 676 } 677 } 678 679 System.out.println("\tlogger.logp(messageLevel, sourceClass, sourceMethod, thrown, supplier)"); 680 for (java.util.logging.Level loggerLevel : julLevels) { 681 setLevel(sink, loggerLevel); 682 for (java.util.logging.Level messageLevel :julLevels) { 683 String desc = "logger.logp(messageLevel, sourceClass, sourceMethod, thrown, supplier): loggerLevel=" 684 + loggerLevel+", messageLevel="+messageLevel; 685 LogEvent expected = 686 LogEvent.of( 687 sequencer.get(), 688 loggerLevel != OFF && messageLevel.intValue() >= loggerLevel.intValue(), 689 name, sourceClass, sourceMethod, messageLevel, null, 690 supplier.get(), thrown, (Object[])null); 691 logger.logp(toPlatformLevel(messageLevel), sourceClass, sourceMethod, thrown, supplier); 692 checkLogEvent(provider, desc, expected, expected.isLoggable); 693 } 694 } 695 696 ResourceBundle bundle = ResourceBundle.getBundle(MyBundle.class.getName()); 697 System.out.println("\tlogger.logrb(messageLevel, bundle, format, arg1, arg2)"); 698 for (java.util.logging.Level loggerLevel : julLevels) { 699 setLevel(sink, loggerLevel); 700 for (java.util.logging.Level messageLevel :julLevels) { 701 String desc = "logger.logrb(messageLevel, bundle, format, arg1, arg2): loggerLevel=" 702 + loggerLevel+", messageLevel="+messageLevel; 703 LogEvent expected = 704 LogEvent.of( 705 sequencer.get(), 706 loggerLevel != OFF && messageLevel.intValue() >= loggerLevel.intValue(), 707 name, messageLevel, bundle, 708 format, (Throwable)null, arg1, arg2); 709 logger.logrb(toPlatformLevel(messageLevel), bundle, format, arg1, arg2); 710 checkLogEvent(provider, desc, expected, expected.isLoggable); 711 } 712 } 713 714 System.out.println("\tlogger.logrb(messageLevel, bundle, msg, thrown)"); 715 for (java.util.logging.Level loggerLevel : julLevels) { 716 setLevel(sink, loggerLevel); 717 for (java.util.logging.Level messageLevel :julLevels) { 718 String desc = "logger.logrb(messageLevel, bundle, msg, thrown): loggerLevel=" 719 + loggerLevel+", messageLevel="+messageLevel; 720 LogEvent expected = 721 LogEvent.of( 722 sequencer.get(), 723 loggerLevel != OFF && messageLevel.intValue() >= loggerLevel.intValue(), 724 name, messageLevel, bundle, 725 fooMsg, thrown, (Object[])null); 726 logger.logrb(toPlatformLevel(messageLevel), bundle, fooMsg, thrown); 727 checkLogEvent(provider, desc, expected, expected.isLoggable); 728 } 729 } 730 731 System.out.println("\tlogger.logrb(messageLevel, sourceClass, sourceMethod, bundle, format, arg1, arg2)"); 732 for (java.util.logging.Level loggerLevel : julLevels) { 733 setLevel(sink, loggerLevel); 734 for (java.util.logging.Level messageLevel :julLevels) { 735 String desc = "logger.logrb(messageLevel, sourceClass, sourceMethod, bundle, format, arg1, arg2): loggerLevel=" 736 + loggerLevel+", messageLevel="+messageLevel; 737 LogEvent expected = 738 LogEvent.of( 739 sequencer.get(), 740 loggerLevel != OFF && messageLevel.intValue() >= loggerLevel.intValue(), 741 name, sourceClass, sourceMethod, messageLevel, bundle, 742 format, (Throwable)null, arg1, arg2); 743 logger.logrb(toPlatformLevel(messageLevel), sourceClass, sourceMethod, bundle, format, arg1, arg2); 744 checkLogEvent(provider, desc, expected, expected.isLoggable); 745 } 746 } 747 748 System.out.println("\tlogger.logrb(messageLevel, sourceClass, sourceMethod, bundle, msg, thrown)"); 749 for (java.util.logging.Level loggerLevel : julLevels) { 750 setLevel(sink, loggerLevel); 751 for (java.util.logging.Level messageLevel :julLevels) { 752 String desc = "logger.logrb(messageLevel, sourceClass, sourceMethod, bundle, msg, thrown): loggerLevel=" 753 + loggerLevel+", messageLevel="+messageLevel; 754 LogEvent expected = 755 LogEvent.of( 756 sequencer.get(), 757 loggerLevel != OFF && messageLevel.intValue() >= loggerLevel.intValue(), 758 name, sourceClass, sourceMethod, messageLevel, bundle, 759 fooMsg, thrown, (Object[])null); 760 logger.logrb(toPlatformLevel(messageLevel), sourceClass, sourceMethod, bundle, fooMsg, thrown); 761 checkLogEvent(provider, desc, expected, expected.isLoggable); 762 } 763 } 764 } 765 766 final static class PermissionsBuilder { 767 final Permissions perms; 768 public PermissionsBuilder() { 769 this(new Permissions()); 770 } 771 public PermissionsBuilder(Permissions perms) { 772 this.perms = perms; 773 } 774 public PermissionsBuilder add(Permission p) { 775 perms.add(p); 776 return this; 777 } 778 public PermissionsBuilder addAll(PermissionCollection col) { 779 if (col != null) { 780 for (Enumeration<Permission> e = col.elements(); e.hasMoreElements(); ) { 781 perms.add(e.nextElement()); 782 } 783 } 784 return this; 785 } 786 public Permissions toPermissions() { 787 final PermissionsBuilder builder = new PermissionsBuilder(); 788 builder.addAll(perms); 789 return builder.perms; 790 } 791 } 792 793 public static class SimplePolicy extends Policy { 794 public static final RuntimePermission LOGGERFINDER_PERMISSION = 795 new RuntimePermission("loggerFinder"); 796 final static RuntimePermission ACCESS_LOGGER = new RuntimePermission("accessClassInPackage.jdk.internal.logger"); 797 final static RuntimePermission ACCESS_LOGGING = new RuntimePermission("accessClassInPackage.sun.util.logging"); 798 799 final Permissions permissions; 800 final Permissions allPermissions; 801 final ThreadLocal<AtomicBoolean> allowControl; 802 final ThreadLocal<AtomicBoolean> allowAccess; 803 final ThreadLocal<AtomicBoolean> allowAll; 804 public SimplePolicy(ThreadLocal<AtomicBoolean> allowControl, 805 ThreadLocal<AtomicBoolean> allowAccess, 806 ThreadLocal<AtomicBoolean> allowAll) { 807 this.allowControl = allowControl; 808 this.allowAccess = allowAccess; 809 this.allowAll = allowAll; 810 permissions = new Permissions(); 811 allPermissions = new PermissionsBuilder() 812 .add(new java.security.AllPermission()) 813 .toPermissions(); 814 } 815 816 Permissions getPermissions() { 817 if (allowControl.get().get() || allowAccess.get().get() || allowAll.get().get()) { 818 PermissionsBuilder builder = new PermissionsBuilder() 819 .addAll(permissions); 820 if (allowControl.get().get()) { 821 builder.add(LOGGERFINDER_PERMISSION); 822 } 823 if (allowAccess.get().get()) { 824 builder.add(ACCESS_LOGGER); 825 builder.add(ACCESS_LOGGING); 826 } 827 if (allowAll.get().get()) { 828 builder.addAll(allPermissions); 829 } 830 return builder.toPermissions(); 831 } 832 return permissions; 833 } 834 835 @Override 836 public boolean implies(ProtectionDomain domain, Permission permission) { 837 return getPermissions().implies(permission); 838 } 839 840 @Override 841 public PermissionCollection getPermissions(CodeSource codesource) { 842 return new PermissionsBuilder().addAll(getPermissions()).toPermissions(); 843 } 844 845 @Override 846 public PermissionCollection getPermissions(ProtectionDomain domain) { 847 return new PermissionsBuilder().addAll(getPermissions()).toPermissions(); 848 } 849 } 850 }