KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > test > classloader > circularity > test > CircularLoadTests


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.test.classloader.circularity.test;
23
24 import java.lang.reflect.Method JavaDoc;
25 import java.lang.reflect.Constructor JavaDoc;
26 import java.lang.reflect.UndeclaredThrowableException JavaDoc;
27 import java.net.URL JavaDoc;
28
29 import org.jboss.logging.Logger;
30 import org.jboss.mx.loading.UnifiedClassLoader;
31 import org.jboss.mx.loading.UnifiedClassLoader3;
32 import org.jboss.mx.loading.UnifiedLoaderRepository3;
33
34 import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
35
36 /** For the <C, UCL> and C^UCL notation used in the comments refer to the
37  * paper "Dynamic Class Loading in the Java Virtual Machine", by Sheng
38  * Liang and Gilad Bracha. I found a pdf version here:
39  * http://www.cs.purdue.edu/homes/jv/smc/pubs/liang-oopsla98.pdf
40  * You can get a postscript version from here:
41  * http://java.sun.com/people/sl/papers/oopsla98.ps.gz
42  * @author Scott.Stark@jboss.org
43  * @version $Revision: 58115 $
44  */

45 public class CircularLoadTests
46 {
47    private static Logger log = Logger.getLogger(CircularLoadTests.class);
48
49    private CyclicBarrier setupBarrier = new CyclicBarrier(3);
50
51    public CircularLoadTests()
52    {
53    }
54
55    /** Test for LinkageError loading constraint violations.
56     Given a UnifiedLoaderRepository3 with 3 class loaders:
57     UCL0 uses le0.jar contains Base and UserOfBase
58     UCL1 uses le1.jar contains Base and Support
59     UCL2 this service sar
60
61     1. Load the Base class via UCL2. This has the potential for causing
62     <Base, UCL0> and <Base, UCL1> to be defined since both UCL0 and UCL1
63     contain this class.
64     2. Load the UserOfBase class via UCL0 to define <UserOfBase, UCL0>
65     3. Load the Support class via UCL1 to define <Support, UCL1>
66     4. Invoke testBase:
67     class <UserOfBase, UCL0>
68     {
69       public void testBase(<Support, UCL1> s)
70       {
71          Base b = s.getBase(); -> Base^UCL0 = Base^UCL1
72       ...
73     }
74     to trigger the loading constraint that Base as loaded by UCL0 and
75     UCL1 must be the same class.
76     */

77    public void testLinkageError() throws Exception JavaDoc
78    {
79       log.info("Begin testLinkageError");
80       UnifiedLoaderRepository3 repository = new UnifiedLoaderRepository3();
81       Class JavaDoc thisClass = getClass();
82       UnifiedClassLoader thisUCL = (UnifiedClassLoader) thisClass.getClassLoader();
83       URL JavaDoc origURL = thisUCL.getOrigURL();
84       log.info("Service origURL="+origURL);
85       URL JavaDoc j0 = new URL JavaDoc(origURL, "le0.jar");
86       log.info("j0 = "+j0);
87       URL JavaDoc j1 = new URL JavaDoc(origURL, "le1.jar");
88       log.info("j1 = "+j1);
89       final UnifiedClassLoader3 ucl0 = new UnifiedClassLoader3(j0);
90       final UnifiedClassLoader3 ucl1 = new UnifiedClassLoader3(j1);
91       final UnifiedClassLoader3 ucl2 = new UnifiedClassLoader3(origURL);
92       repository.addClassLoader(ucl0);
93       repository.addClassLoader(ucl1);
94       repository.addClassLoader(ucl2);
95
96       try
97       {
98          // Load Base
99
Class JavaDoc baseClass = ucl2.loadClass("org.jboss.test.classloader.circularity.support.Base");
100          log.info("Base.CS: "+baseClass.getClass().getProtectionDomain().getCodeSource());
101
102          // Load and create an instance of the UserOfBase class
103
Class JavaDoc userOfBaseClass = ucl0.loadClass("org.jboss.test.classloader.circularity.support.UserOfBase");
104          Class JavaDoc[] noSig = {};
105          Constructor JavaDoc ctor0 = userOfBaseClass.getConstructor(noSig);
106          Object JavaDoc[] noArgs = {};
107          Object JavaDoc userOfBase = ctor0.newInstance(noArgs);
108          log.info("UserOfBase.CS: "+userOfBase.getClass().getProtectionDomain().getCodeSource());
109
110          // Load and create an instance of the Support class
111
Class JavaDoc supportClass = ucl1.loadClass("org.jboss.test.classloader.circularity.support.Support");
112          Constructor JavaDoc ctor1 = supportClass.getConstructor(noSig);
113          Object JavaDoc support = ctor1.newInstance(noArgs);
114          log.info("Support.CS: "+support.getClass().getProtectionDomain().getCodeSource());
115
116          // Now invoke UserOfBase.testBase(Support)
117
Class JavaDoc[] sig = {supportClass};
118          Method JavaDoc testBase = userOfBaseClass.getMethod("testBase", sig);
119          log.info(testBase.toString());
120          Object JavaDoc[] args = {support};
121          testBase.invoke(userOfBase, args);
122       }
123       catch(Exception JavaDoc e)
124       {
125          log.error("Failed", e);
126          throw e;
127       }
128       catch(Throwable JavaDoc e)
129       {
130          log.error("Failed", e);
131          throw new UndeclaredThrowableException JavaDoc(e);
132       }
133       log.info("End testLinkageError");
134    }
135
136    /** Test for IllegalAccessError violations due to pkg classes split across jars
137     Given a UnifiedLoaderRepository3 with two class loaders:
138     UCL0 uses login.jar which contains UserOfLoginInfo
139     UCL1 uses usrmgr.jar which contains UserOfUsrMgr
140
141     Both the login.jar and usrmgr.jar reference a cl-util.jar via manifest
142     Class-Path entries. The cl-util.jar contains LoginInfo and UsrMgr.
143     */

144    public void testPackageProtected() throws Exception JavaDoc
145    {
146       log.info("Begin testPackageProtected");
147       UnifiedLoaderRepository3 repository = new UnifiedLoaderRepository3();
148       Class JavaDoc thisClass = getClass();
149       UnifiedClassLoader thisUCL = (UnifiedClassLoader) thisClass.getClassLoader();
150       URL JavaDoc origURL = thisUCL.getOrigURL();
151       log.info("Service origURL="+origURL);
152       URL JavaDoc j0 = new URL JavaDoc(origURL, "login.jar");
153       log.info("j0 = "+j0);
154       URL JavaDoc j1 = new URL JavaDoc(origURL, "usrmgr.jar");
155       log.info("j1 = "+j1);
156       URL JavaDoc util = new URL JavaDoc(origURL, "cl-util.jar");
157       log.info("util = "+j1);
158       final UnifiedClassLoader3 libs = new UnifiedClassLoader3(origURL);
159       final UnifiedClassLoader3 ucl0 = libs;
160       final UnifiedClassLoader3 ucl1 = libs;
161       repository.addClassLoader(libs);
162       libs.addURL(util);
163       libs.addURL(j0);
164       libs.addURL(j1);
165
166       try
167       {
168       // Load and create an instance of the UserOfLoginInfo class
169
Class JavaDoc c0 = ucl0.loadClass("org.jboss.test.classloader.circularity.support.UserOfLoginInfo");
170       Class JavaDoc[] ctorsig0 = {String JavaDoc.class, String JavaDoc.class};
171       Constructor JavaDoc ctor0 = c0.getConstructor(ctorsig0);
172       Object JavaDoc[] args0 = {"jduke", "theduke"};
173       Object JavaDoc o0 = ctor0.newInstance(args0);
174       log.info("UserOfLoginInfo.CS: "+o0.getClass().getProtectionDomain().getCodeSource());
175
176       // Load and create an instance of the UserOfUsrMgr class
177
Class JavaDoc c1 = ucl1.loadClass("org.jboss.test.classloader.circularity.support.UserOfUsrMgr");
178       Class JavaDoc[] ctorsig1 = {String JavaDoc.class, String JavaDoc.class};
179       Constructor JavaDoc ctor1 = c1.getConstructor(ctorsig1);
180       Object JavaDoc[] args1 = {"jduke", "theduke"};
181       Object JavaDoc o1 = ctor1.newInstance(args1);
182       log.info("UserOfUsrMgr.CS: "+o1.getClass().getProtectionDomain().getCodeSource());
183
184       // Now invoke UserOfUsrMgr.changePassword(char[] password)
185
char[] password = "theduke2".toCharArray();
186          Class JavaDoc[] sig = {password.getClass()};
187          Method JavaDoc changePassword = c1.getMethod("changePassword", sig);
188          log.info(changePassword.toString());
189          Object JavaDoc[] args = {password};
190          changePassword.invoke(o1, args);
191       }
192       catch(Exception JavaDoc e)
193       {
194          log.error("Failed", e);
195          throw e;
196       }
197       log.info("End testPackageProtected");
198    }
199
200    /** Given a UnifiedLoaderRepository3 with two class loaders:
201     UCL0 uses any0.jar which contains Base, Class0, Class2
202     UCL1 uses any1.jar which contains Class0, Class2
203     create a thread to load Derived using UCL0.
204     */

205    public void testDuplicateClass() throws Exception JavaDoc
206    {
207       log.info("Begin testDuplicateClass");
208       UnifiedLoaderRepository3 repository = new UnifiedLoaderRepository3();
209       Class JavaDoc thisClass = getClass();
210       UnifiedClassLoader thisUCL = (UnifiedClassLoader) thisClass.getClassLoader();
211       URL JavaDoc origURL = thisUCL.getOrigURL();
212       log.info("Service origURL="+origURL);
213       URL JavaDoc j0 = new URL JavaDoc(origURL, "any0.jar");
214       log.info("j0 = "+j0);
215       URL JavaDoc j1 = new URL JavaDoc(origURL, "any1.jar");
216       log.info("j1 = "+j1);
217       final UnifiedClassLoader3 ucl0 = new UnifiedClassLoader3(j0);
218       final UnifiedClassLoader3 ucl1 = new UnifiedClassLoader3(j1);
219       repository.addClassLoader(ucl0);
220       repository.addClassLoader(ucl1);
221
222       Class JavaDoc c0 = ucl0.loadClass("org.jboss.test.classloader.circularity.support.Class0");
223       log.info("Class0.CS: "+c0.getProtectionDomain().getCodeSource());
224       Class JavaDoc c2 = ucl1.loadClass("org.jboss.test.classloader.circularity.support.Class2");
225       log.info("Class2.CS: "+c2.getProtectionDomain().getCodeSource());
226       Class JavaDoc base = ucl0.loadClass("org.jboss.test.classloader.circularity.support.Base");
227       Class JavaDoc[] sig = {};
228       Method JavaDoc run = base.getMethod("run", sig);
229       Object JavaDoc[] empty = {};
230       run.invoke(null, empty);
231       log.info("End testDuplicateClass");
232    }
233
234    /** Given a UnifiedLoaderRepository3 with three class loaders:
235     UCL0 uses j0.jar which contains Class0
236     UCL1 uses j2.jar which contains Class2
237     Request a class org.jboss.test.classloader.circularity.supportx.Class2
238     using T0 assign ownership of UCL0 to T0, and then load Class2 using
239     UCL1 and T1 to validate that a load task is not assigned to T0 since
240     is should no longer own a UCL with the org.jboss.test.classloader.circularity.support
241     package.
242     */

243    public void testUCLOwner() throws Exception JavaDoc
244    {
245       UnifiedLoaderRepository3 repository = new UnifiedLoaderRepository3();
246       Class JavaDoc thisClass = getClass();
247       UnifiedClassLoader thisUCL = (UnifiedClassLoader) thisClass.getClassLoader();
248       URL JavaDoc origURL = thisUCL.getOrigURL();
249       log.info("Service origURL="+origURL);
250       URL JavaDoc j0 = new URL JavaDoc(origURL, "j0.jar");
251       log.info("j0 = "+j0);
252       URL JavaDoc j1 = new URL JavaDoc(origURL, "j2.jar");
253       log.info("j1 = "+j1);
254       final UnifiedClassLoader3 ucl0 = new UnifiedClassLoader3(j0);
255       final UnifiedClassLoader3 ucl1 = new UnifiedClassLoader3(j1);
256       repository.addClassLoader(ucl0);
257       repository.addClassLoader(ucl1);
258
259       // Request a class in a package that does not exist
260
LoadThread t0 = new LoadThread("org.jboss.test.classloader.circularity.supportx.Class2",
261          ucl0, "testUCLOwner.T0");
262       t0.start();
263       // Join the thread
264
t0.join(5000);
265       if( t0.loadedClass != null || t0.loadError == null )
266       {
267          log.error("T0 failed as no class should have been found, loadedClass="+t0.loadedClass);
268          throw new IllegalStateException JavaDoc("T0 failed as no class should have been found");
269       }
270
271       LoadThread t1 = new LoadThread("org.jboss.test.classloader.circularity.support.Class2",
272          ucl1, "testUCLOwner.T1");
273       t1.start();
274       // Join the thread
275
t1.join(5000);
276       if( t1.loadedClass == null || t1.loadError != null )
277       {
278          log.error("T1 failed to load Class2", t1.loadError);
279          throw new IllegalStateException JavaDoc("T1 failed to load Class2");
280       }
281    }
282
283    /** Given a UnifiedLoaderRepository3 with three class loaders:
284     UCL0 uses j0.jar which contains Class0
285     UCL1 uses j4.jar which contains Derived, but not Base
286     create a thread to load Derived using UCL0.
287     */

288    public void testMissingSuperClass() throws Exception JavaDoc
289    {
290       UnifiedLoaderRepository3 repository = new UnifiedLoaderRepository3();
291       Class JavaDoc thisClass = getClass();
292       UnifiedClassLoader thisUCL = (UnifiedClassLoader) thisClass.getClassLoader();
293       URL JavaDoc origURL = thisUCL.getOrigURL();
294       log.info("Service origURL="+origURL);
295       URL JavaDoc j0 = new URL JavaDoc(origURL, "j0.jar");
296       log.info("j0 = "+j0);
297       URL JavaDoc j3 = new URL JavaDoc(origURL, "j3.jar");
298       log.info("j3 = "+j3);
299       final UnifiedClassLoader3 ucl0 = new UnifiedClassLoader3(j0);
300       final UnifiedClassLoader3 ucl1 = new UnifiedClassLoader3(j3);
301       repository.addClassLoader(ucl0);
302       repository.addClassLoader(ucl1);
303
304       LoadThread t0 = new LoadThread("org.jboss.test.classloader.circularity.support.Derived",
305          ucl0, "testMissingSuperClass.T0");
306       t0.start();
307       // Join the thread
308
t0.join(5000);
309       if( t0.loadedClass != null || t0.loadError == null )
310       {
311          log.error("T0 failed as no class should have been found");
312          throw new IllegalStateException JavaDoc("T0 failed as no class should have been found");
313       }
314       log.debug("Load of Derivied failed as expected", t0.loadError);
315    }
316
317    /** Given a UnifiedLoaderRepository3 with three class loaders:
318     UCL0 uses j0.jar which contains Class0
319     UCL1 uses j1.jar which contains Class1
320     UCL2 uses j2.jar which contains Class2
321
322     creates 3 threads:
323     T0 uses UCL0 to load Class2
324     T1 uses UCL1 to load Class0
325     T2 uses UCL2 to load Class1
326     */

327    public void testLoading() throws Exception JavaDoc
328    {
329       UnifiedLoaderRepository3 repository = new UnifiedLoaderRepository3();
330       Class JavaDoc thisClass = getClass();
331       UnifiedClassLoader thisUCL = (UnifiedClassLoader) thisClass.getClassLoader();
332       URL JavaDoc origURL = thisUCL.getOrigURL();
333       log.info("Service origURL="+origURL);
334       URL JavaDoc j0 = new URL JavaDoc(origURL, "j0.jar");
335       log.info("j0 = "+j0);
336       URL JavaDoc j1 = new URL JavaDoc(origURL, "j1.jar");
337       log.info("j1 = "+j1);
338       URL JavaDoc j2 = new URL JavaDoc(origURL, "j2.jar");
339       log.info("j2 = "+j2);
340       final UnifiedLoader ucl0 = new UnifiedLoader(j0);
341       final UnifiedLoader ucl1 = new UnifiedLoader(j1);
342       final UnifiedLoader ucl2 = new UnifiedLoader(j2);
343       repository.addClassLoader(ucl0);
344       repository.addClassLoader(ucl1);
345       repository.addClassLoader(ucl2);
346
347       LoadThread t0 = new LoadThread("org.jboss.test.classloader.circularity.support.Class2",
348          ucl0, "testLoading.T0");
349       LoadThread t1 = new LoadThread("org.jboss.test.classloader.circularity.support.Class0",
350          ucl1, "testLoading.T1");
351       LoadThread t2 = new LoadThread("org.jboss.test.classloader.circularity.support.Class1",
352          ucl2, "testLoading.T2");
353       t0.start();
354       t1.start();
355       t2.start();
356       // Join the threads
357
boolean ok = true;
358       t0.join(5000);
359       if( t0.loadedClass == null || t0.loadError != null )
360       {
361          log.error("T0 failed", t0.loadError);
362          ok = false;
363       }
364       t1.join(5000);
365       if( t1.loadedClass == null || t1.loadError != null )
366       {
367          log.error("T1 failed", t1.loadError);
368          ok = false;
369       }
370       t2.join(5000);
371       if( t2.loadedClass == null || t2.loadError != null )
372       {
373          log.error("T2 failed", t2.loadError);
374          ok = false;
375       }
376       if( ok == false )
377          throw new IllegalStateException JavaDoc("Failed to load Class0..Class2");
378    }
379
380    static class LoadThread extends Thread JavaDoc
381    {
382       String JavaDoc classname;
383       ClassLoader JavaDoc loader;
384       Class JavaDoc loadedClass;
385       Throwable JavaDoc loadError;
386
387       LoadThread(String JavaDoc classname, ClassLoader JavaDoc loader, String JavaDoc name)
388       {
389          super(name);
390          this.classname = classname;
391          this.loader = loader;
392       }
393
394       public void run()
395       {
396          try
397          {
398             loadedClass = loader.loadClass(classname);
399          }
400          catch(Throwable JavaDoc t)
401          {
402             loadError = t;
403          }
404       }
405    }
406
407    public class UnifiedLoader extends UnifiedClassLoader3
408    {
409       private boolean enteredBarrier;
410       public UnifiedLoader(URL JavaDoc url)
411       {
412          super(url);
413       }
414
415       public synchronized Class JavaDoc loadClass(String JavaDoc name, boolean resolve)
416          throws ClassNotFoundException JavaDoc
417       {
418          try
419          {
420             // Get the UCLs all locked up before starting
421
if( enteredBarrier == false )
422                setupBarrier.barrier();
423             enteredBarrier = true;
424          }
425          catch(InterruptedException JavaDoc e)
426          {
427             throw new ClassNotFoundException JavaDoc("Failed due to InterruptedException");
428          }
429          return super.loadClass(name, false);
430       }
431
432    }
433 }
434
Popular Tags