< prev index next >

test/java/lang/System/LoggerFinder/internal/LoggerBridgeTest/LoggerBridgeTest.java

Print this page




  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) {


< prev index next >