001: package abbot.script;
002:
003: import javax.swing.SwingUtilities;
004:
005: import junit.extensions.abbot.TestHelper;
006: import junit.framework.*;
007: import abbot.util.NonDelegatingClassLoader;
008: import java.lang.ref.WeakReference;
009:
010: /**
011: * Verify AppClassLoader operation.
012: */
013:
014: // Additional tests:
015: // A class loaded by both system and app loader should differ
016: // load from different class path
017: // load resource from different class path
018: // load from manifest class path in jar in class path
019: public class AppClassLoaderTest extends TestCase {
020:
021: private AppClassLoader acl;
022:
023: /** Ensure the class loader is GC'd after uninstall. */
024: public void testGC() throws Exception {
025: acl = new AppClassLoader();
026: WeakReference ref = new WeakReference(acl);
027: class Flag {
028: volatile boolean flag;
029: }
030: final Flag flag = new Flag();
031:
032: acl.install();
033:
034: SwingUtilities.invokeAndWait(new Runnable() {
035: public void run() {
036: flag.flag = acl.isEventDispatchThread();
037: }
038: });
039:
040: assertTrue("Custom event queue not installed", flag.flag);
041:
042: acl.uninstall();
043: acl = null;
044:
045: System.gc();
046: acl = (AppClassLoader) ref.get();
047: assertTrue("Class loader reference should be GC'd", acl == null);
048: }
049:
050: /** Ensure the bootstrap classes are always loaded by the bootstrap
051: * loader, except in cases where we specifically want preloading.
052: */
053: public void testAppletViewerExclusion() throws Throwable {
054: // applet viewer should get the custom loader
055: AppClassLoader dcl = new AppClassLoader();
056:
057: Class appletClass = Class.forName("sun.applet.AppletViewer",
058: true, dcl);
059: assertTrue(
060: "AppletViewer class loading should *not* be delegated",
061: appletClass.getClassLoader() instanceof NonDelegatingClassLoader);
062:
063: Class orbClass = Class.forName("org.omg.CORBA.ORB", true, dcl);
064: assertTrue(
065: "org.omg class loading should always be delegated",
066: !(orbClass.getClassLoader() instanceof NonDelegatingClassLoader));
067:
068: Class sliderClass = Class.forName("javax.swing.JSlider", true,
069: dcl);
070: assertTrue(
071: "javax.swing class loading should always be delegated",
072: !(sliderClass.getClassLoader() instanceof NonDelegatingClassLoader));
073: }
074:
075: private ClassLoader eventClassLoader = null;
076:
077: public void testContextInstallUninstall() throws Throwable {
078: final AppClassLoader dcl = new AppClassLoader();
079: ClassLoader original = getClass().getClassLoader();
080: ClassLoader origContext = Thread.currentThread()
081: .getContextClassLoader();
082: try {
083: dcl.install();
084: eventClassLoader = null;
085: SwingUtilities.invokeAndWait(new Runnable() {
086: public void run() {
087: eventClassLoader = Thread.currentThread()
088: .getContextClassLoader();
089: }
090: });
091: assertEquals("Context not installed on event thread", dcl,
092: eventClassLoader);
093: dcl.uninstall();
094: eventClassLoader = null;
095: SwingUtilities.invokeAndWait(new Runnable() {
096: public void run() {
097: eventClassLoader = Thread.currentThread()
098: .getContextClassLoader();
099: }
100: });
101: assertTrue("Context not uninstalled from event thread",
102: eventClassLoader != dcl);
103: assertEquals("Original class loader not restored",
104: getClass().getClassLoader(), original);
105: assertEquals("Original context not restored", Thread
106: .currentThread().getContextClassLoader(),
107: origContext);
108: } finally {
109: // Make sure it's uninstalled in case something bad happened
110: dcl.uninstall();
111: }
112: }
113:
114: public void testLoadAppletViewer() throws Throwable {
115: String pathName = "lib/example.jar";
116: String className = "sun.applet.AppletViewer";
117: ClassLoader cl1 = new AppClassLoader(pathName);
118: ClassLoader cl2 = new AppClassLoader(pathName);
119: try {
120: Class cls1 = Class.forName(className, true, cl1);
121: Class cls2 = Class.forName(className, true, cl2);
122: assertTrue("Class loader should define the class package",
123: cls1.getPackage() != null);
124: assertEquals("Class loader defined the wrong package",
125: "sun.applet", cls1.getPackage().getName());
126:
127: Class cls3 = Class.forName(className);
128: assertTrue("Core classes should be different when "
129: + "loaded dynamically", !cls1.equals(cls2));
130: assertTrue(
131: "Class loader should never delegate AppletViewer class",
132: !cls3.equals(cls1) && !cls3.equals(cls2));
133: } catch (ClassNotFoundException cnf) {
134: fail("App class loader failed to load " + className
135: + " from path " + pathName);
136: }
137: }
138:
139: // this behavior results in too many complications; it's inevitably
140: // impossible for the framework ensure it loads from the right class
141: // loader at the right time, since the exact same classes are being loaded.
142: /*
143: public void testDirectBaseTesterLoading() throws Throwable {
144: AppClassLoader dcl =
145: new AppClassLoader("lib/abbot.jar");
146: Class testerClass =
147: Class.forName("abbot.tester.ComponentTester", true, dcl);
148: assertEquals("Custom class loader should be used to load a framework class when the framework is in the custom loader's class path",
149: dcl, testerClass.getClassLoader());
150: Class compClass = Class.forName("javax.swing.JSlider", true, dcl);
151: assertTrue("Component class should not be loaded by custom loader, "
152: + "not by " + dcl,
153: !dcl.equals(compClass.getClass().getClassLoader()));
154:
155: // A new reloading class loader should still get its own copy
156: AppClassLoader dcl2 =
157: new AppClassLoader("lib/abbot.jar");
158: Class testerClass2 =
159: Class.forName("abbot.tester.ComponentTester", true, dcl2);
160: assertEquals("Basic tester should be reloadable",
161: dcl2, testerClass2.getClassLoader());
162: compClass = Class.forName("javax.swing.JSlider", true, dcl);
163: assertTrue("Component class should not be loaded by custom loader, "
164: + "not by " + dcl2,
165: !dcl2.equals(compClass.getClass().getClassLoader()));
166:
167: // If the framework is *not* in the classpath, should always get the
168: // same class.
169: AppClassLoader dcl3 = new AppClassLoader("classes");
170: Class testerClass3 =
171: Class.forName("abbot.tester.ComponentTester", true, dcl3);
172: assertTrue("Basic tester should be loaded from framework path, not by "
173: + dcl3,
174: !dcl3.equals(testerClass3.getClassLoader()));
175: }
176: */
177:
178: /** Load a custom tester and a tester and ensure the class hierarchy is
179: * appropriate.
180: */
181: public void testExtensionTesterLoading() throws Throwable {
182: AppClassLoader dcl = new AppClassLoader("lib/example.jar");
183: Class customTesterClass = Class.forName(
184: "abbot.tester.extensions.ArrowButtonTester", true, dcl);
185: ClassLoader ccl = customTesterClass.getClassLoader();
186: ClassLoader fcl = getClass().getClassLoader();
187: assertTrue(
188: "Class loader for extension tester should allow reloading: "
189: + ccl, ccl instanceof NonDelegatingClassLoader);
190:
191: assertTrue(
192: "Class loader for extension tester should differ from the "
193: + "framework class loader " + fcl, !ccl
194: .equals(fcl));
195:
196: assertEquals("Class loader for base tester class "
197: + "ancestor of the extension tester "
198: + "should match that of the test environment",
199: getClass().getClassLoader(), customTesterClass
200: .getSuperclass().getClassLoader());
201:
202: assertEquals("Actual base tester class ancestor "
203: + "of the extension should match that of "
204: + "the framework environment",
205: abbot.tester.ComponentTester.class, customTesterClass
206: .getSuperclass());
207: }
208:
209: /** Extensions not in the app loader class path but in the framework
210: * class path should still be loaded by the AppClassLoader, not the system
211: * class loader.
212: */
213: public void testExtensionsNotInTestCodeClassPath() throws Throwable {
214: AppClassLoader dcl = new AppClassLoader("lib/example.jar");
215: try {
216: Class customTesterClass = Class.forName(
217: "abbot.tester.extensions.DummyTester", true, dcl);
218: ClassLoader ccl = customTesterClass.getClassLoader();
219: ClassLoader fcl = getClass().getClassLoader();
220:
221: assertTrue("Wrong class loader for custom tester",
222: ccl instanceof NonDelegatingClassLoader);
223: assertTrue(
224: "Extension should not be found in the test code path",
225: !dcl.equals(ccl));
226:
227: // The parent class of the custom class should not come from the
228: // app class loader
229: assertEquals(
230: "Tester superclass should match the test environment",
231: fcl, customTesterClass.getSuperclass()
232: .getClassLoader());
233: } catch (ClassNotFoundException cnf) {
234: String msg = "The class loader should revert to java.class.path "
235: + "if the extension is not found in the app class loader "
236: + "classpath. The extension was not found.";
237: throw new AssertionFailedError(msg);
238: }
239: }
240:
241: public AppClassLoaderTest(String name) {
242: super (name);
243: }
244:
245: public static void main(String[] args) {
246: TestHelper.runTests(args, AppClassLoaderTest.class);
247: }
248: }
|