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