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.lang.reflect.InvocationTargetException; 24 import java.lang.reflect.Method; 25 import java.security.AccessControlException; 26 import java.security.AccessController; 27 import java.security.CodeSource; 28 import java.security.Permission; 29 import java.security.PermissionCollection; 30 import java.security.Permissions; 31 import java.security.Policy; 32 import java.security.PrivilegedAction; 33 import java.security.ProtectionDomain; 34 import java.util.Arrays; 35 import java.util.Collections; 36 import java.util.Enumeration; 37 import java.util.HashMap; 38 import java.util.Map; 39 import java.util.Objects; 40 import java.util.Queue; 41 import java.util.ResourceBundle; 42 import java.util.concurrent.ArrayBlockingQueue; 43 import java.util.concurrent.ConcurrentHashMap; 44 import java.util.concurrent.atomic.AtomicBoolean; 45 import java.util.concurrent.atomic.AtomicLong; 46 import java.util.function.Supplier; 47 import java.util.logging.Handler; 48 import java.util.logging.LogRecord; 49 import java.lang.System.LoggerFinder; 50 import java.lang.System.Logger; 51 import java.lang.System.Logger.Level; 52 import java.util.stream.Stream; 53 import sun.util.logging.PlatformLogger; 54 55 /** 56 * @test 57 * @bug 8140364 58 * @summary JDK implementation specific unit test for JDK internal artifacts. 59 * Tests all bridge methods with the a custom backend whose 60 * loggers implement PlatformLogger.Bridge. 61 * @modules java.base/sun.util.logging 62 * java.base/jdk.internal.logger 63 * java.logging 64 * @build CustomSystemClassLoader LoggerBridgeTest 65 * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader LoggerBridgeTest NOSECURITY 66 * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader LoggerBridgeTest NOPERMISSIONS 67 * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader LoggerBridgeTest WITHPERMISSIONS 68 * @author danielfuchs 69 */ 70 public class LoggerBridgeTest { 71 72 public static final RuntimePermission LOGGERFINDER_PERMISSION = 73 new RuntimePermission("loggerFinder"); 74 75 final static AtomicLong sequencer = new AtomicLong(); 76 final static boolean VERBOSE = false; 77 static final ThreadLocal<AtomicBoolean> allowControl = new ThreadLocal<AtomicBoolean>() { 78 @Override 79 protected AtomicBoolean initialValue() { 80 return new AtomicBoolean(false); 81 } 82 }; 83 static final ThreadLocal<AtomicBoolean> allowAccess = new ThreadLocal<AtomicBoolean>() { 84 @Override 214 evt.supplier = supplier; 215 evt.isLoggable = isLoggable; 216 evt.className = className; 217 evt.methodName = methodName; 218 return evt; 219 } 220 221 public static LogEvent of(boolean isLoggable, String name, 222 String className, String methodName, 223 sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle, 224 Supplier<String> supplier, Throwable thrown, Object... params) { 225 return LogEvent.of(sequencer.getAndIncrement(), isLoggable, name, 226 className, methodName, level, bundle, supplier, thrown, params); 227 } 228 229 } 230 static final Class<?> providerClass; 231 static { 232 try { 233 // Preload classes before the security manager is on. 234 providerClass = ClassLoader.getSystemClassLoader().loadClass("LoggerBridgeTest$LogProducerFinder"); 235 ((LoggerFinder)providerClass.newInstance()).getLogger("foo", providerClass.getModule()); 236 } catch (Exception ex) { 237 throw new ExceptionInInitializerError(ex); 238 } 239 } 240 241 public static class LogProducerFinder extends LoggerFinder { 242 final ConcurrentHashMap<String, LoggerImpl> system = new ConcurrentHashMap<>(); 243 final ConcurrentHashMap<String, LoggerImpl> user = new ConcurrentHashMap<>(); 244 245 public class LoggerImpl implements Logger, PlatformLogger.Bridge { 246 private final String name; 247 private sun.util.logging.PlatformLogger.Level level = sun.util.logging.PlatformLogger.Level.INFO; 248 private sun.util.logging.PlatformLogger.Level OFF = sun.util.logging.PlatformLogger.Level.OFF; 249 private sun.util.logging.PlatformLogger.Level FINE = sun.util.logging.PlatformLogger.Level.FINE; 250 private sun.util.logging.PlatformLogger.Level FINER = sun.util.logging.PlatformLogger.Level.FINER; 251 private sun.util.logging.PlatformLogger.Level FINEST = sun.util.logging.PlatformLogger.Level.FINEST; 252 private sun.util.logging.PlatformLogger.Level CONFIG = sun.util.logging.PlatformLogger.Level.CONFIG; 253 private sun.util.logging.PlatformLogger.Level INFO = sun.util.logging.PlatformLogger.Level.INFO; 254 private sun.util.logging.PlatformLogger.Level WARNING = sun.util.logging.PlatformLogger.Level.WARNING; 255 private sun.util.logging.PlatformLogger.Level SEVERE = sun.util.logging.PlatformLogger.Level.SEVERE; 256 257 public LoggerImpl(String name) { 258 this.name = name; 259 } 260 261 @Override 262 public String getName() { 263 return name; 264 } 265 266 @Override 267 public boolean isLoggable(Level level) { 268 return this.level != OFF && this.level.intValue() <= level.getSeverity(); 269 } 270 271 @Override 272 public void log(Level level, ResourceBundle bundle, 273 String key, Throwable thrown) { 274 throw new UnsupportedOperationException(); 275 } 276 277 @Override 278 public void log(Level level, ResourceBundle bundle, 279 String format, Object... params) { 280 throw new UnsupportedOperationException(); 281 } 282 283 void log(LogEvent event) { 284 eventQueue.add(event); 285 } 286 287 @Override 288 public void log(Level level, Supplier<String> msgSupplier) { 289 throw new UnsupportedOperationException(); 290 } 291 292 @Override 293 public void log(Level level, Supplier<String> msgSupplier, 294 Throwable thrown) { 295 throw new UnsupportedOperationException(); 296 } 297 298 @Override 299 public void log(sun.util.logging.PlatformLogger.Level level, String msg) { 300 log(LogEvent.of(isLoggable(level), name, null, null, 301 level, null, msg, null, (Object[])null)); 302 } 303 304 @Override 305 public void log(sun.util.logging.PlatformLogger.Level level, 306 Supplier<String> msgSupplier) { 307 log(LogEvent.of(isLoggable(level), name, null, null, 308 level, null, msgSupplier, null, (Object[])null)); 309 } 310 311 @Override 312 public void log(sun.util.logging.PlatformLogger.Level level, String msg, 313 Object... params) { 314 log(LogEvent.of(isLoggable(level), name, null, null, 315 level, null, msg, null, params)); 316 } 317 318 @Override 319 public void log(sun.util.logging.PlatformLogger.Level level, String msg, 320 Throwable thrown) { 321 log(LogEvent.of(isLoggable(level), name, null, null, 322 level, null, msg, thrown, (Object[])null)); 323 } 324 325 @Override 326 public void log(sun.util.logging.PlatformLogger.Level level, Throwable thrown, 327 Supplier<String> msgSupplier) { 328 log(LogEvent.of(isLoggable(level), name, null, null, 329 level, null, msgSupplier, thrown, (Object[])null)); 330 } 331 332 @Override 333 public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, 334 String sourceMethod, String msg) { 335 log(LogEvent.of(isLoggable(level), name, 336 sourceClass, sourceMethod, 337 level, null, msg, null, (Object[])null)); 338 } 339 340 @Override 341 public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, 342 String sourceMethod, Supplier<String> msgSupplier) { 343 log(LogEvent.of(isLoggable(level), name, 344 sourceClass, sourceMethod, 345 level, null, msgSupplier, null, (Object[])null)); 346 } 347 348 @Override 349 public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, 350 String sourceMethod, String msg, Object... params) { 351 log(LogEvent.of(isLoggable(level), name, 352 sourceClass, sourceMethod, 353 level, null, msg, null, params)); 354 } 355 356 @Override 357 public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, 358 String sourceMethod, String msg, Throwable thrown) { 359 log(LogEvent.of(isLoggable(level), name, 360 sourceClass, sourceMethod, 361 level, null, msg, thrown, (Object[])null)); 362 } 363 364 @Override 365 public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, 366 String sourceMethod, Throwable thrown, 367 Supplier<String> msgSupplier) { 368 log(LogEvent.of(isLoggable(level), name, 369 sourceClass, sourceMethod, 370 level, null, msgSupplier, thrown, (Object[])null)); 371 } 372 373 @Override 374 public void logrb(sun.util.logging.PlatformLogger.Level level, String sourceClass, 375 String sourceMethod, ResourceBundle bundle, String msg, 376 Object... params) { 377 log(LogEvent.of(isLoggable(level), name, 378 sourceClass, sourceMethod, 379 level, bundle, msg, null, params)); 380 } 381 382 @Override 383 public void logrb(sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle, 384 String msg, Object... params) { 385 log(LogEvent.of(isLoggable(level), name, null, null, 386 level, bundle, msg, null, params)); 387 } 388 389 @Override 390 public void logrb(sun.util.logging.PlatformLogger.Level level, String sourceClass, 391 String sourceMethod, ResourceBundle bundle, String msg, 392 Throwable thrown) { 393 log(LogEvent.of(isLoggable(level), name, 394 sourceClass, sourceMethod, 395 level, bundle, msg, thrown, (Object[])null)); 396 } 397 398 @Override 399 public void logrb(sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle, 400 String msg, Throwable thrown) { 401 log(LogEvent.of(isLoggable(level), name, null, null, 402 level, bundle, msg, thrown, (Object[])null)); 403 } 404 405 @Override 406 public boolean isLoggable(sun.util.logging.PlatformLogger.Level level) { 407 return this.level != OFF && level.intValue() 408 >= this.level.intValue(); 409 } 410 411 @Override 412 public boolean isEnabled() { 413 return this.level != OFF; 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 ClassLoader getClassLoader(Module m) { 435 final boolean before = allowAll.get().getAndSet(true); 436 try { 437 return m.getClassLoader(); 438 } finally { 439 allowAll.get().set(before); 440 } 441 } 442 443 static final sun.util.logging.PlatformLogger.Level[] julLevels = { 444 sun.util.logging.PlatformLogger.Level.ALL, 445 sun.util.logging.PlatformLogger.Level.FINEST, 446 sun.util.logging.PlatformLogger.Level.FINER, 447 sun.util.logging.PlatformLogger.Level.FINE, 448 sun.util.logging.PlatformLogger.Level.CONFIG, 449 sun.util.logging.PlatformLogger.Level.INFO, 450 sun.util.logging.PlatformLogger.Level.WARNING, 451 sun.util.logging.PlatformLogger.Level.SEVERE, 452 sun.util.logging.PlatformLogger.Level.OFF, 453 }; 658 } catch (AccessControlException acx) { 659 if (hasRequiredPermissions) { 660 throw new RuntimeException("Unexpected security exception: ", acx); 661 } 662 if (!acx.getPermission().equals(LOGGERFINDER_PERMISSION)) { 663 throw new RuntimeException("Unexpected permission in exception: " + acx, acx); 664 } 665 System.out.println("Got expected exception for localized system logger: " + acx); 666 } 667 if (hasRequiredPermissions && appLogger2 == sysLogger2) { 668 throw new RuntimeException("identical loggers"); 669 } 670 if (appLogger2 == appLogger1) { 671 throw new RuntimeException("identical loggers"); 672 } 673 if (hasRequiredPermissions && sysLogger2 == sysLogger1) { 674 throw new RuntimeException("identical loggers"); 675 } 676 677 678 final LogProducerFinder.LoggerImpl appSink; 679 final LogProducerFinder.LoggerImpl sysSink; 680 boolean old = allowControl.get().get(); 681 allowControl.get().set(true); 682 try { 683 appSink = LogProducerFinder.LoggerImpl.class.cast( 684 provider.getLogger("foo", LoggerBridgeTest.class.getModule())); 685 sysSink = LogProducerFinder.LoggerImpl.class.cast( 686 provider.getLogger("foo", Thread.class.getModule())); 687 } finally { 688 allowControl.get().set(old); 689 } 690 691 testLogger(provider, loggerDescMap, "foo", null, convert(appLogger1), appSink); 692 if (hasRequiredPermissions) { 693 testLogger(provider, loggerDescMap, "foo", null, convert(sysLogger1), sysSink); 694 } 695 testLogger(provider, loggerDescMap, "foo", loggerBundle, convert(appLogger2), appSink); 696 if (hasRequiredPermissions) { 697 testLogger(provider, loggerDescMap, "foo", loggerBundle, convert(sysLogger2), sysSink); 698 } 699 } 700 701 public static class Foo { 702 703 } 704 705 static void verbose(String msg) { 722 } 723 724 static void checkLogEvent(LoggerFinder provider, String desc, 725 LogEvent expected, boolean expectNotNull) { 726 LogEvent actual = eventQueue.poll(); 727 if (actual == null && !expectNotNull) return; 728 if (actual != null && !expectNotNull) { 729 throw new RuntimeException("Unexpected log event found for " + desc 730 + "\n\tgot: " + actual); 731 } 732 if (!expected.equals(actual)) { 733 throw new RuntimeException("mismatch for " + desc 734 + "\n\texpected=" + expected 735 + "\n\t actual=" + actual); 736 } else { 737 verbose("Got expected results for " 738 + desc + "\n\t" + expected); 739 } 740 } 741 742 static void setLevel( LogProducerFinder.LoggerImpl sink, 743 sun.util.logging.PlatformLogger.Level loggerLevel) { 744 sink.level = loggerLevel; 745 } 746 747 // Calls the methods defined on LogProducer and verify the 748 // parameters received by the underlying LogProducerFinder.LoggerImpl 749 // logger. 750 private static void testLogger(LoggerFinder provider, 751 Map<Object, String> loggerDescMap, 752 String name, 753 ResourceBundle loggerBundle, 754 PlatformLogger.Bridge logger, 755 LogProducerFinder.LoggerImpl sink) { 756 757 System.out.println("Testing " + loggerDescMap.get(logger) + "[" + logger + "]"); 758 final sun.util.logging.PlatformLogger.Level OFF = sun.util.logging.PlatformLogger.Level.OFF; 759 760 Foo foo = new Foo(); 761 String fooMsg = foo.toString(); 762 System.out.println("\tlogger.log(messageLevel, fooMsg)"); 763 System.out.println("\tlogger.<level>(fooMsg)"); 764 for (sun.util.logging.PlatformLogger.Level loggerLevel : julLevels) { 765 setLevel(sink, loggerLevel); 766 for (sun.util.logging.PlatformLogger.Level messageLevel :julLevels) { 767 String desc = "logger.log(messageLevel, fooMsg): loggerLevel=" 768 + loggerLevel+", messageLevel="+messageLevel; 769 LogEvent expected = 770 LogEvent.of( 771 sequencer.get(), 772 loggerLevel != OFF && messageLevel.intValue() >= loggerLevel.intValue(), 773 name, messageLevel, loggerBundle, 774 fooMsg, (Throwable)null, (Object[])null); 775 logger.log(messageLevel, fooMsg); | 1 /* 2 * Copyright (c) 2015, 2018, 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.lang.reflect.InvocationTargetException; 24 import java.lang.reflect.Method; 25 import java.security.AccessControlException; 26 import java.security.CodeSource; 27 import java.security.Permission; 28 import java.security.PermissionCollection; 29 import java.security.Permissions; 30 import java.security.Policy; 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.util.stream.Stream; 50 import sun.util.logging.PlatformLogger; 51 52 /** 53 * @test 54 * @bug 8140364 55 * @summary JDK implementation specific unit test for JDK internal artifacts. 56 * Tests all bridge methods with the a custom backend whose 57 * loggers implement PlatformLogger.Bridge. 58 * @modules java.base/sun.util.logging 59 * java.base/jdk.internal.logger 60 * java.logging 61 * @build CustomSystemClassLoader LogProducerFinder LoggerBridgeTest 62 * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader LoggerBridgeTest NOSECURITY 63 * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader LoggerBridgeTest NOPERMISSIONS 64 * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader LoggerBridgeTest WITHPERMISSIONS 65 * @author danielfuchs 66 */ 67 public class LoggerBridgeTest { 68 69 public static final RuntimePermission LOGGERFINDER_PERMISSION = 70 new RuntimePermission("loggerFinder"); 71 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 211 evt.supplier = supplier; 212 evt.isLoggable = isLoggable; 213 evt.className = className; 214 evt.methodName = methodName; 215 return evt; 216 } 217 218 public static LogEvent of(boolean isLoggable, String name, 219 String className, String methodName, 220 sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle, 221 Supplier<String> supplier, Throwable thrown, Object... params) { 222 return LogEvent.of(sequencer.getAndIncrement(), isLoggable, name, 223 className, methodName, level, bundle, supplier, thrown, params); 224 } 225 226 } 227 static final Class<?> providerClass; 228 static { 229 try { 230 // Preload classes before the security manager is on. 231 providerClass = ClassLoader.getSystemClassLoader().loadClass("LogProducerFinder"); 232 ((LoggerFinder)providerClass.newInstance()).getLogger("foo", providerClass.getModule()); 233 } catch (Exception ex) { 234 throw new ExceptionInInitializerError(ex); 235 } 236 } 237 238 public static class LoggerImpl implements System.Logger, PlatformLogger.Bridge { 239 private final String name; 240 private PlatformLogger.Level level = PlatformLogger.Level.INFO; 241 private PlatformLogger.Level OFF = PlatformLogger.Level.OFF; 242 private PlatformLogger.Level FINE = PlatformLogger.Level.FINE; 243 private PlatformLogger.Level FINER = PlatformLogger.Level.FINER; 244 private PlatformLogger.Level FINEST = PlatformLogger.Level.FINEST; 245 private PlatformLogger.Level CONFIG = PlatformLogger.Level.CONFIG; 246 private PlatformLogger.Level INFO = PlatformLogger.Level.INFO; 247 private PlatformLogger.Level WARNING = PlatformLogger.Level.WARNING; 248 private PlatformLogger.Level SEVERE = PlatformLogger.Level.SEVERE; 249 250 public LoggerImpl(String name) { 251 this.name = name; 252 } 253 254 public void configureLevel(PlatformLogger.Level level) { 255 this.level = level; 256 } 257 258 @Override 259 public String getName() { 260 return name; 261 } 262 263 @Override 264 public boolean isLoggable(Level level) { 265 return this.level != OFF && this.level.intValue() <= level.getSeverity(); 266 } 267 268 @Override 269 public void log(Level level, ResourceBundle bundle, 270 String key, Throwable thrown) { 271 throw new UnsupportedOperationException(); 272 } 273 274 @Override 275 public void log(Level level, ResourceBundle bundle, 276 String format, Object... params) { 277 throw new UnsupportedOperationException(); 278 } 279 280 void log(LogEvent event) { 281 eventQueue.add(event); 282 } 283 284 @Override 285 public void log(Level level, Supplier<String> msgSupplier) { 286 throw new UnsupportedOperationException(); 287 } 288 289 @Override 290 public void log(Level level, Supplier<String> msgSupplier, 291 Throwable thrown) { 292 throw new UnsupportedOperationException(); 293 } 294 295 @Override 296 public void log(PlatformLogger.Level level, String msg) { 297 log(LogEvent.of(isLoggable(level), name, null, null, 298 level, null, msg, null, (Object[]) null)); 299 } 300 301 @Override 302 public void log(PlatformLogger.Level level, 303 Supplier<String> msgSupplier) { 304 log(LogEvent.of(isLoggable(level), name, null, null, 305 level, null, msgSupplier, null, (Object[]) null)); 306 } 307 308 @Override 309 public void log(PlatformLogger.Level level, String msg, 310 Object... params) { 311 log(LogEvent.of(isLoggable(level), name, null, null, 312 level, null, msg, null, params)); 313 } 314 315 @Override 316 public void log(PlatformLogger.Level level, String msg, 317 Throwable thrown) { 318 log(LogEvent.of(isLoggable(level), name, null, null, 319 level, null, msg, thrown, (Object[]) null)); 320 } 321 322 @Override 323 public void log(PlatformLogger.Level level, Throwable thrown, 324 Supplier<String> msgSupplier) { 325 log(LogEvent.of(isLoggable(level), name, null, null, 326 level, null, msgSupplier, thrown, (Object[]) null)); 327 } 328 329 @Override 330 public void logp(PlatformLogger.Level level, String sourceClass, 331 String sourceMethod, String msg) { 332 log(LogEvent.of(isLoggable(level), name, 333 sourceClass, sourceMethod, 334 level, null, msg, null, (Object[]) null)); 335 } 336 337 @Override 338 public void logp(PlatformLogger.Level level, String sourceClass, 339 String sourceMethod, Supplier<String> msgSupplier) { 340 log(LogEvent.of(isLoggable(level), name, 341 sourceClass, sourceMethod, 342 level, null, msgSupplier, null, (Object[]) null)); 343 } 344 345 @Override 346 public void logp(PlatformLogger.Level level, String sourceClass, 347 String sourceMethod, String msg, Object... params) { 348 log(LogEvent.of(isLoggable(level), name, 349 sourceClass, sourceMethod, 350 level, null, msg, null, params)); 351 } 352 353 @Override 354 public void logp(PlatformLogger.Level level, String sourceClass, 355 String sourceMethod, String msg, Throwable thrown) { 356 log(LogEvent.of(isLoggable(level), name, 357 sourceClass, sourceMethod, 358 level, null, msg, thrown, (Object[]) null)); 359 } 360 361 @Override 362 public void logp(PlatformLogger.Level level, String sourceClass, 363 String sourceMethod, Throwable thrown, 364 Supplier<String> msgSupplier) { 365 log(LogEvent.of(isLoggable(level), name, 366 sourceClass, sourceMethod, 367 level, null, msgSupplier, thrown, (Object[]) null)); 368 } 369 370 @Override 371 public void logrb(PlatformLogger.Level level, String sourceClass, 372 String sourceMethod, ResourceBundle bundle, String msg, 373 Object... params) { 374 log(LogEvent.of(isLoggable(level), name, 375 sourceClass, sourceMethod, 376 level, bundle, msg, null, params)); 377 } 378 379 @Override 380 public void logrb(PlatformLogger.Level level, ResourceBundle bundle, 381 String msg, Object... params) { 382 log(LogEvent.of(isLoggable(level), name, null, null, 383 level, bundle, msg, null, params)); 384 } 385 386 @Override 387 public void logrb(PlatformLogger.Level level, String sourceClass, 388 String sourceMethod, ResourceBundle bundle, String msg, 389 Throwable thrown) { 390 log(LogEvent.of(isLoggable(level), name, 391 sourceClass, sourceMethod, 392 level, bundle, msg, thrown, (Object[]) null)); 393 } 394 395 @Override 396 public void logrb(PlatformLogger.Level level, ResourceBundle bundle, 397 String msg, Throwable thrown) { 398 log(LogEvent.of(isLoggable(level), name, null, null, 399 level, bundle, msg, thrown, (Object[]) null)); 400 } 401 402 @Override 403 public boolean isLoggable(PlatformLogger.Level level) { 404 return this.level != OFF && level.intValue() 405 >= this.level.intValue(); 406 } 407 408 @Override 409 public boolean isEnabled() { 410 return this.level != OFF; 411 } 412 413 } 414 415 static ClassLoader getClassLoader(Module m) { 416 final boolean before = allowAll.get().getAndSet(true); 417 try { 418 return m.getClassLoader(); 419 } finally { 420 allowAll.get().set(before); 421 } 422 } 423 424 static final sun.util.logging.PlatformLogger.Level[] julLevels = { 425 sun.util.logging.PlatformLogger.Level.ALL, 426 sun.util.logging.PlatformLogger.Level.FINEST, 427 sun.util.logging.PlatformLogger.Level.FINER, 428 sun.util.logging.PlatformLogger.Level.FINE, 429 sun.util.logging.PlatformLogger.Level.CONFIG, 430 sun.util.logging.PlatformLogger.Level.INFO, 431 sun.util.logging.PlatformLogger.Level.WARNING, 432 sun.util.logging.PlatformLogger.Level.SEVERE, 433 sun.util.logging.PlatformLogger.Level.OFF, 434 }; 639 } catch (AccessControlException acx) { 640 if (hasRequiredPermissions) { 641 throw new RuntimeException("Unexpected security exception: ", acx); 642 } 643 if (!acx.getPermission().equals(LOGGERFINDER_PERMISSION)) { 644 throw new RuntimeException("Unexpected permission in exception: " + acx, acx); 645 } 646 System.out.println("Got expected exception for localized system logger: " + acx); 647 } 648 if (hasRequiredPermissions && appLogger2 == sysLogger2) { 649 throw new RuntimeException("identical loggers"); 650 } 651 if (appLogger2 == appLogger1) { 652 throw new RuntimeException("identical loggers"); 653 } 654 if (hasRequiredPermissions && sysLogger2 == sysLogger1) { 655 throw new RuntimeException("identical loggers"); 656 } 657 658 659 final LoggerImpl appSink; 660 final LoggerImpl sysSink; 661 boolean old = allowControl.get().get(); 662 allowControl.get().set(true); 663 try { 664 appSink = LoggerImpl.class.cast( 665 provider.getLogger("foo", LoggerBridgeTest.class.getModule())); 666 sysSink = LoggerImpl.class.cast( 667 provider.getLogger("foo", Thread.class.getModule())); 668 } finally { 669 allowControl.get().set(old); 670 } 671 672 testLogger(provider, loggerDescMap, "foo", null, convert(appLogger1), appSink); 673 if (hasRequiredPermissions) { 674 testLogger(provider, loggerDescMap, "foo", null, convert(sysLogger1), sysSink); 675 } 676 testLogger(provider, loggerDescMap, "foo", loggerBundle, convert(appLogger2), appSink); 677 if (hasRequiredPermissions) { 678 testLogger(provider, loggerDescMap, "foo", loggerBundle, convert(sysLogger2), sysSink); 679 } 680 } 681 682 public static class Foo { 683 684 } 685 686 static void verbose(String msg) { 703 } 704 705 static void checkLogEvent(LoggerFinder provider, String desc, 706 LogEvent expected, boolean expectNotNull) { 707 LogEvent actual = eventQueue.poll(); 708 if (actual == null && !expectNotNull) return; 709 if (actual != null && !expectNotNull) { 710 throw new RuntimeException("Unexpected log event found for " + desc 711 + "\n\tgot: " + actual); 712 } 713 if (!expected.equals(actual)) { 714 throw new RuntimeException("mismatch for " + desc 715 + "\n\texpected=" + expected 716 + "\n\t actual=" + actual); 717 } else { 718 verbose("Got expected results for " 719 + desc + "\n\t" + expected); 720 } 721 } 722 723 static void setLevel(LoggerImpl sink, 724 sun.util.logging.PlatformLogger.Level loggerLevel) { 725 sink.configureLevel(loggerLevel); 726 } 727 728 // Calls the methods defined on PlatformLogger.Bridge and verify the 729 // parameters received by the underlying LoggerImpl 730 // logger. 731 private static void testLogger(LoggerFinder provider, 732 Map<Object, String> loggerDescMap, 733 String name, 734 ResourceBundle loggerBundle, 735 PlatformLogger.Bridge logger, 736 LoggerImpl sink) { 737 738 System.out.println("Testing " + loggerDescMap.get(logger) + "[" + logger + "]"); 739 final sun.util.logging.PlatformLogger.Level OFF = sun.util.logging.PlatformLogger.Level.OFF; 740 741 Foo foo = new Foo(); 742 String fooMsg = foo.toString(); 743 System.out.println("\tlogger.log(messageLevel, fooMsg)"); 744 System.out.println("\tlogger.<level>(fooMsg)"); 745 for (sun.util.logging.PlatformLogger.Level loggerLevel : julLevels) { 746 setLevel(sink, loggerLevel); 747 for (sun.util.logging.PlatformLogger.Level messageLevel :julLevels) { 748 String desc = "logger.log(messageLevel, fooMsg): loggerLevel=" 749 + loggerLevel+", messageLevel="+messageLevel; 750 LogEvent expected = 751 LogEvent.of( 752 sequencer.get(), 753 loggerLevel != OFF && messageLevel.intValue() >= loggerLevel.intValue(), 754 name, messageLevel, loggerBundle, 755 fooMsg, (Throwable)null, (Object[])null); 756 logger.log(messageLevel, fooMsg); |