--- old/test/jdk/java/lang/System/LoggerFinder/internal/BaseDefaultLoggerFinderTest/BaseDefaultLoggerFinderTest.java 2018-12-18 14:27:34.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/BaseDefaultLoggerFinderTest/BaseDefaultLoggerFinderTest.java 2018-12-18 14:27:34.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,7 +64,7 @@ * implementation. * @modules java.base/sun.util.logging * java.base/jdk.internal.logger - * @build AccessSystemLogger BaseDefaultLoggerFinderTest CustomSystemClassLoader + * @build AccessSystemLogger BaseDefaultLoggerFinderTest CustomSystemClassLoader BaseLoggerFinder * @run driver AccessSystemLogger * @run main/othervm -Xbootclasspath/a:boot -Djava.system.class.loader=CustomSystemClassLoader BaseDefaultLoggerFinderTest NOSECURITY * @run main/othervm -Xbootclasspath/a:boot -Djava.system.class.loader=CustomSystemClassLoader BaseDefaultLoggerFinderTest NOPERMISSIONS @@ -97,7 +97,7 @@ static { try { providerClass = new Class[] { - ClassLoader.getSystemClassLoader().loadClass("BaseDefaultLoggerFinderTest$BaseLoggerFinder"), + ClassLoader.getSystemClassLoader().loadClass("BaseLoggerFinder"), }; } catch (ClassNotFoundException ex) { throw new ExceptionInInitializerError(ex); @@ -120,43 +120,6 @@ PlatformLogger.Bridge asPlatformLoggerBridge(Logger logger); } - public static class BaseLoggerFinder extends DefaultLoggerFinder implements TestLoggerFinder { - - static final RuntimePermission LOGGERFINDER_PERMISSION = - new RuntimePermission("loggerFinder"); - public BaseLoggerFinder() { - if (fails.get()) { - throw new RuntimeException("Simulate exception while loading provider"); - } - } - - @Override - public void setLevel(Logger logger, Level level, Module caller) { - PrivilegedAction pa = () -> { - setLevel(logger, PlatformLogger.toPlatformLevel(level), caller); - return null; - }; - AccessController.doPrivileged(pa); - } - - @Override - public void setLevel(Logger logger, PlatformLogger.Level level, Module caller) { - PrivilegedAction pa = () -> demandLoggerFor(logger.getName(), caller); - Logger impl = AccessController.doPrivileged(pa); - SimpleConsoleLogger.class.cast(impl) - .getLoggerConfiguration() - .setPlatformLevel(level); - } - - @Override - public PlatformLogger.Bridge asPlatformLoggerBridge(Logger logger) { - PrivilegedAction pa = () -> - PlatformLogger.Bridge.convert(logger); - return AccessController.doPrivileged(pa); - } - - } - public static class MyBundle extends ResourceBundle { final ConcurrentHashMap map = new ConcurrentHashMap<>(); @@ -477,7 +440,7 @@ System.out.println("\n*** Without Security Manager\n"); System.out.println(TestLoggerFinder.conf.get()); provider = getLoggerFinder(expectedClass); - if (!provider.getClass().getName().equals("BaseDefaultLoggerFinderTest$BaseLoggerFinder")) { + if (!provider.getClass().getName().equals("BaseLoggerFinder")) { throw new RuntimeException("Unexpected provider: " + provider.getClass().getName()); } test(provider, true); @@ -498,7 +461,7 @@ try { allowControl.get().set(true); provider = getLoggerFinder(expectedClass); - if (!provider.getClass().getName().equals("BaseDefaultLoggerFinderTest$BaseLoggerFinder")) { + if (!provider.getClass().getName().equals("BaseLoggerFinder")) { throw new RuntimeException("Unexpected provider: " + provider.getClass().getName()); } } finally { @@ -516,7 +479,7 @@ try { allowControl.get().set(true); provider = getLoggerFinder(expectedClass); - if (!provider.getClass().getName().equals("BaseDefaultLoggerFinderTest$BaseLoggerFinder")) { + if (!provider.getClass().getName().equals("BaseLoggerFinder")) { throw new RuntimeException("Unexpected provider: " + provider.getClass().getName()); } test(provider, true); @@ -532,7 +495,7 @@ try { allowControl.get().set(true); provider = getLoggerFinder(expectedClass); - if (!provider.getClass().getName().equals("BaseDefaultLoggerFinderTest$BaseLoggerFinder")) { + if (!provider.getClass().getName().equals("BaseLoggerFinder")) { throw new RuntimeException("Unexpected provider: " + provider.getClass().getName()); } test(provider, CustomLoggerWrapper::new, true); @@ -550,7 +513,7 @@ try { allowControl.get().set(true); provider = getLoggerFinder(expectedClass); - if (!provider.getClass().getName().equals("BaseDefaultLoggerFinderTest$BaseLoggerFinder")) { + if (!provider.getClass().getName().equals("BaseLoggerFinder")) { throw new RuntimeException("Unexpected provider: " + provider.getClass().getName()); } test(provider, ReflectionLoggerWrapper::new, true); --- old/test/jdk/java/lang/System/LoggerFinder/internal/BaseDefaultLoggerFinderTest/CustomSystemClassLoader.java 2018-12-18 14:27:36.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/BaseDefaultLoggerFinderTest/CustomSystemClassLoader.java 2018-12-18 14:27:36.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** @@ -48,8 +49,8 @@ final List finderClassNames = - Arrays.asList("BaseDefaultLoggerFinderTest$BaseLoggerFinder"); - final Map> finderClasses = new HashMap<>(); + Arrays.asList("BaseLoggerFinder"); + final Map> finderClasses = new ConcurrentHashMap<>(); Class testLoggerFinderClass; public CustomSystemClassLoader() { @@ -61,9 +62,14 @@ private Class defineFinderClass(String name) throws ClassNotFoundException { + Class finderClass = finderClasses.get(name); + if (finderClass != null) return finderClass; + final Object obj = getClassLoadingLock(name); synchronized(obj) { - if (finderClasses.get(name) != null) return finderClasses.get(name); + finderClasses.get(name); + if (finderClass != null) return finderClass; + if (testLoggerFinderClass == null) { // Hack: we load testLoggerFinderClass to get its code source. // we can't use this.getClass() since we are in the boot. @@ -76,7 +82,7 @@ byte[] b = Files.readAllBytes(file.toPath()); Permissions perms = new Permissions(); perms.add(new AllPermission()); - Class finderClass = defineClass( + finderClass = defineClass( name, b, 0, b.length, new ProtectionDomain( this.getClass().getProtectionDomain().getCodeSource(), perms)); @@ -94,9 +100,13 @@ } } + private static boolean matches(String prefix, String name) { + return prefix.equals(name) || name.startsWith(prefix + "$"); + } + @Override public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - if (finderClassNames.contains(name)) { + if (finderClassNames.stream().anyMatch(n -> matches(n, name))) { Class c = defineFinderClass(name); if (resolve) { resolveClass(c); @@ -108,7 +118,7 @@ @Override protected Class findClass(String name) throws ClassNotFoundException { - if (finderClassNames.contains(name)) { + if (finderClassNames.stream().anyMatch(n -> matches(n, name))) { return defineFinderClass(name); } return super.findClass(name); --- old/test/jdk/java/lang/System/LoggerFinder/internal/BaseDefaultLoggerFinderTest/META-INF/services/java.lang.System$LoggerFinder 2018-12-18 14:27:37.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/BaseDefaultLoggerFinderTest/META-INF/services/java.lang.System$LoggerFinder 2018-12-18 14:27:37.000000000 +0100 @@ -1 +1 @@ -BaseDefaultLoggerFinderTest$BaseLoggerFinder +BaseLoggerFinder --- old/test/jdk/java/lang/System/LoggerFinder/internal/BaseLoggerBridgeTest/BaseLoggerBridgeTest.java 2018-12-18 14:27:39.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/BaseLoggerBridgeTest/BaseLoggerBridgeTest.java 2018-12-18 14:27:39.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,7 @@ * Tests a naive implementation of System.Logger, and in particular * the default mapping provided by PlatformLogger.Bridge. * @modules java.base/sun.util.logging java.base/jdk.internal.logger - * @build CustomSystemClassLoader BaseLoggerBridgeTest + * @build CustomSystemClassLoader BaseLoggerFinder BaseLoggerBridgeTest * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader BaseLoggerBridgeTest NOSECURITY * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader BaseLoggerBridgeTest NOPERMISSIONS * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader BaseLoggerBridgeTest WITHPERMISSIONS @@ -94,7 +94,7 @@ static final Class providerClass; static { try { - providerClass = ClassLoader.getSystemClassLoader().loadClass("BaseLoggerBridgeTest$BaseLoggerFinder"); + providerClass = ClassLoader.getSystemClassLoader().loadClass("BaseLoggerFinder"); } catch (ClassNotFoundException ex) { throw new ExceptionInInitializerError(ex); } @@ -336,33 +336,12 @@ log(LogEvent.of(isLoggable(level), name, level, thrown, msgSupplier)); } - - } public Logger getLogger(String name, Module caller); public Logger getLocalizedLogger(String name, ResourceBundle bundle, Module caller); } - public static class BaseLoggerFinder extends LoggerFinder implements TestLoggerFinder { - static final RuntimePermission LOGGERFINDER_PERMISSION = - new RuntimePermission("loggerFinder"); - @Override - public Logger getLogger(String name, Module caller) { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(LOGGERFINDER_PERMISSION); - } - PrivilegedAction pa = () -> caller.getClassLoader(); - ClassLoader callerLoader = AccessController.doPrivileged(pa); - if (callerLoader == null) { - return system.computeIfAbsent(name, (n) -> new LoggerImpl(n)); - } else { - return user.computeIfAbsent(name, (n) -> new LoggerImpl(n)); - } - } - } - static PlatformLogger.Bridge convert(Logger logger) { boolean old = allowAll.get().get(); allowAccess.get().set(true); --- old/test/jdk/java/lang/System/LoggerFinder/internal/BaseLoggerBridgeTest/CustomSystemClassLoader.java 2018-12-18 14:27:41.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/BaseLoggerBridgeTest/CustomSystemClassLoader.java 2018-12-18 14:27:40.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ import java.security.AllPermission; import java.security.Permissions; import java.security.ProtectionDomain; - +import java.util.concurrent.ConcurrentHashMap; /** * A custom ClassLoader to load the concrete LoggerFinder class @@ -39,7 +39,7 @@ public class CustomSystemClassLoader extends ClassLoader { - Class finderClass = null; + private final ConcurrentHashMap> classes = new ConcurrentHashMap<>(); public CustomSystemClassLoader() { super(); @@ -50,8 +50,13 @@ private Class defineFinderClass(String name) throws ClassNotFoundException { + Class finderClass = classes.get(name); + if (finderClass != null) return finderClass; + final Object obj = getClassLoadingLock(name); + synchronized(obj) { + finderClass = classes.get(name); if (finderClass != null) return finderClass; URL url = this.getClass().getProtectionDomain().getCodeSource().getLocation(); @@ -66,6 +71,7 @@ this.getClass().getProtectionDomain().getCodeSource(), perms)); System.out.println("Loaded " + name); + classes.put(name, finderClass); return finderClass; } catch (Throwable ex) { ex.printStackTrace(); @@ -80,7 +86,7 @@ @Override public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - if (name.endsWith("$BaseLoggerFinder")) { + if (name.equals("BaseLoggerFinder") || name.startsWith("BaseLoggerFinder$")) { Class c = defineFinderClass(name); if (resolve) { resolveClass(c); @@ -92,7 +98,7 @@ @Override protected Class findClass(String name) throws ClassNotFoundException { - if (name.endsWith("$BaseLoggerFinder")) { + if (name.equals("BaseLoggerFinder") || name.startsWith("BaseLoggerFinder$")) { return defineFinderClass(name); } return super.findClass(name); --- old/test/jdk/java/lang/System/LoggerFinder/internal/BaseLoggerBridgeTest/META-INF/services/java.lang.System$LoggerFinder 2018-12-18 14:27:42.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/BaseLoggerBridgeTest/META-INF/services/java.lang.System$LoggerFinder 2018-12-18 14:27:42.000000000 +0100 @@ -1 +1 @@ -BaseLoggerBridgeTest$BaseLoggerFinder +BaseLoggerFinder --- old/test/jdk/java/lang/System/LoggerFinder/internal/BasePlatformLoggerTest/BasePlatformLoggerTest.java 2018-12-18 14:27:44.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/BasePlatformLoggerTest/BasePlatformLoggerTest.java 2018-12-18 14:27:43.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,7 @@ * Tests a naive implementation of System.Logger, and in particular * the default mapping provided by PlatformLogger. * @modules java.base/sun.util.logging - * @build CustomSystemClassLoader BasePlatformLoggerTest + * @build CustomSystemClassLoader BaseLoggerFinder BasePlatformLoggerTest * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader BasePlatformLoggerTest NOSECURITY * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader BasePlatformLoggerTest NOPERMISSIONS * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader BasePlatformLoggerTest WITHPERMISSIONS @@ -90,7 +90,7 @@ static final Class providerClass; static { try { - providerClass = ClassLoader.getSystemClassLoader().loadClass("BasePlatformLoggerTest$BaseLoggerFinder"); + providerClass = ClassLoader.getSystemClassLoader().loadClass("BaseLoggerFinder"); } catch (ClassNotFoundException ex) { throw new ExceptionInInitializerError(ex); } @@ -330,23 +330,6 @@ public Logger getLogger(String name, Module caller); } - public static class BaseLoggerFinder extends LoggerFinder implements TestLoggerFinder { - @Override - public Logger getLogger(String name, Module caller) { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(LOGGERFINDER_PERMISSION); - } - PrivilegedAction pa = () -> caller.getClassLoader(); - ClassLoader callerLoader = AccessController.doPrivileged(pa); - if (callerLoader == null) { - return system.computeIfAbsent(name, (n) -> new LoggerImpl(n)); - } else { - return user.computeIfAbsent(name, (n) -> new LoggerImpl(n)); - } - } - } - static PlatformLogger getPlatformLogger(String name) { boolean old = allowAccess.get().get(); allowAccess.get().set(true); --- old/test/jdk/java/lang/System/LoggerFinder/internal/BasePlatformLoggerTest/CustomSystemClassLoader.java 2018-12-18 14:27:45.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/BasePlatformLoggerTest/CustomSystemClassLoader.java 2018-12-18 14:27:45.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ import java.security.AllPermission; import java.security.Permissions; import java.security.ProtectionDomain; +import java.util.concurrent.ConcurrentHashMap; /** @@ -39,7 +40,7 @@ public class CustomSystemClassLoader extends ClassLoader { - Class finderClass = null; + private final ConcurrentHashMap> classes = new ConcurrentHashMap<>(); public CustomSystemClassLoader() { super(); @@ -50,8 +51,12 @@ private Class defineFinderClass(String name) throws ClassNotFoundException { + Class finderClass = classes.get(name); + if (finderClass != null) return finderClass; + final Object obj = getClassLoadingLock(name); synchronized(obj) { + finderClass = classes.get(name); if (finderClass != null) return finderClass; URL url = this.getClass().getProtectionDomain().getCodeSource().getLocation(); @@ -66,6 +71,7 @@ this.getClass().getProtectionDomain().getCodeSource(), perms)); System.out.println("Loaded " + name); + classes.put(name, finderClass); return finderClass; } catch (Throwable ex) { ex.printStackTrace(); @@ -80,7 +86,7 @@ @Override public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - if (name.endsWith("$BaseLoggerFinder")) { + if (name.endsWith("BaseLoggerFinder") || name.startsWith("BaseLoggerFinder$")) { Class c = defineFinderClass(name); if (resolve) { resolveClass(c); @@ -92,7 +98,7 @@ @Override protected Class findClass(String name) throws ClassNotFoundException { - if (name.endsWith("$BaseLoggerFinder")) { + if (name.endsWith("BaseLoggerFinder") || name.startsWith("BaseLoggerFinder$")) { return defineFinderClass(name); } return super.findClass(name); --- old/test/jdk/java/lang/System/LoggerFinder/internal/BasePlatformLoggerTest/META-INF/services/java.lang.System$LoggerFinder 2018-12-18 14:27:47.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/BasePlatformLoggerTest/META-INF/services/java.lang.System$LoggerFinder 2018-12-18 14:27:47.000000000 +0100 @@ -1 +1 @@ -BasePlatformLoggerTest$BaseLoggerFinder +BaseLoggerFinder --- old/test/jdk/java/lang/System/LoggerFinder/internal/LoggerBridgeTest/CustomSystemClassLoader.java 2018-12-18 14:27:48.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/LoggerBridgeTest/CustomSystemClassLoader.java 2018-12-18 14:27:48.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ import java.security.AllPermission; import java.security.Permissions; import java.security.ProtectionDomain; +import java.util.concurrent.ConcurrentHashMap; /** @@ -39,8 +40,7 @@ public class CustomSystemClassLoader extends ClassLoader { - Class loggerFinderClass = null; -// Class loggerImplClass = null; + private final ConcurrentHashMap> classes = new ConcurrentHashMap<>(); public CustomSystemClassLoader() { super(); @@ -51,8 +51,13 @@ private Class defineFinderClass(String name) throws ClassNotFoundException { + + Class loggerFinderClass = classes.get(name); + if (loggerFinderClass != null) return loggerFinderClass; + final Object obj = getClassLoadingLock(name); synchronized(obj) { + loggerFinderClass = classes.get(name); if (loggerFinderClass != null) return loggerFinderClass; URL url = this.getClass().getProtectionDomain().getCodeSource().getLocation(); @@ -66,6 +71,7 @@ name, b, 0, b.length, new ProtectionDomain( this.getClass().getProtectionDomain().getCodeSource(), perms)); + classes.put(name, loggerFinderClass); System.out.println("Loaded " + name); return loggerFinderClass; } catch (Throwable ex) { @@ -78,61 +84,22 @@ } } } -// private Class defineLoggerImplClass(String name) -// throws ClassNotFoundException { -// final Object obj = getClassLoadingLock(name); -// synchronized(obj) { -// if (loggerImplClass != null) return loggerImplClass; -// -// URL url = this.getClass().getProtectionDomain().getCodeSource().getLocation(); -// File file = new File(url.getPath(), name+".class"); -// if (file.canRead()) { -// try { -// byte[] b = Files.readAllBytes(file.toPath()); -// Permissions perms = new Permissions(); -// perms.add(new AllPermission()); -// loggerImplClass = defineClass( -// name, b, 0, b.length, new ProtectionDomain( -// this.getClass().getProtectionDomain().getCodeSource(), -// perms)); -// System.out.println("Loaded " + name); -// return loggerImplClass; -// } catch (Throwable ex) { -// ex.printStackTrace(); -// throw new ClassNotFoundException(name, ex); -// } -// } else { -// throw new ClassNotFoundException(name, -// new IOException(file.toPath() + ": can't read")); -// } -// } -// } -// + @Override public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - if (name.endsWith("$LogProducerFinder")) { + if (name.equals("LogProducerFinder") || name.startsWith("LogProducerFinder$")) { Class c = defineFinderClass(name); if (resolve) { resolveClass(c); } return c; } -// if (name.endsWith("$LogProducerFinder$LoggerImpl")) { -// Class c = defineLoggerImplClass(name); -// if (resolve) { -// resolveClass(c); -// } -// return c; -// } return super.loadClass(name, resolve); } @Override protected Class findClass(String name) throws ClassNotFoundException { -// if (name.endsWith("$LogProducerFinder$LoggerImpl")) { -// return defineLoggerImplClass(name); -// } - if (name.endsWith("$$LogProducerFinder")) { + if (name.equals("LogProducerFinder") || name.startsWith("LogProducerFinder$")) { return defineFinderClass(name); } return super.findClass(name); --- old/test/jdk/java/lang/System/LoggerFinder/internal/LoggerBridgeTest/LoggerBridgeTest.java 2018-12-18 14:27:50.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/LoggerBridgeTest/LoggerBridgeTest.java 2018-12-18 14:27:50.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,13 +23,11 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.security.AccessControlException; -import java.security.AccessController; import java.security.CodeSource; import java.security.Permission; import java.security.PermissionCollection; import java.security.Permissions; import java.security.Policy; -import java.security.PrivilegedAction; import java.security.ProtectionDomain; import java.util.Arrays; import java.util.Collections; @@ -48,7 +46,6 @@ import java.util.logging.LogRecord; import java.lang.System.LoggerFinder; import java.lang.System.Logger; -import java.lang.System.Logger.Level; import java.util.stream.Stream; import sun.util.logging.PlatformLogger; @@ -61,7 +58,7 @@ * @modules java.base/sun.util.logging * java.base/jdk.internal.logger * java.logging - * @build CustomSystemClassLoader LoggerBridgeTest + * @build CustomSystemClassLoader LogProducerFinder LoggerBridgeTest * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader LoggerBridgeTest NOSECURITY * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader LoggerBridgeTest NOPERMISSIONS * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader LoggerBridgeTest WITHPERMISSIONS @@ -231,204 +228,188 @@ static { try { // Preload classes before the security manager is on. - providerClass = ClassLoader.getSystemClassLoader().loadClass("LoggerBridgeTest$LogProducerFinder"); + providerClass = ClassLoader.getSystemClassLoader().loadClass("LogProducerFinder"); ((LoggerFinder)providerClass.newInstance()).getLogger("foo", providerClass.getModule()); } catch (Exception ex) { throw new ExceptionInInitializerError(ex); } } - public static class LogProducerFinder extends LoggerFinder { - final ConcurrentHashMap system = new ConcurrentHashMap<>(); - final ConcurrentHashMap user = new ConcurrentHashMap<>(); - - public class LoggerImpl implements Logger, PlatformLogger.Bridge { - private final String name; - private sun.util.logging.PlatformLogger.Level level = sun.util.logging.PlatformLogger.Level.INFO; - private sun.util.logging.PlatformLogger.Level OFF = sun.util.logging.PlatformLogger.Level.OFF; - private sun.util.logging.PlatformLogger.Level FINE = sun.util.logging.PlatformLogger.Level.FINE; - private sun.util.logging.PlatformLogger.Level FINER = sun.util.logging.PlatformLogger.Level.FINER; - private sun.util.logging.PlatformLogger.Level FINEST = sun.util.logging.PlatformLogger.Level.FINEST; - private sun.util.logging.PlatformLogger.Level CONFIG = sun.util.logging.PlatformLogger.Level.CONFIG; - private sun.util.logging.PlatformLogger.Level INFO = sun.util.logging.PlatformLogger.Level.INFO; - private sun.util.logging.PlatformLogger.Level WARNING = sun.util.logging.PlatformLogger.Level.WARNING; - private sun.util.logging.PlatformLogger.Level SEVERE = sun.util.logging.PlatformLogger.Level.SEVERE; + public static class LoggerImpl implements System.Logger, PlatformLogger.Bridge { + private final String name; + private PlatformLogger.Level level = PlatformLogger.Level.INFO; + private PlatformLogger.Level OFF = PlatformLogger.Level.OFF; + private PlatformLogger.Level FINE = PlatformLogger.Level.FINE; + private PlatformLogger.Level FINER = PlatformLogger.Level.FINER; + private PlatformLogger.Level FINEST = PlatformLogger.Level.FINEST; + private PlatformLogger.Level CONFIG = PlatformLogger.Level.CONFIG; + private PlatformLogger.Level INFO = PlatformLogger.Level.INFO; + private PlatformLogger.Level WARNING = PlatformLogger.Level.WARNING; + private PlatformLogger.Level SEVERE = PlatformLogger.Level.SEVERE; - public LoggerImpl(String name) { - this.name = name; - } - - @Override - public String getName() { - return name; - } + public LoggerImpl(String name) { + this.name = name; + } - @Override - public boolean isLoggable(Level level) { - return this.level != OFF && this.level.intValue() <= level.getSeverity(); - } + public void configureLevel(PlatformLogger.Level level) { + this.level = level; + } - @Override - public void log(Level level, ResourceBundle bundle, - String key, Throwable thrown) { - throw new UnsupportedOperationException(); - } + @Override + public String getName() { + return name; + } - @Override - public void log(Level level, ResourceBundle bundle, - String format, Object... params) { - throw new UnsupportedOperationException(); - } + @Override + public boolean isLoggable(Level level) { + return this.level != OFF && this.level.intValue() <= level.getSeverity(); + } - void log(LogEvent event) { - eventQueue.add(event); - } + @Override + public void log(Level level, ResourceBundle bundle, + String key, Throwable thrown) { + throw new UnsupportedOperationException(); + } - @Override - public void log(Level level, Supplier msgSupplier) { - throw new UnsupportedOperationException(); - } + @Override + public void log(Level level, ResourceBundle bundle, + String format, Object... params) { + throw new UnsupportedOperationException(); + } - @Override - public void log(Level level, Supplier msgSupplier, - Throwable thrown) { - throw new UnsupportedOperationException(); - } + void log(LogEvent event) { + eventQueue.add(event); + } - @Override - public void log(sun.util.logging.PlatformLogger.Level level, String msg) { - log(LogEvent.of(isLoggable(level), name, null, null, - level, null, msg, null, (Object[])null)); - } + @Override + public void log(Level level, Supplier msgSupplier) { + throw new UnsupportedOperationException(); + } - @Override - public void log(sun.util.logging.PlatformLogger.Level level, - Supplier msgSupplier) { - log(LogEvent.of(isLoggable(level), name, null, null, - level, null, msgSupplier, null, (Object[])null)); - } + @Override + public void log(Level level, Supplier msgSupplier, + Throwable thrown) { + throw new UnsupportedOperationException(); + } - @Override - public void log(sun.util.logging.PlatformLogger.Level level, String msg, - Object... params) { - log(LogEvent.of(isLoggable(level), name, null, null, - level, null, msg, null, params)); - } + @Override + public void log(PlatformLogger.Level level, String msg) { + log(LogEvent.of(isLoggable(level), name, null, null, + level, null, msg, null, (Object[]) null)); + } - @Override - public void log(sun.util.logging.PlatformLogger.Level level, String msg, - Throwable thrown) { - log(LogEvent.of(isLoggable(level), name, null, null, - level, null, msg, thrown, (Object[])null)); - } + @Override + public void log(PlatformLogger.Level level, + Supplier msgSupplier) { + log(LogEvent.of(isLoggable(level), name, null, null, + level, null, msgSupplier, null, (Object[]) null)); + } - @Override - public void log(sun.util.logging.PlatformLogger.Level level, Throwable thrown, - Supplier msgSupplier) { - log(LogEvent.of(isLoggable(level), name, null, null, - level, null, msgSupplier, thrown, (Object[])null)); - } + @Override + public void log(PlatformLogger.Level level, String msg, + Object... params) { + log(LogEvent.of(isLoggable(level), name, null, null, + level, null, msg, null, params)); + } - @Override - public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, - String sourceMethod, String msg) { - log(LogEvent.of(isLoggable(level), name, - sourceClass, sourceMethod, - level, null, msg, null, (Object[])null)); - } + @Override + public void log(PlatformLogger.Level level, String msg, + Throwable thrown) { + log(LogEvent.of(isLoggable(level), name, null, null, + level, null, msg, thrown, (Object[]) null)); + } - @Override - public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, - String sourceMethod, Supplier msgSupplier) { - log(LogEvent.of(isLoggable(level), name, - sourceClass, sourceMethod, - level, null, msgSupplier, null, (Object[])null)); - } + @Override + public void log(PlatformLogger.Level level, Throwable thrown, + Supplier msgSupplier) { + log(LogEvent.of(isLoggable(level), name, null, null, + level, null, msgSupplier, thrown, (Object[]) null)); + } - @Override - public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, - String sourceMethod, String msg, Object... params) { - log(LogEvent.of(isLoggable(level), name, - sourceClass, sourceMethod, - level, null, msg, null, params)); - } + @Override + public void logp(PlatformLogger.Level level, String sourceClass, + String sourceMethod, String msg) { + log(LogEvent.of(isLoggable(level), name, + sourceClass, sourceMethod, + level, null, msg, null, (Object[]) null)); + } - @Override - public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, - String sourceMethod, String msg, Throwable thrown) { - log(LogEvent.of(isLoggable(level), name, - sourceClass, sourceMethod, - level, null, msg, thrown, (Object[])null)); - } + @Override + public void logp(PlatformLogger.Level level, String sourceClass, + String sourceMethod, Supplier msgSupplier) { + log(LogEvent.of(isLoggable(level), name, + sourceClass, sourceMethod, + level, null, msgSupplier, null, (Object[]) null)); + } - @Override - public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, - String sourceMethod, Throwable thrown, - Supplier msgSupplier) { - log(LogEvent.of(isLoggable(level), name, - sourceClass, sourceMethod, - level, null, msgSupplier, thrown, (Object[])null)); - } + @Override + public void logp(PlatformLogger.Level level, String sourceClass, + String sourceMethod, String msg, Object... params) { + log(LogEvent.of(isLoggable(level), name, + sourceClass, sourceMethod, + level, null, msg, null, params)); + } - @Override - public void logrb(sun.util.logging.PlatformLogger.Level level, String sourceClass, - String sourceMethod, ResourceBundle bundle, String msg, - Object... params) { - log(LogEvent.of(isLoggable(level), name, - sourceClass, sourceMethod, - level, bundle, msg, null, params)); - } + @Override + public void logp(PlatformLogger.Level level, String sourceClass, + String sourceMethod, String msg, Throwable thrown) { + log(LogEvent.of(isLoggable(level), name, + sourceClass, sourceMethod, + level, null, msg, thrown, (Object[]) null)); + } - @Override - public void logrb(sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle, - String msg, Object... params) { - log(LogEvent.of(isLoggable(level), name, null, null, - level, bundle, msg, null, params)); - } + @Override + public void logp(PlatformLogger.Level level, String sourceClass, + String sourceMethod, Throwable thrown, + Supplier msgSupplier) { + log(LogEvent.of(isLoggable(level), name, + sourceClass, sourceMethod, + level, null, msgSupplier, thrown, (Object[]) null)); + } - @Override - public void logrb(sun.util.logging.PlatformLogger.Level level, String sourceClass, - String sourceMethod, ResourceBundle bundle, String msg, - Throwable thrown) { - log(LogEvent.of(isLoggable(level), name, - sourceClass, sourceMethod, - level, bundle, msg, thrown, (Object[])null)); - } + @Override + public void logrb(PlatformLogger.Level level, String sourceClass, + String sourceMethod, ResourceBundle bundle, String msg, + Object... params) { + log(LogEvent.of(isLoggable(level), name, + sourceClass, sourceMethod, + level, bundle, msg, null, params)); + } - @Override - public void logrb(sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle, - String msg, Throwable thrown) { - log(LogEvent.of(isLoggable(level), name, null, null, - level, bundle, msg, thrown, (Object[])null)); - } + @Override + public void logrb(PlatformLogger.Level level, ResourceBundle bundle, + String msg, Object... params) { + log(LogEvent.of(isLoggable(level), name, null, null, + level, bundle, msg, null, params)); + } - @Override - public boolean isLoggable(sun.util.logging.PlatformLogger.Level level) { - return this.level != OFF && level.intValue() - >= this.level.intValue(); - } + @Override + public void logrb(PlatformLogger.Level level, String sourceClass, + String sourceMethod, ResourceBundle bundle, String msg, + Throwable thrown) { + log(LogEvent.of(isLoggable(level), name, + sourceClass, sourceMethod, + level, bundle, msg, thrown, (Object[]) null)); + } - @Override - public boolean isEnabled() { - return this.level != OFF; - } + @Override + public void logrb(PlatformLogger.Level level, ResourceBundle bundle, + String msg, Throwable thrown) { + log(LogEvent.of(isLoggable(level), name, null, null, + level, bundle, msg, thrown, (Object[]) null)); + } + @Override + public boolean isLoggable(PlatformLogger.Level level) { + return this.level != OFF && level.intValue() + >= this.level.intValue(); } @Override - public Logger getLogger(String name, Module caller) { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(LOGGERFINDER_PERMISSION); - } - PrivilegedAction pa = () -> caller.getClassLoader(); - ClassLoader callerLoader = AccessController.doPrivileged(pa); - if (callerLoader == null) { - return system.computeIfAbsent(name, (n) -> new LoggerImpl(n)); - } else { - return user.computeIfAbsent(name, (n) -> new LoggerImpl(n)); - } + public boolean isEnabled() { + return this.level != OFF; } + } static ClassLoader getClassLoader(Module m) { @@ -675,14 +656,14 @@ } - final LogProducerFinder.LoggerImpl appSink; - final LogProducerFinder.LoggerImpl sysSink; + final LoggerImpl appSink; + final LoggerImpl sysSink; boolean old = allowControl.get().get(); allowControl.get().set(true); try { - appSink = LogProducerFinder.LoggerImpl.class.cast( + appSink = LoggerImpl.class.cast( provider.getLogger("foo", LoggerBridgeTest.class.getModule())); - sysSink = LogProducerFinder.LoggerImpl.class.cast( + sysSink = LoggerImpl.class.cast( provider.getLogger("foo", Thread.class.getModule())); } finally { allowControl.get().set(old); @@ -739,20 +720,20 @@ } } - static void setLevel( LogProducerFinder.LoggerImpl sink, + static void setLevel(LoggerImpl sink, sun.util.logging.PlatformLogger.Level loggerLevel) { - sink.level = loggerLevel; + sink.configureLevel(loggerLevel); } - // Calls the methods defined on LogProducer and verify the - // parameters received by the underlying LogProducerFinder.LoggerImpl + // Calls the methods defined on PlatformLogger.Bridge and verify the + // parameters received by the underlying LoggerImpl // logger. private static void testLogger(LoggerFinder provider, Map loggerDescMap, String name, ResourceBundle loggerBundle, PlatformLogger.Bridge logger, - LogProducerFinder.LoggerImpl sink) { + LoggerImpl sink) { System.out.println("Testing " + loggerDescMap.get(logger) + "[" + logger + "]"); final sun.util.logging.PlatformLogger.Level OFF = sun.util.logging.PlatformLogger.Level.OFF; --- old/test/jdk/java/lang/System/LoggerFinder/internal/LoggerBridgeTest/META-INF/services/java.lang.System$LoggerFinder 2018-12-18 14:27:52.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/LoggerBridgeTest/META-INF/services/java.lang.System$LoggerFinder 2018-12-18 14:27:51.000000000 +0100 @@ -1 +1 @@ -LoggerBridgeTest$LogProducerFinder +LogProducerFinder --- old/test/jdk/java/lang/System/LoggerFinder/internal/LoggerFinderLoaderTest/CustomSystemClassLoader.java 2018-12-18 14:27:53.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/LoggerFinderLoaderTest/CustomSystemClassLoader.java 2018-12-18 14:27:53.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** @@ -48,9 +49,8 @@ final List finderClassNames = - Arrays.asList("LoggerFinderLoaderTest$BaseLoggerFinder", - "LoggerFinderLoaderTest$BaseLoggerFinder2"); - final Map> finderClasses = new HashMap<>(); + Arrays.asList("BaseLoggerFinder", "BaseLoggerFinder2"); + final Map> finderClasses = new ConcurrentHashMap<>(); Class testLoggerFinderClass; public CustomSystemClassLoader() { @@ -62,9 +62,13 @@ private Class defineFinderClass(String name) throws ClassNotFoundException { + Class finderClass = finderClasses.get(name); + if (finderClass != null) return finderClass; + final Object obj = getClassLoadingLock(name); synchronized(obj) { - if (finderClasses.get(name) != null) return finderClasses.get(name); + finderClass = finderClasses.get(name); + if (finderClass != null) return finderClass; if (testLoggerFinderClass == null) { // Hack: we load testLoggerFinderClass to get its code source. // we can't use this.getClass() since we are in the boot. @@ -77,7 +81,7 @@ byte[] b = Files.readAllBytes(file.toPath()); Permissions perms = new Permissions(); perms.add(new AllPermission()); - Class finderClass = defineClass( + finderClass = defineClass( name, b, 0, b.length, new ProtectionDomain( this.getClass().getProtectionDomain().getCodeSource(), perms)); @@ -95,9 +99,13 @@ } } + private static boolean matches(String prefix, String name) { + return prefix.equals(name) || name.startsWith(prefix + "$"); + } + @Override public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - if (finderClassNames.contains(name)) { + if (finderClassNames.stream().anyMatch(n -> matches(n, name))) { Class c = defineFinderClass(name); if (resolve) { resolveClass(c); @@ -109,7 +117,7 @@ @Override protected Class findClass(String name) throws ClassNotFoundException { - if (finderClassNames.contains(name)) { + if (finderClassNames.stream().anyMatch(n -> matches(n, name))) { return defineFinderClass(name); } return super.findClass(name); --- old/test/jdk/java/lang/System/LoggerFinder/internal/LoggerFinderLoaderTest/LoggerFinderLoaderTest.java 2018-12-18 14:27:55.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/LoggerFinderLoaderTest/LoggerFinderLoaderTest.java 2018-12-18 14:27:55.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,7 @@ * DefaultLoggerFinder and SimpleConsoleLogger implementation. * @modules java.base/sun.util.logging * java.base/jdk.internal.logger - * @build AccessSystemLogger LoggerFinderLoaderTest CustomSystemClassLoader + * @build AccessSystemLogger LoggerFinderLoaderTest CustomSystemClassLoader BaseLoggerFinder BaseLoggerFinder2 * @run driver AccessSystemLogger * @run main/othervm -Xbootclasspath/a:boot -Djava.system.class.loader=CustomSystemClassLoader LoggerFinderLoaderTest NOSECURITY * @run main/othervm -Xbootclasspath/a:boot -Djava.system.class.loader=CustomSystemClassLoader LoggerFinderLoaderTest NOPERMISSIONS @@ -118,8 +118,8 @@ static { try { providerClass = new Class[] { - ClassLoader.getSystemClassLoader().loadClass("LoggerFinderLoaderTest$BaseLoggerFinder"), - ClassLoader.getSystemClassLoader().loadClass("LoggerFinderLoaderTest$BaseLoggerFinder2") + ClassLoader.getSystemClassLoader().loadClass("BaseLoggerFinder"), + ClassLoader.getSystemClassLoader().loadClass("BaseLoggerFinder2") }; } catch (ClassNotFoundException ex) { throw new ExceptionInInitializerError(ex); @@ -171,51 +171,6 @@ public Logger getLocalizedLogger(String name, ResourceBundle bundle, Module caller); } - public static class BaseLoggerFinder extends LoggerFinder implements TestLoggerFinder { - - static final RuntimePermission LOGGERFINDER_PERMISSION = - new RuntimePermission("loggerFinder"); - public BaseLoggerFinder() { - if (fails.get()) { - throw new RuntimeException("Simulate exception while loading provider"); - } - } - - System.Logger createSimpleLogger(String name) { - PrivilegedAction pa = () -> SimpleConsoleLogger.makeSimpleLogger(name); - return AccessController.doPrivileged(pa); - } - - - @Override - public Logger getLogger(String name, Module caller) { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(LOGGERFINDER_PERMISSION); - } - PrivilegedAction pa = () -> caller.getClassLoader(); - ClassLoader callerLoader = AccessController.doPrivileged(pa); - if (callerLoader == null) { - return system.computeIfAbsent(name, (n) -> new LoggerImpl(n, createSimpleLogger(name))); - } else { - return user.computeIfAbsent(name, (n) -> new LoggerImpl(n, createSimpleLogger(name))); - } - } - } - - public static class BaseLoggerFinder2 extends LoggerFinder implements TestLoggerFinder { - - static final RuntimePermission LOGGERFINDER_PERMISSION = - new RuntimePermission("loggerFinder"); - public BaseLoggerFinder2() { - throw new ServiceConfigurationError("Should not come here"); - } - @Override - public Logger getLogger(String name, Module caller) { - throw new ServiceConfigurationError("Should not come here"); - } - } - public static class MyBundle extends ResourceBundle { final ConcurrentHashMap map = new ConcurrentHashMap<>(); @@ -270,7 +225,7 @@ throw new RuntimeException("Expected message not found. Error stream contained: " + warning); } if (TestLoggerFinder.fails.get()) { - if (!warning.contains("java.util.ServiceConfigurationError: java.lang.System$LoggerFinder: Provider LoggerFinderLoaderTest$BaseLoggerFinder could not be instantiated")) { + if (!warning.contains("java.util.ServiceConfigurationError: java.lang.System$LoggerFinder: Provider BaseLoggerFinder could not be instantiated")) { throw new RuntimeException("Expected message not found. Error stream contained: " + warning); } } else if (singleton) { @@ -425,7 +380,7 @@ ServiceLoader.load(LoggerFinder.class, ClassLoader.getSystemClassLoader()); Iterator iterator = serviceLoader.iterator(); Object firstProvider = iterator.next(); - if (!firstProvider.getClass().getName().equals("LoggerFinderLoaderTest$BaseLoggerFinder")) { + if (!firstProvider.getClass().getName().equals("BaseLoggerFinder")) { throw new RuntimeException("Unexpected provider: " + firstProvider.getClass().getName()); } if (!iterator.hasNext()) { --- old/test/jdk/java/lang/System/LoggerFinder/internal/LoggerFinderLoaderTest/META-INF/services/java.lang.System$LoggerFinder 2018-12-18 14:27:56.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/LoggerFinderLoaderTest/META-INF/services/java.lang.System$LoggerFinder 2018-12-18 14:27:56.000000000 +0100 @@ -1,3 +1,3 @@ -LoggerFinderLoaderTest$BaseLoggerFinder -LoggerFinderLoaderTest$BaseLoggerFinder2 +BaseLoggerFinder +BaseLoggerFinder2 --- old/test/jdk/java/lang/System/LoggerFinder/internal/PlatformLoggerBridgeTest/CustomSystemClassLoader.java 2018-12-18 14:27:58.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/PlatformLoggerBridgeTest/CustomSystemClassLoader.java 2018-12-18 14:27:58.000000000 +0100 @@ -28,6 +28,8 @@ import java.security.AllPermission; import java.security.Permissions; import java.security.ProtectionDomain; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** @@ -39,7 +41,7 @@ public class CustomSystemClassLoader extends ClassLoader { - Class loggerFinderClass = null; + final ConcurrentHashMap> classes = new ConcurrentHashMap<>(); public CustomSystemClassLoader() { super(); @@ -50,8 +52,11 @@ private Class defineFinderClass(String name) throws ClassNotFoundException { + Class loggerFinderClass = classes.get(name); + if (loggerFinderClass != null) return loggerFinderClass; final Object obj = getClassLoadingLock(name); synchronized(obj) { + loggerFinderClass = classes.get(name); if (loggerFinderClass != null) return loggerFinderClass; URL url = this.getClass().getProtectionDomain().getCodeSource().getLocation(); @@ -66,6 +71,7 @@ this.getClass().getProtectionDomain().getCodeSource(), perms)); System.out.println("Loaded " + name); + classes.put(name, loggerFinderClass); return loggerFinderClass; } catch (Throwable ex) { ex.printStackTrace(); @@ -80,7 +86,7 @@ @Override public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - if (name.endsWith("$LogProducerFinder")) { + if (name.equals("LogProducerFinder") || name.startsWith("LogProducerFinder$")) { Class c = defineFinderClass(name); if (resolve) { resolveClass(c); @@ -92,7 +98,7 @@ @Override protected Class findClass(String name) throws ClassNotFoundException { - if (name.endsWith("$$LogProducerFinder")) { + if (name.equals("LogProducerFinder") || name.startsWith("LogProducerFinder$")) { return defineFinderClass(name); } return super.findClass(name); --- old/test/jdk/java/lang/System/LoggerFinder/internal/PlatformLoggerBridgeTest/META-INF/services/java.lang.System$LoggerFinder 2018-12-18 14:28:00.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/PlatformLoggerBridgeTest/META-INF/services/java.lang.System$LoggerFinder 2018-12-18 14:27:59.000000000 +0100 @@ -1 +1 @@ -PlatformLoggerBridgeTest$LogProducerFinder +LogProducerFinder --- old/test/jdk/java/lang/System/LoggerFinder/internal/PlatformLoggerBridgeTest/PlatformLoggerBridgeTest.java 2018-12-18 14:28:01.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/PlatformLoggerBridgeTest/PlatformLoggerBridgeTest.java 2018-12-18 14:28:01.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,7 +58,7 @@ * backend whose loggers implement PlatformLogger.Bridge. * @modules java.base/sun.util.logging * java.logging - * @build CustomSystemClassLoader PlatformLoggerBridgeTest + * @build CustomSystemClassLoader LogProducerFinder PlatformLoggerBridgeTest * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader PlatformLoggerBridgeTest NOSECURITY * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader PlatformLoggerBridgeTest NOPERMISSIONS * @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader PlatformLoggerBridgeTest WITHPERMISSIONS @@ -89,19 +89,19 @@ } }; + public static final Queue eventQueue = new ArrayBlockingQueue<>(128); + static final Class providerClass; static { try { // Preload classes before the security manager is on. - providerClass = ClassLoader.getSystemClassLoader().loadClass("PlatformLoggerBridgeTest$LogProducerFinder"); + providerClass = ClassLoader.getSystemClassLoader().loadClass("LogProducerFinder"); ((LoggerFinder)providerClass.newInstance()).getLogger("foo", providerClass.getModule()); } catch (Exception ex) { throw new ExceptionInInitializerError(ex); } } - public static final Queue eventQueue = new ArrayBlockingQueue<>(128); - public static final class LogEvent implements Cloneable { public LogEvent() { @@ -234,200 +234,182 @@ } - public static class LogProducerFinder extends LoggerFinder { - static final RuntimePermission LOGGERFINDER_PERMISSION = - new RuntimePermission("loggerFinder"); - final ConcurrentHashMap system = new ConcurrentHashMap<>(); - final ConcurrentHashMap user = new ConcurrentHashMap<>(); - - public class LoggerImpl implements Logger, PlatformLogger.Bridge { - private final String name; - private sun.util.logging.PlatformLogger.Level level = sun.util.logging.PlatformLogger.Level.INFO; - private sun.util.logging.PlatformLogger.Level OFF = sun.util.logging.PlatformLogger.Level.OFF; - private sun.util.logging.PlatformLogger.Level FINE = sun.util.logging.PlatformLogger.Level.FINE; - private sun.util.logging.PlatformLogger.Level FINER = sun.util.logging.PlatformLogger.Level.FINER; - private sun.util.logging.PlatformLogger.Level FINEST = sun.util.logging.PlatformLogger.Level.FINEST; - private sun.util.logging.PlatformLogger.Level CONFIG = sun.util.logging.PlatformLogger.Level.CONFIG; - private sun.util.logging.PlatformLogger.Level INFO = sun.util.logging.PlatformLogger.Level.INFO; - private sun.util.logging.PlatformLogger.Level WARNING = sun.util.logging.PlatformLogger.Level.WARNING; - private sun.util.logging.PlatformLogger.Level SEVERE = sun.util.logging.PlatformLogger.Level.SEVERE; - - public LoggerImpl(String name) { - this.name = name; - } - - @Override - public String getName() { - return name; - } + public static class LoggerImpl implements System.Logger, PlatformLogger.Bridge { + private final String name; + private sun.util.logging.PlatformLogger.Level level = sun.util.logging.PlatformLogger.Level.INFO; + private sun.util.logging.PlatformLogger.Level OFF = sun.util.logging.PlatformLogger.Level.OFF; + private sun.util.logging.PlatformLogger.Level FINE = sun.util.logging.PlatformLogger.Level.FINE; + private sun.util.logging.PlatformLogger.Level FINER = sun.util.logging.PlatformLogger.Level.FINER; + private sun.util.logging.PlatformLogger.Level FINEST = sun.util.logging.PlatformLogger.Level.FINEST; + private sun.util.logging.PlatformLogger.Level CONFIG = sun.util.logging.PlatformLogger.Level.CONFIG; + private sun.util.logging.PlatformLogger.Level INFO = sun.util.logging.PlatformLogger.Level.INFO; + private sun.util.logging.PlatformLogger.Level WARNING = sun.util.logging.PlatformLogger.Level.WARNING; + private sun.util.logging.PlatformLogger.Level SEVERE = sun.util.logging.PlatformLogger.Level.SEVERE; - @Override - public boolean isLoggable(Level level) { - return this.level != OFF && this.level.intValue() <= level.getSeverity(); - } + public LoggerImpl(String name) { + this.name = name; + } - @Override - public void log(Level level, ResourceBundle bundle, - String key, Throwable thrown) { - throw new UnsupportedOperationException(); - } + public void configureLevel(sun.util.logging.PlatformLogger.Level level) { + this.level = level; + } - @Override - public void log(Level level, ResourceBundle bundle, - String format, Object... params) { - throw new UnsupportedOperationException(); - } + @Override + public String getName() { + return name; + } - void log(LogEvent event) { - eventQueue.add(event); - } + @Override + public boolean isLoggable(Level level) { + return this.level != OFF && this.level.intValue() <= level.getSeverity(); + } - @Override - public void log(Level level, Supplier msgSupplier) { - throw new UnsupportedOperationException(); - } + @Override + public void log(Level level, ResourceBundle bundle, + String key, Throwable thrown) { + throw new UnsupportedOperationException(); + } - @Override - public void log(Level level, Supplier msgSupplier, - Throwable thrown) { - throw new UnsupportedOperationException(); - } + @Override + public void log(Level level, ResourceBundle bundle, + String format, Object... params) { + throw new UnsupportedOperationException(); + } - @Override - public void log(sun.util.logging.PlatformLogger.Level level, String msg) { - log(LogEvent.of(isLoggable(level), name, null, null, - level, null, msg, null, (Object[])null)); - } + void log(PlatformLoggerBridgeTest.LogEvent event) { + eventQueue.add(event); + } - @Override - public void log(sun.util.logging.PlatformLogger.Level level, - Supplier msgSupplier) { - log(LogEvent.of(isLoggable(level), name, null, null, - level, null, msgSupplier, null, (Object[])null)); - } + @Override + public void log(Level level, Supplier msgSupplier) { + throw new UnsupportedOperationException(); + } - @Override - public void log(sun.util.logging.PlatformLogger.Level level, String msg, - Object... params) { - log(LogEvent.of(isLoggable(level), name, null, null, - level, null, msg, null, params)); - } + @Override + public void log(Level level, Supplier msgSupplier, + Throwable thrown) { + throw new UnsupportedOperationException(); + } - @Override - public void log(sun.util.logging.PlatformLogger.Level level, String msg, - Throwable thrown) { - log(LogEvent.of(isLoggable(level), name, null, null, - level, null, msg, thrown, (Object[])null)); - } + @Override + public void log(sun.util.logging.PlatformLogger.Level level, String msg) { + log(LogEvent.of(isLoggable(level), name, null, null, + level, null, msg, null, (Object[]) null)); + } - @Override - public void log(sun.util.logging.PlatformLogger.Level level, Throwable thrown, - Supplier msgSupplier) { - log(LogEvent.of(isLoggable(level), name, null, null, - level, null, msgSupplier, thrown, (Object[])null)); - } + @Override + public void log(sun.util.logging.PlatformLogger.Level level, + Supplier msgSupplier) { + log(LogEvent.of(isLoggable(level), name, null, null, + level, null, msgSupplier, null, (Object[]) null)); + } - @Override - public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, - String sourceMethod, String msg) { - log(LogEvent.of(isLoggable(level), name, - sourceClass, sourceMethod, - level, null, msg, null, (Object[])null)); - } + @Override + public void log(sun.util.logging.PlatformLogger.Level level, String msg, + Object... params) { + log(LogEvent.of(isLoggable(level), name, null, null, + level, null, msg, null, params)); + } - @Override - public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, - String sourceMethod, Supplier msgSupplier) { - log(LogEvent.of(isLoggable(level), name, - sourceClass, sourceMethod, - level, null, msgSupplier, null, (Object[])null)); - } + @Override + public void log(sun.util.logging.PlatformLogger.Level level, String msg, + Throwable thrown) { + log(LogEvent.of(isLoggable(level), name, null, null, + level, null, msg, thrown, (Object[]) null)); + } - @Override - public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, - String sourceMethod, String msg, Object... params) { - log(LogEvent.of(isLoggable(level), name, - sourceClass, sourceMethod, - level, null, msg, null, params)); - } + @Override + public void log(sun.util.logging.PlatformLogger.Level level, Throwable thrown, + Supplier msgSupplier) { + log(LogEvent.of(isLoggable(level), name, null, null, + level, null, msgSupplier, thrown, (Object[]) null)); + } - @Override - public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, - String sourceMethod, String msg, Throwable thrown) { - log(LogEvent.of(isLoggable(level), name, - sourceClass, sourceMethod, - level, null, msg, thrown, (Object[])null)); - } + @Override + public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, + String sourceMethod, String msg) { + log(LogEvent.of(isLoggable(level), name, + sourceClass, sourceMethod, + level, null, msg, null, (Object[]) null)); + } - @Override - public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, - String sourceMethod, Throwable thrown, - Supplier msgSupplier) { - log(LogEvent.of(isLoggable(level), name, - sourceClass, sourceMethod, - level, null, msgSupplier, thrown, (Object[])null)); - } + @Override + public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, + String sourceMethod, Supplier msgSupplier) { + log(LogEvent.of(isLoggable(level), name, + sourceClass, sourceMethod, + level, null, msgSupplier, null, (Object[]) null)); + } - @Override - public void logrb(sun.util.logging.PlatformLogger.Level level, String sourceClass, - String sourceMethod, ResourceBundle bundle, String msg, - Object... params) { - log(LogEvent.of(isLoggable(level), name, - sourceClass, sourceMethod, - level, bundle, msg, null, params)); - } + @Override + public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, + String sourceMethod, String msg, Object... params) { + log(LogEvent.of(isLoggable(level), name, + sourceClass, sourceMethod, + level, null, msg, null, params)); + } - @Override - public void logrb(sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle, - String msg, Object... params) { - log(LogEvent.of(isLoggable(level), name, null, null, - level, bundle, msg, null, params)); - } + @Override + public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, + String sourceMethod, String msg, Throwable thrown) { + log(LogEvent.of(isLoggable(level), name, + sourceClass, sourceMethod, + level, null, msg, thrown, (Object[]) null)); + } - @Override - public void logrb(sun.util.logging.PlatformLogger.Level level, String sourceClass, - String sourceMethod, ResourceBundle bundle, String msg, - Throwable thrown) { - log(LogEvent.of(isLoggable(level), name, - sourceClass, sourceMethod, - level, bundle, msg, thrown, (Object[])null)); - } + @Override + public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, + String sourceMethod, Throwable thrown, + Supplier msgSupplier) { + log(LogEvent.of(isLoggable(level), name, + sourceClass, sourceMethod, + level, null, msgSupplier, thrown, (Object[]) null)); + } - @Override - public void logrb(sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle, - String msg, Throwable thrown) { - log(LogEvent.of(isLoggable(level), name, null, null, - level, bundle, msg, thrown, (Object[])null)); - } + @Override + public void logrb(sun.util.logging.PlatformLogger.Level level, String sourceClass, + String sourceMethod, ResourceBundle bundle, String msg, + Object... params) { + log(LogEvent.of(isLoggable(level), name, + sourceClass, sourceMethod, + level, bundle, msg, null, params)); + } - @Override - public boolean isLoggable(sun.util.logging.PlatformLogger.Level level) { - return this.level != OFF && level.intValue() - >= this.level.intValue(); - } + @Override + public void logrb(sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle, + String msg, Object... params) { + log(LogEvent.of(isLoggable(level), name, null, null, + level, bundle, msg, null, params)); + } - @Override - public boolean isEnabled() { - return this.level != OFF; - } + @Override + public void logrb(sun.util.logging.PlatformLogger.Level level, String sourceClass, + String sourceMethod, ResourceBundle bundle, String msg, + Throwable thrown) { + log(LogEvent.of(isLoggable(level), name, + sourceClass, sourceMethod, + level, bundle, msg, thrown, (Object[]) null)); + } + @Override + public void logrb(sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle, + String msg, Throwable thrown) { + log(LogEvent.of(isLoggable(level), name, null, null, + level, bundle, msg, thrown, (Object[]) null)); + } + @Override + public boolean isLoggable(sun.util.logging.PlatformLogger.Level level) { + return this.level != OFF && level.intValue() + >= this.level.intValue(); } @Override - public Logger getLogger(String name, Module caller) { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(LOGGERFINDER_PERMISSION); - } - PrivilegedAction pa = () -> caller.getClassLoader(); - ClassLoader callerLoader = AccessController.doPrivileged(pa); - if (callerLoader == null) { - return system.computeIfAbsent(name, (n) -> new LoggerImpl(n)); - } else { - return user.computeIfAbsent(name, (n) -> new LoggerImpl(n)); - } + public boolean isEnabled() { + return this.level != OFF; } + + } static final sun.util.logging.PlatformLogger.Level[] julLevels = { @@ -593,11 +575,11 @@ System.out.println("Got expected exception for system logger: " + acx); } - final LogProducerFinder.LoggerImpl sysSink; + final LoggerImpl sysSink; boolean old = allowControl.get().get(); allowControl.get().set(true); try { - sysSink = LogProducerFinder.LoggerImpl.class.cast( + sysSink = LoggerImpl.class.cast( provider.getLogger("foo", Thread.class.getModule())); } finally { allowControl.get().set(old); @@ -647,20 +629,20 @@ } } - static void setLevel( LogProducerFinder.LoggerImpl sink, + static void setLevel(LoggerImpl sink, sun.util.logging.PlatformLogger.Level loggerLevel) { - sink.level = loggerLevel; + sink.configureLevel(loggerLevel); } // Calls the methods defined on LogProducer and verify the - // parameters received by the underlying LogProducerFinder.LoggerImpl + // parameters received by the underlying LoggerImpl // logger. private static void testLogger(LoggerFinder provider, Map loggerDescMap, String name, ResourceBundle loggerBundle, PlatformLogger logger, - LogProducerFinder.LoggerImpl sink) { + LoggerImpl sink) { System.out.println("Testing " + loggerDescMap.get(logger) + " [" + logger +"]"); final sun.util.logging.PlatformLogger.Level OFF = sun.util.logging.PlatformLogger.Level.OFF; --- /dev/null 2018-12-18 14:28:03.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/BaseDefaultLoggerFinderTest/BaseLoggerFinder.java 2018-12-18 14:28:02.000000000 +0100 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jdk.internal.logger.DefaultLoggerFinder; +import jdk.internal.logger.SimpleConsoleLogger; +import sun.util.logging.PlatformLogger; + +import java.lang.System.Logger; +import java.lang.System.Logger.Level; +import java.security.AccessController; +import java.security.PrivilegedAction; + +public class BaseLoggerFinder extends DefaultLoggerFinder + implements BaseDefaultLoggerFinderTest.TestLoggerFinder { + + public BaseLoggerFinder() { + if (fails.get()) { + throw new RuntimeException("Simulate exception while loading provider"); + } + } + + @Override + public void setLevel(Logger logger, Level level, Module caller) { + PrivilegedAction pa = () -> { + setLevel(logger, PlatformLogger.toPlatformLevel(level), caller); + return null; + }; + AccessController.doPrivileged(pa); + } + + @Override + public void setLevel(Logger logger, PlatformLogger.Level level, Module caller) { + PrivilegedAction pa = () -> demandLoggerFor(logger.getName(), caller); + Logger impl = AccessController.doPrivileged(pa); + SimpleConsoleLogger.class.cast(impl) + .getLoggerConfiguration() + .setPlatformLevel(level); + } + + @Override + public PlatformLogger.Bridge asPlatformLoggerBridge(Logger logger) { + PrivilegedAction pa = () -> + PlatformLogger.Bridge.convert(logger); + return AccessController.doPrivileged(pa); + } + +} + --- /dev/null 2018-12-18 14:28:05.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/BaseLoggerBridgeTest/BaseLoggerFinder.java 2018-12-18 14:28:04.000000000 +0100 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.lang.System.LoggerFinder; +import java.lang.System.Logger; + +public class BaseLoggerFinder extends LoggerFinder + implements BaseLoggerBridgeTest.TestLoggerFinder { + static final RuntimePermission LOGGERFINDER_PERMISSION = + new RuntimePermission("loggerFinder"); + + @Override + public Logger getLogger(String name, Module caller) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(LOGGERFINDER_PERMISSION); + } + PrivilegedAction pa = () -> caller.getClassLoader(); + ClassLoader callerLoader = AccessController.doPrivileged(pa); + if (callerLoader == null) { + return system.computeIfAbsent(name, (n) -> new LoggerImpl(n)); + } else { + return user.computeIfAbsent(name, (n) -> new LoggerImpl(n)); + } + } +} --- /dev/null 2018-12-18 14:28:06.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/BasePlatformLoggerTest/BaseLoggerFinder.java 2018-12-18 14:28:06.000000000 +0100 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.System.Logger; +import java.lang.System.LoggerFinder; +import java.security.AccessController; +import java.security.PrivilegedAction; + +public class BaseLoggerFinder extends LoggerFinder + implements BasePlatformLoggerTest.TestLoggerFinder { + + public static final RuntimePermission LOGGERFINDER_PERMISSION = + new RuntimePermission("loggerFinder"); + + @Override + public Logger getLogger(String name, Module caller) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(LOGGERFINDER_PERMISSION); + } + PrivilegedAction pa = () -> caller.getClassLoader(); + ClassLoader callerLoader = AccessController.doPrivileged(pa); + if (callerLoader == null) { + return system.computeIfAbsent(name, (n) -> new LoggerImpl(n)); + } else { + return user.computeIfAbsent(name, (n) -> new LoggerImpl(n)); + } + } +} + --- /dev/null 2018-12-18 14:28:08.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/LoggerBridgeTest/LogProducerFinder.java 2018-12-18 14:28:07.000000000 +0100 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.System.Logger; +import java.lang.System.LoggerFinder; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.concurrent.ConcurrentHashMap; + +public class LogProducerFinder extends LoggerFinder { + + public static final RuntimePermission LOGGERFINDER_PERMISSION = + new RuntimePermission("loggerFinder"); + final ConcurrentHashMap system = new ConcurrentHashMap<>(); + final ConcurrentHashMap user = new ConcurrentHashMap<>(); + + @Override + public Logger getLogger(String name, Module caller) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(LOGGERFINDER_PERMISSION); + } + PrivilegedAction pa = () -> caller.getClassLoader(); + ClassLoader callerLoader = AccessController.doPrivileged(pa); + if (callerLoader == null) { + return system.computeIfAbsent(name, (n) -> new LoggerBridgeTest.LoggerImpl(n)); + } else { + return user.computeIfAbsent(name, (n) -> new LoggerBridgeTest.LoggerImpl(n)); + } + } +} + --- /dev/null 2018-12-18 14:28:09.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/LoggerFinderLoaderTest/BaseLoggerFinder.java 2018-12-18 14:28:09.000000000 +0100 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jdk.internal.logger.SimpleConsoleLogger; + +import java.lang.System.Logger; +import java.lang.System.LoggerFinder; +import java.security.AccessController; +import java.security.PrivilegedAction; + +public class BaseLoggerFinder extends LoggerFinder + implements LoggerFinderLoaderTest.TestLoggerFinder { + + static final RuntimePermission LOGGERFINDER_PERMISSION = + new RuntimePermission("loggerFinder"); + + public BaseLoggerFinder() { + if (fails.get()) { + throw new RuntimeException("Simulate exception while loading provider"); + } + } + + Logger createSimpleLogger(String name) { + PrivilegedAction pa = () -> SimpleConsoleLogger.makeSimpleLogger(name); + return AccessController.doPrivileged(pa); + } + + @Override + public Logger getLogger(String name, Module caller) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(LOGGERFINDER_PERMISSION); + } + PrivilegedAction pa = () -> caller.getClassLoader(); + ClassLoader callerLoader = AccessController.doPrivileged(pa); + if (callerLoader == null) { + return system.computeIfAbsent(name, (n) -> new LoggerImpl(n, createSimpleLogger(name))); + } else { + return user.computeIfAbsent(name, (n) -> new LoggerImpl(n, createSimpleLogger(name))); + } + } +} --- /dev/null 2018-12-18 14:28:11.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/LoggerFinderLoaderTest/BaseLoggerFinder2.java 2018-12-18 14:28:10.000000000 +0100 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.System.Logger; +import java.lang.System.LoggerFinder; +import java.util.ServiceConfigurationError; + +public class BaseLoggerFinder2 extends LoggerFinder + implements LoggerFinderLoaderTest.TestLoggerFinder { + + public BaseLoggerFinder2() { + throw new ServiceConfigurationError("Should not come here"); + } + + @Override + public Logger getLogger(String name, Module caller) { + throw new ServiceConfigurationError("Should not come here"); + } +} --- /dev/null 2018-12-18 14:28:12.000000000 +0100 +++ new/test/jdk/java/lang/System/LoggerFinder/internal/PlatformLoggerBridgeTest/LogProducerFinder.java 2018-12-18 14:28:12.000000000 +0100 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.Queue; +import java.util.ResourceBundle; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Supplier; +import java.lang.System.LoggerFinder; +import java.lang.System.Logger; + +public class LogProducerFinder extends LoggerFinder { + + static final RuntimePermission LOGGERFINDER_PERMISSION = + new RuntimePermission("loggerFinder"); + final ConcurrentHashMap + system = new ConcurrentHashMap<>(); + final ConcurrentHashMap + user = new ConcurrentHashMap<>(); + + private static PlatformLoggerBridgeTest.LoggerImpl newLoggerImpl(String name) { + return new PlatformLoggerBridgeTest.LoggerImpl(name); + } + + @Override + public Logger getLogger(String name, Module caller) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(LOGGERFINDER_PERMISSION); + } + PrivilegedAction pa = () -> caller.getClassLoader(); + ClassLoader callerLoader = AccessController.doPrivileged(pa); + if (callerLoader == null) { + return system.computeIfAbsent(name, (n) -> newLoggerImpl(n)); + } else { + return user.computeIfAbsent(name, (n) -> newLoggerImpl(n)); + } + } +}