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