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");
147 @Override
148 public int hashCode() {
149 return Objects.hash(toArray());
150 }
151
152 public LogEvent cloneWith(long sequenceNumber)
153 throws CloneNotSupportedException {
154 LogEvent cloned = (LogEvent)super.clone();
155 cloned.sequenceNumber = sequenceNumber;
156 return cloned;
157 }
158
159 public static LogEvent of(long sequenceNumber,
160 boolean isLoggable, String name,
161 sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle,
162 String key, Throwable thrown, Object... params) {
163 return LogEvent.of(sequenceNumber, isLoggable, name,
164 null, null, level, bundle, key,
165 thrown, params);
166 }
167 public static LogEvent of(long sequenceNumber,
168 boolean isLoggable, String name,
169 sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle,
170 Supplier<String> supplier, Throwable thrown, Object... params) {
171 return LogEvent.of(sequenceNumber, isLoggable, name,
172 null, null, level, bundle, supplier,
173 thrown, params);
174 }
175
176 public static LogEvent of(long sequenceNumber,
177 boolean isLoggable, String name,
178 String className, String methodName,
179 sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle,
180 String key, Throwable thrown, Object... params) {
181 LogEvent evt = new LogEvent(sequenceNumber);
182 evt.loggerName = name;
183 evt.level = level;
184 evt.args = params;
185 evt.bundle = bundle;
186 evt.thrown = thrown;
214 evt.isLoggable = isLoggable;
215 evt.className = className;
216 evt.methodName = methodName;
217 return evt;
218 }
219
220 public static LogEvent of(boolean isLoggable, String name,
221 String className, String methodName,
222 sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle,
223 Supplier<String> supplier, Throwable thrown, Object... params) {
224 return LogEvent.of(sequencer.getAndIncrement(), isLoggable, name,
225 className, methodName, level, bundle, supplier, thrown, params);
226 }
227
228 }
229 static final Class<?> providerClass;
230 static {
231 try {
232 // Preload classes before the security manager is on.
233 providerClass = ClassLoader.getSystemClassLoader().loadClass("LoggerBridgeTest$LogProducerFinder");
234 ((LoggerFinder)providerClass.newInstance()).getLogger("foo", providerClass);
235 } catch (Exception ex) {
236 throw new ExceptionInInitializerError(ex);
237 }
238 }
239
240 public static class LogProducerFinder extends 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;
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 @Override
418 public Logger getLogger(String name, Class<?> 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<String,String> map = new ConcurrentHashMap<>();
448
449 @Override
450 protected Object handleGetObject(String key) {
451 if (key.contains(" (translated)")) {
452 throw new RuntimeException("Unexpected key: " + key);
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 final static Method lazyGetLogger;
495 static {
496 // jdk.internal.logging.LoggerBridge.getLogger(name, caller)
497 try {
498 Class<?> bridgeClass = Class.forName("jdk.internal.logger.LazyLoggers");
499 lazyGetLogger = bridgeClass.getDeclaredMethod("getLogger",
500 String.class, Class.class);
501 lazyGetLogger.setAccessible(true);
502 } catch (Throwable ex) {
503 throw new ExceptionInInitializerError(ex);
504 }
505 }
506
507 static Logger getLogger(LoggerFinder provider, String name, Class<?> caller) {
508 Logger logger;
509 try {
510 logger = Logger.class.cast(lazyGetLogger.invoke(null, name, caller));
511 } catch (Throwable x) {
512 Throwable t = (x instanceof InvocationTargetException) ?
513 ((InvocationTargetException)x).getTargetException() : x;
514 if (t instanceof RuntimeException) {
515 throw (RuntimeException)t;
516 } else if (t instanceof Exception) {
517 throw new RuntimeException(t);
518 } else {
519 throw (Error)t;
520 }
521 }
522 // The method above does not throw exception...
523 // call the provider here to verify that an exception would have
524 // been thrown by the provider.
525 if (logger != null && caller == Thread.class) {
526 Logger log = provider.getLogger(name, caller);
527 }
528 return logger;
529 }
530
531 static Logger getLogger(LoggerFinder provider, String name, ResourceBundle bundle, Class<?> caller) {
532 if (caller.getClassLoader() != null) {
533 return System.getLogger(name,bundle);
534 } else {
535 return provider.getLocalizedLogger(name, bundle, caller);
536 }
537 }
538
539 static PlatformLogger.Bridge convert(Logger logger) {
540 return PlatformLogger.Bridge.convert(logger);
541 }
542
543 static enum TestCases {NOSECURITY, NOPERMISSIONS, WITHPERMISSIONS};
544
545 static void setSecurityManager() {
546 if (System.getSecurityManager() == null) {
547 Policy.setPolicy(new SimplePolicy(allowControl, allowAccess, allowAll));
548 System.setSecurityManager(new SecurityManager());
549 }
550 }
551
552 public static void main(String[] args) {
597 provider = LoggerFinder.getLoggerFinder();
598 test(provider, true);
599 } finally {
600 allowControl.get().set(control);
601 }
602 break;
603 default:
604 throw new RuntimeException("Unknown test case: " + testCase);
605 }
606 });
607 System.out.println("\nPASSED: Tested " + sequencer.get() + " cases.");
608 }
609
610 public static void test(LoggerFinder provider, boolean hasRequiredPermissions) {
611
612 ResourceBundle loggerBundle = ResourceBundle.getBundle(MyLoggerBundle.class.getName());
613 final Map<Object, String> loggerDescMap = new HashMap<>();
614
615
616 Logger appLogger1 = System.getLogger("foo");
617 loggerDescMap.put(appLogger1, "LogProducer.getApplicationLogger(\"foo\")");
618
619 Logger sysLogger1 = null;
620 try {
621 sysLogger1 = getLogger(provider, "foo", Thread.class);
622 loggerDescMap.put(sysLogger1, "LogProducer.getSystemLogger(\"foo\")");
623 if (!hasRequiredPermissions) {
624 throw new RuntimeException("Managed to obtain a system logger without permission");
625 }
626 } catch (AccessControlException acx) {
627 if (hasRequiredPermissions) {
628 throw new RuntimeException("Unexpected security exception: ", acx);
629 }
630 if (!acx.getPermission().equals(LOGGERFINDER_PERMISSION)) {
631 throw new RuntimeException("Unexpected permission in exception: " + acx, acx);
632 }
633 System.out.println("Got expected exception for system logger: " + acx);
634 }
635
636
637 Logger appLogger2 =
638 System.getLogger("foo", loggerBundle);
639 loggerDescMap.put(appLogger2, "LogProducer.getApplicationLogger(\"foo\", loggerBundle)");
640
641 Logger sysLogger2 = null;
642 try {
643 sysLogger2 = getLogger(provider, "foo", loggerBundle, Thread.class);
644 loggerDescMap.put(sysLogger2, "provider.getSystemLogger(\"foo\", loggerBundle)");
645 if (!hasRequiredPermissions) {
646 throw new RuntimeException("Managed to obtain a system logger without permission");
647 }
648 } catch (AccessControlException acx) {
649 if (hasRequiredPermissions) {
650 throw new RuntimeException("Unexpected security exception: ", acx);
651 }
652 if (!acx.getPermission().equals(LOGGERFINDER_PERMISSION)) {
653 throw new RuntimeException("Unexpected permission in exception: " + acx, acx);
654 }
655 System.out.println("Got expected exception for localized system logger: " + acx);
656 }
657 if (hasRequiredPermissions && appLogger2 == sysLogger2) {
658 throw new RuntimeException("identical loggers");
659 }
660 if (appLogger2 == appLogger1) {
661 throw new RuntimeException("identical loggers");
662 }
663 if (hasRequiredPermissions && sysLogger2 == sysLogger1) {
664 throw new RuntimeException("identical loggers");
665 }
666
667
668 final LogProducerFinder.LoggerImpl appSink;
669 final LogProducerFinder.LoggerImpl sysSink;
670 boolean old = allowControl.get().get();
671 allowControl.get().set(true);
672 try {
673 appSink = LogProducerFinder.LoggerImpl.class.cast(
674 provider.getLogger("foo", LoggerBridgeTest.class));
675 sysSink = LogProducerFinder.LoggerImpl.class.cast(
676 provider.getLogger("foo", Thread.class));
677 } finally {
678 allowControl.get().set(old);
679 }
680
681 testLogger(provider, loggerDescMap, "foo", null, convert(appLogger1), appSink);
682 if (hasRequiredPermissions) {
683 testLogger(provider, loggerDescMap, "foo", null, convert(sysLogger1), sysSink);
684 }
685 testLogger(provider, loggerDescMap, "foo", loggerBundle, convert(appLogger2), appSink);
686 if (hasRequiredPermissions) {
687 testLogger(provider, loggerDescMap, "foo", loggerBundle, convert(sysLogger2), sysSink);
688 }
689 }
690
691 public static class Foo {
692
693 }
694
695 static void verbose(String msg) {
696 if (VERBOSE) {
|
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 import java.lang.reflect.Module;
55
56 /**
57 * @test
58 * @bug 8140364
59 * @summary JDK implementation specific unit test for JDK internal artifacts.
60 * Tests all bridge methods with the a custom backend whose
61 * loggers implement PlatformLogger.Bridge.
62 * @modules java.base/sun.util.logging
63 * java.base/jdk.internal.logger
64 * java.logging
65 * @build CustomSystemClassLoader LoggerBridgeTest
66 * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader LoggerBridgeTest NOSECURITY
67 * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader LoggerBridgeTest NOPERMISSIONS
68 * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader LoggerBridgeTest WITHPERMISSIONS
69 * @author danielfuchs
70 */
71 public class LoggerBridgeTest {
72
73 public static final RuntimePermission LOGGERFINDER_PERMISSION =
74 new RuntimePermission("loggerFinder");
148 @Override
149 public int hashCode() {
150 return Objects.hash(toArray());
151 }
152
153 public LogEvent cloneWith(long sequenceNumber)
154 throws CloneNotSupportedException {
155 LogEvent cloned = (LogEvent)super.clone();
156 cloned.sequenceNumber = sequenceNumber;
157 return cloned;
158 }
159
160 public static LogEvent of(long sequenceNumber,
161 boolean isLoggable, String name,
162 sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle,
163 String key, Throwable thrown, Object... params) {
164 return LogEvent.of(sequenceNumber, isLoggable, name,
165 null, null, level, bundle, key,
166 thrown, params);
167 }
168
169 public static LogEvent of(long sequenceNumber,
170 boolean isLoggable, String name,
171 sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle,
172 Supplier<String> supplier, Throwable thrown, Object... params) {
173 return LogEvent.of(sequenceNumber, isLoggable, name,
174 null, null, level, bundle, supplier,
175 thrown, params);
176 }
177
178 public static LogEvent of(long sequenceNumber,
179 boolean isLoggable, String name,
180 String className, String methodName,
181 sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle,
182 String key, Throwable thrown, Object... params) {
183 LogEvent evt = new LogEvent(sequenceNumber);
184 evt.loggerName = name;
185 evt.level = level;
186 evt.args = params;
187 evt.bundle = bundle;
188 evt.thrown = thrown;
216 evt.isLoggable = isLoggable;
217 evt.className = className;
218 evt.methodName = methodName;
219 return evt;
220 }
221
222 public static LogEvent of(boolean isLoggable, String name,
223 String className, String methodName,
224 sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle,
225 Supplier<String> supplier, Throwable thrown, Object... params) {
226 return LogEvent.of(sequencer.getAndIncrement(), isLoggable, name,
227 className, methodName, level, bundle, supplier, thrown, params);
228 }
229
230 }
231 static final Class<?> providerClass;
232 static {
233 try {
234 // Preload classes before the security manager is on.
235 providerClass = ClassLoader.getSystemClassLoader().loadClass("LoggerBridgeTest$LogProducerFinder");
236 ((LoggerFinder)providerClass.newInstance()).getLogger("foo", providerClass.getModule());
237 } catch (Exception ex) {
238 throw new ExceptionInInitializerError(ex);
239 }
240 }
241
242 public static class LogProducerFinder extends LoggerFinder {
243 final ConcurrentHashMap<String, LoggerImpl> system = new ConcurrentHashMap<>();
244 final ConcurrentHashMap<String, LoggerImpl> user = new ConcurrentHashMap<>();
245
246 public class LoggerImpl implements Logger, PlatformLogger.Bridge {
247 private final String name;
248 private sun.util.logging.PlatformLogger.Level level = sun.util.logging.PlatformLogger.Level.INFO;
249 private sun.util.logging.PlatformLogger.Level OFF = sun.util.logging.PlatformLogger.Level.OFF;
250 private sun.util.logging.PlatformLogger.Level FINE = sun.util.logging.PlatformLogger.Level.FINE;
251 private sun.util.logging.PlatformLogger.Level FINER = sun.util.logging.PlatformLogger.Level.FINER;
252 private sun.util.logging.PlatformLogger.Level FINEST = sun.util.logging.PlatformLogger.Level.FINEST;
253 private sun.util.logging.PlatformLogger.Level CONFIG = sun.util.logging.PlatformLogger.Level.CONFIG;
254 private sun.util.logging.PlatformLogger.Level INFO = sun.util.logging.PlatformLogger.Level.INFO;
255 private sun.util.logging.PlatformLogger.Level WARNING = sun.util.logging.PlatformLogger.Level.WARNING;
256 private sun.util.logging.PlatformLogger.Level SEVERE = sun.util.logging.PlatformLogger.Level.SEVERE;
400 public void logrb(sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle,
401 String msg, Throwable thrown) {
402 log(LogEvent.of(isLoggable(level), name, null, null,
403 level, bundle, msg, thrown, (Object[])null));
404 }
405
406 @Override
407 public boolean isLoggable(sun.util.logging.PlatformLogger.Level level) {
408 return this.level != OFF && level.intValue()
409 >= this.level.intValue();
410 }
411
412 @Override
413 public boolean isEnabled() {
414 return this.level != OFF;
415 }
416
417 }
418
419 @Override
420 public Logger getLogger(String name, Module caller) {
421 SecurityManager sm = System.getSecurityManager();
422 if (sm != null) {
423 sm.checkPermission(LOGGERFINDER_PERMISSION);
424 }
425 PrivilegedAction<ClassLoader> pa = () -> caller.getClassLoader();
426 ClassLoader callerLoader = AccessController.doPrivileged(pa);
427 if (callerLoader == null) {
428 return system.computeIfAbsent(name, (n) -> new LoggerImpl(n));
429 } else {
430 return user.computeIfAbsent(name, (n) -> new LoggerImpl(n));
431 }
432 }
433 }
434
435 static ClassLoader getClassLoader(Module m) {
436 final boolean before = allowAll.get().getAndSet(true);
437 try {
438 return m.getClassLoader();
439 } finally {
440 allowAll.get().set(before);
441 }
442 }
443
444 static final sun.util.logging.PlatformLogger.Level[] julLevels = {
445 sun.util.logging.PlatformLogger.Level.ALL,
446 sun.util.logging.PlatformLogger.Level.FINEST,
447 sun.util.logging.PlatformLogger.Level.FINER,
448 sun.util.logging.PlatformLogger.Level.FINE,
449 sun.util.logging.PlatformLogger.Level.CONFIG,
450 sun.util.logging.PlatformLogger.Level.INFO,
451 sun.util.logging.PlatformLogger.Level.WARNING,
452 sun.util.logging.PlatformLogger.Level.SEVERE,
453 sun.util.logging.PlatformLogger.Level.OFF,
454 };
455
456 public static class MyBundle extends ResourceBundle {
457
458 final ConcurrentHashMap<String,String> map = new ConcurrentHashMap<>();
459
460 @Override
461 protected Object handleGetObject(String key) {
462 if (key.contains(" (translated)")) {
463 throw new RuntimeException("Unexpected key: " + key);
491 }
492 @Override
493 public void flush() {
494 }
495 @Override
496 public void close() throws SecurityException {
497 }
498
499 }
500
501 public static class MyLoggerBundle extends MyBundle {
502
503 }
504
505 final static Method lazyGetLogger;
506 static {
507 // jdk.internal.logging.LoggerBridge.getLogger(name, caller)
508 try {
509 Class<?> bridgeClass = Class.forName("jdk.internal.logger.LazyLoggers");
510 lazyGetLogger = bridgeClass.getDeclaredMethod("getLogger",
511 String.class, Module.class);
512 lazyGetLogger.setAccessible(true);
513 } catch (Throwable ex) {
514 throw new ExceptionInInitializerError(ex);
515 }
516 }
517
518 static Logger getLogger(LoggerFinder provider, String name, Module caller) {
519 Logger logger;
520 try {
521 logger = Logger.class.cast(lazyGetLogger.invoke(null, name, caller));
522 } catch (Throwable x) {
523 Throwable t = (x instanceof InvocationTargetException) ?
524 ((InvocationTargetException)x).getTargetException() : x;
525 if (t instanceof RuntimeException) {
526 throw (RuntimeException)t;
527 } else if (t instanceof Exception) {
528 throw new RuntimeException(t);
529 } else {
530 throw (Error)t;
531 }
532 }
533 // The method above does not throw exception...
534 // call the provider here to verify that an exception would have
535 // been thrown by the provider.
536 if (logger != null && caller == Thread.class.getModule()) {
537 Logger log = provider.getLogger(name, caller);
538 }
539 return logger;
540 }
541
542 static Logger getLogger(LoggerFinder provider, String name, ResourceBundle bundle, Module caller) {
543 if (getClassLoader(caller) != null) {
544 return System.getLogger(name,bundle);
545 } else {
546 return provider.getLocalizedLogger(name, bundle, caller);
547 }
548 }
549
550 static PlatformLogger.Bridge convert(Logger logger) {
551 return PlatformLogger.Bridge.convert(logger);
552 }
553
554 static enum TestCases {NOSECURITY, NOPERMISSIONS, WITHPERMISSIONS};
555
556 static void setSecurityManager() {
557 if (System.getSecurityManager() == null) {
558 Policy.setPolicy(new SimplePolicy(allowControl, allowAccess, allowAll));
559 System.setSecurityManager(new SecurityManager());
560 }
561 }
562
563 public static void main(String[] args) {
608 provider = LoggerFinder.getLoggerFinder();
609 test(provider, true);
610 } finally {
611 allowControl.get().set(control);
612 }
613 break;
614 default:
615 throw new RuntimeException("Unknown test case: " + testCase);
616 }
617 });
618 System.out.println("\nPASSED: Tested " + sequencer.get() + " cases.");
619 }
620
621 public static void test(LoggerFinder provider, boolean hasRequiredPermissions) {
622
623 ResourceBundle loggerBundle = ResourceBundle.getBundle(MyLoggerBundle.class.getName());
624 final Map<Object, String> loggerDescMap = new HashMap<>();
625
626
627 Logger appLogger1 = System.getLogger("foo");
628 loggerDescMap.put(appLogger1, "System.getLogger(\"foo\")");
629
630 Logger sysLogger1 = null;
631 try {
632 sysLogger1 = getLogger(provider, "foo", Thread.class.getModule());
633 loggerDescMap.put(sysLogger1, "provider.getLogger(\"foo\", Thread.class.getModule())");
634 if (!hasRequiredPermissions) {
635 throw new RuntimeException("Managed to obtain a system logger without permission");
636 }
637 } catch (AccessControlException acx) {
638 if (hasRequiredPermissions) {
639 throw new RuntimeException("Unexpected security exception: ", acx);
640 }
641 if (!acx.getPermission().equals(LOGGERFINDER_PERMISSION)) {
642 throw new RuntimeException("Unexpected permission in exception: " + acx, acx);
643 }
644 System.out.println("Got expected exception for system logger: " + acx);
645 }
646
647
648 Logger appLogger2 =
649 System.getLogger("foo", loggerBundle);
650 loggerDescMap.put(appLogger2, "System.getLogger(\"foo\", loggerBundle)");
651
652 Logger sysLogger2 = null;
653 try {
654 sysLogger2 = getLogger(provider, "foo", loggerBundle, Thread.class.getModule());
655 loggerDescMap.put(sysLogger2, "provider.getLogger(\"foo\", loggerBundle, Thread.class.getModule())");
656 if (!hasRequiredPermissions) {
657 throw new RuntimeException("Managed to obtain a system logger without permission");
658 }
659 } catch (AccessControlException acx) {
660 if (hasRequiredPermissions) {
661 throw new RuntimeException("Unexpected security exception: ", acx);
662 }
663 if (!acx.getPermission().equals(LOGGERFINDER_PERMISSION)) {
664 throw new RuntimeException("Unexpected permission in exception: " + acx, acx);
665 }
666 System.out.println("Got expected exception for localized system logger: " + acx);
667 }
668 if (hasRequiredPermissions && appLogger2 == sysLogger2) {
669 throw new RuntimeException("identical loggers");
670 }
671 if (appLogger2 == appLogger1) {
672 throw new RuntimeException("identical loggers");
673 }
674 if (hasRequiredPermissions && sysLogger2 == sysLogger1) {
675 throw new RuntimeException("identical loggers");
676 }
677
678
679 final LogProducerFinder.LoggerImpl appSink;
680 final LogProducerFinder.LoggerImpl sysSink;
681 boolean old = allowControl.get().get();
682 allowControl.get().set(true);
683 try {
684 appSink = LogProducerFinder.LoggerImpl.class.cast(
685 provider.getLogger("foo", LoggerBridgeTest.class.getModule()));
686 sysSink = LogProducerFinder.LoggerImpl.class.cast(
687 provider.getLogger("foo", Thread.class.getModule()));
688 } finally {
689 allowControl.get().set(old);
690 }
691
692 testLogger(provider, loggerDescMap, "foo", null, convert(appLogger1), appSink);
693 if (hasRequiredPermissions) {
694 testLogger(provider, loggerDescMap, "foo", null, convert(sysLogger1), sysSink);
695 }
696 testLogger(provider, loggerDescMap, "foo", loggerBundle, convert(appLogger2), appSink);
697 if (hasRequiredPermissions) {
698 testLogger(provider, loggerDescMap, "foo", loggerBundle, convert(sysLogger2), sysSink);
699 }
700 }
701
702 public static class Foo {
703
704 }
705
706 static void verbose(String msg) {
707 if (VERBOSE) {
|