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