1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 import java.io.File; 27 import java.io.FileInputStream; 28 import java.io.IOException; 29 import java.io.InputStream; 30 import java.lang.reflect.InvocationTargetException; 31 import java.lang.reflect.Method; 32 33 /** 34 * @test 8163162 35 * @summary Checks that LazyLoggers are returned for System.Logger instances 36 * created by modules in the platform class loader. 37 * @compile systempkg/log/SystemLoggerAccessor.java SystemLoggerInPlatformLoader.java 38 * @run main/othervm SystemLoggerInPlatformLoader 39 * @author danielfuchs 40 */ 41 public class SystemLoggerInPlatformLoader { 42 43 static final class PlatformClassLoaderChild extends ClassLoader { 44 private PlatformClassLoaderChild() { 45 super(ClassLoader.getPlatformClassLoader()); 46 } 47 public Class<?> definePlatformClass(String name) throws IOException { 48 String testClasses = System.getProperty("test.classes", "./build/classes"); 49 String fname = name.replace('.', '/').concat(".class"); 50 try (InputStream is = new FileInputStream(new File(testClasses, fname))) { 51 byte[] b = is.readAllBytes(); 52 ClassLoader parent = getParent(); 53 try { 54 Method m = ClassLoader.class.getDeclaredMethod("defineClass", 55 String.class, byte[].class, int.class, int.class); 56 m.setAccessible(true); 57 return (Class<?>)m.invoke(parent, name, b, 0, b.length); 58 } catch (NoSuchMethodException 59 | IllegalAccessException 60 | InvocationTargetException ex) { 61 throw new IOException(ex); 62 } 63 } 64 } 65 static final PlatformClassLoaderChild INSTANCE = new PlatformClassLoaderChild(); 66 static Class<?> loadLoggerAccessor() throws IOException { 67 return INSTANCE.definePlatformClass("systempkg.log.SystemLoggerAccessor"); 68 } 69 } 70 71 static final Class<?> LOGGER_ACCESSOR_CLASS; 72 static { 73 try { 74 LOGGER_ACCESSOR_CLASS = PlatformClassLoaderChild.loadLoggerAccessor(); 75 ClassLoader platformCL = ClassLoader.getPlatformClassLoader(); 76 if (LOGGER_ACCESSOR_CLASS.getClassLoader() != platformCL) { 77 throw new ExceptionInInitializerError( 78 "Could not load accessor class in platform class loader: " 79 + LOGGER_ACCESSOR_CLASS.getClassLoader()); 80 } 81 } catch (IOException ex) { 82 throw new ExceptionInInitializerError(ex); 83 } 84 } 85 86 // Returns a system logger created on behalf of a class loaded by the 87 // Platform ClassLoader 88 static System.Logger getSystemLogger(String name) { 89 try { 90 return (System.Logger)LOGGER_ACCESSOR_CLASS.getMethod( 91 "getSystemLogger", String.class).invoke(null, name); 92 } catch (NoSuchMethodException 93 | IllegalAccessException 94 | InvocationTargetException ex) { 95 throw new RuntimeException("Failed to invoke LoggerAccessor.getJULLogger", ex); 96 } 97 } 98 99 public static void main(String[] args) { 100 System.Logger splogger = getSystemLogger("bar"); // for a platform class 101 System.Logger slogger = System.getLogger("bar"); // for an application class 102 if (slogger == splogger) { 103 throw new RuntimeException("Same loggers"); 104 } 105 Class sploggerType = splogger.getClass(); 106 System.out.println("splogger: " + sploggerType); 107 if (!sploggerType.getSimpleName().equals("JdkLazyLogger")) { 108 throw new RuntimeException(sploggerType.getSimpleName() 109 + ": unexpected class for splogger" 110 + " (expected a lazy logger for a platform class)"); 111 } 112 Class sloggerType = slogger.getClass(); 113 System.out.println("slogger: " + sloggerType); 114 if (sloggerType.equals(sploggerType)) { 115 throw new RuntimeException(sloggerType 116 + ": unexpected class for slogger" 117 + " (a lazy logger was not expected" 118 + " for a non platform class)"); 119 } 120 } 121 }