1/* 2 * Copyright (c) 2005, 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/* 25 * 26 * 27 * Unit test for Instrumentation appendToSystemClassLoaderSearch. This 28 * test does the following: 29 * 30 * 1. Creates a class loader to load class Foo. Execute Foo.doSomething 31 * which references a missing class Bar. The doSomething method 32 * should fail with NoClassDefFoundError. 33 * 34 * 2. Add Bar.jar to the system class path. Bar.jar contains Bar. 35 * 36 * 3. Create another class loader to load Foo. Execute Foo.doSomething. 37 * doSomething will load Bar. 38 * 39 * 4. Re-execute the first Foo's doSomething - it should fail a second 40 * time because the attempt to resolve Bar must fail with the same 41 * error as the first attempt. 42 * 43 * 5. De-reference both class loaders and execute System.gc(). We can't 44 * assert that the Foo classes will be unloaded but it serves to 45 * exercise the unload code path in HotSpot. 46 */ 47import java.lang.instrument.Instrumentation; 48import java.io.File; 49import java.net.URL; 50import java.net.URLClassLoader; 51import java.lang.reflect.Method; 52import java.lang.reflect.InvocationTargetException; 53import java.util.jar.JarFile; 54 55public class ClassUnloadTest { 56 57 static Instrumentation ins; 58 59 public static void main(String args[]) throws Exception { 60 String dir = args[0] + File.separator; 61 String jar = dir + args[1]; 62 63 System.out.println(jar); 64 65 URL u = (new File(dir)).toURL(); 66 URL urls[] = { u }; 67 68 // This should fail as Bar is not available 69 Invoker i1 = new Invoker(urls, "Foo", "doSomething"); 70 Boolean result = (Boolean)i1.invoke((Object)null); 71 if (result.booleanValue()) { 72 throw new RuntimeException("Test configuration error - doSomething should not succeed"); 73 } 74 75 // put Bar on the system class path 76 ins.appendToSystemClassLoaderSearch( new JarFile(jar) ); 77 78 // This should fail even though Bar is now available 79 result = (Boolean)i1.invoke((Object)null); 80 if (result.booleanValue()) { 81 throw new RuntimeException("Test configuration error - doSomething should not succeed"); 82 } 83 84 // This should succeed because this is a different Foo 85 Invoker i2 = new Invoker(urls, "Foo", "doSomething"); 86 result = (Boolean)i2.invoke((Object)null); 87 if (!result.booleanValue()) { 88 throw new RuntimeException("Test configuration error - doSomething did not succeed"); 89 } 90 91 // Exercise some class unloading 92 i1 = i2 = null; 93 System.gc(); 94 } 95 96 static class Invoker { 97 98 URLClassLoader cl; 99 Method m; 100 101 public Invoker(URL urls[], String cn, String mn, Class ... params) 102 throws ClassNotFoundException, NoSuchMethodException 103 { 104 cl = new URLClassLoader(urls); 105 Class c = Class.forName("Foo", true, cl); 106 m = c.getDeclaredMethod(mn, params); 107 } 108 109 public Object invoke(Object ... args) 110 throws IllegalAccessException, InvocationTargetException 111 { 112 return m.invoke(args); 113 } 114 } 115 116 public static void premain(String args, Instrumentation i) { 117 ins = i; 118 } 119} 120