1 /* 2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.lang.reflect.InvocationTargetException; 25 import java.lang.reflect.Method; 26 import java.net.MalformedURLException; 27 import java.net.URL; 28 import java.net.URLClassLoader; 29 import java.nio.file.Paths; 30 import java.util.logging.Logger; 31 32 /** 33 * This class is used to ensure that a resource bundle loadable by a classloader 34 * is on the caller's stack, but not on the classpath or TCCL. It tests that 35 * Logger.getLogger() can load the bundle via the immediate caller's classloader 36 * 37 * @author Jim Gish 38 */ 39 public class IndirectlyLoadABundle { 40 41 private static final String rbName = "CallerSearchableResource"; 42 loadAndTest()43 public boolean loadAndTest() throws Throwable { 44 // Make sure we can find it via the URLClassLoader 45 URLClassLoader yetAnotherResourceCL = new URLClassLoader(getURLs(), null); 46 if (!testForValidResourceSetup(yetAnotherResourceCL)) { 47 throw new Exception("Couldn't directly load bundle " + rbName 48 + " as expected. Test config problem"); 49 } 50 // But it shouldn't be available via the system classloader 51 ClassLoader myCL = this.getClass().getClassLoader(); 52 if (testForValidResourceSetup(myCL)) { 53 throw new Exception("Was able to directly load bundle " + rbName 54 + " from " + myCL + " but shouldn't have been" 55 + " able to. Test config problem"); 56 } 57 58 Class<?> loadItUpClazz = Class.forName("LoadItUp1", true, 59 yetAnotherResourceCL); 60 ClassLoader actual = loadItUpClazz.getClassLoader(); 61 if (actual != yetAnotherResourceCL) { 62 throw new Exception("LoadItUp1 was loaded by an unexpected CL: " + actual); 63 } 64 Object loadItUp = loadItUpClazz.newInstance(); 65 Method testMethod = loadItUpClazz.getMethod("getLogger", String.class, String.class); 66 try { 67 return (Logger)testMethod.invoke(loadItUp, "NestedLogger1", rbName) != null; 68 } catch (InvocationTargetException ex) { 69 throw ex.getTargetException(); 70 } 71 } 72 testGetAnonymousLogger()73 public boolean testGetAnonymousLogger() throws Throwable { 74 // Test getAnonymousLogger() 75 URLClassLoader loadItUpCL = new URLClassLoader(getURLs(), null); 76 Class<?> loadItUpClazz = Class.forName("LoadItUp1", true, loadItUpCL); 77 ClassLoader actual = loadItUpClazz.getClassLoader(); 78 if (actual != loadItUpCL) { 79 throw new Exception("LoadItUp1 was loaded by an unexpected CL: " 80 + actual); 81 } 82 Object loadItUpAnon = loadItUpClazz.newInstance(); 83 Method testAnonMethod = loadItUpClazz.getMethod("getAnonymousLogger", 84 String.class); 85 try { 86 return (Logger)testAnonMethod.invoke(loadItUpAnon, rbName) != null; 87 } catch (InvocationTargetException ex) { 88 throw ex.getTargetException(); 89 } 90 } 91 92 testGetLoggerGetLoggerWithBundle()93 public boolean testGetLoggerGetLoggerWithBundle() throws Throwable { 94 // test getLogger("NestedLogger2"); followed by 95 // getLogger("NestedLogger2", rbName) to see if the bundle is found 96 // 97 URL[] urls = getURLs(); 98 if (getLoggerWithNewCL(urls, "NestedLogger2", null)) { 99 return getLoggerWithNewCL(urls, "NestedLogger2", rbName); 100 101 } else { 102 throw new Exception("TEST FAILED: first call to getLogger() failed " 103 + " in IndirectlyLoadABundle." 104 + "testGetLoggerGetLoggerWithBundle"); 105 } 106 } 107 getURLs()108 private URL[] getURLs() throws MalformedURLException { 109 // Find out where we are running from so we can setup the URLClassLoader URLs 110 // test.src and test.classes will be set if running in jtreg, but probably 111 // not otherwise 112 String testDir = System.getProperty("test.src", System.getProperty("user.dir")); 113 String testClassesDir = System.getProperty("test.classes", 114 System.getProperty("user.dir")); 115 URL[] urls = new URL[2]; 116 // Allow for both jtreg and standalone cases here 117 urls[0] = Paths.get(testDir, "resources").toUri().toURL(); 118 urls[1] = Paths.get(testClassesDir).toUri().toURL(); 119 120 return urls; 121 } 122 getLoggerWithNewCL(URL[] urls, String loggerName, String bundleName)123 private boolean getLoggerWithNewCL(URL[] urls, String loggerName, 124 String bundleName) throws Throwable { 125 Logger result = null;; 126 // Test getLogger("foo"); getLogger("foo", "rbName"); 127 // First do the getLogger() call with no bundle name 128 URLClassLoader getLoggerCL = new URLClassLoader(urls, null); 129 Class<?> loadItUpClazz1 = Class.forName("LoadItUp1", true, getLoggerCL); 130 ClassLoader actual = loadItUpClazz1.getClassLoader(); 131 if (actual != getLoggerCL) { 132 throw new Exception("LoadItUp1 was loaded by an unexpected CL: " 133 + actual); 134 } 135 Object loadItUp1 = loadItUpClazz1.newInstance(); 136 if (bundleName != null) { 137 Method getLoggerMethod = loadItUpClazz1.getMethod("getLogger", 138 String.class, 139 String.class); 140 try { 141 result = (Logger) getLoggerMethod.invoke(loadItUp1, loggerName, 142 bundleName); 143 } catch (InvocationTargetException ex) { 144 throw ex.getTargetException(); 145 } 146 } else { 147 Method getLoggerMethod = loadItUpClazz1.getMethod("getLogger", 148 String.class); 149 try { 150 result = (Logger) getLoggerMethod.invoke(loadItUp1, loggerName); 151 } catch (InvocationTargetException ex) { 152 throw ex.getTargetException(); 153 } 154 } 155 return result != null; 156 } 157 testForValidResourceSetup(ClassLoader cl)158 private boolean testForValidResourceSetup(ClassLoader cl) { 159 // First make sure the test environment is setup properly and the bundle 160 // actually exists 161 return ResourceBundleSearchTest.isOnClassPath(rbName, cl); 162 } 163 } 164