001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.test.classloader.test;
023:
024: import java.io.File;
025: import java.net.URL;
026: import java.util.HashSet;
027: import java.util.Set;
028: import java.lang.reflect.Field;
029: import java.lang.reflect.Method;
030:
031: import junit.framework.TestCase;
032: import junit.framework.TestSuite;
033: import junit.framework.Test;
034:
035: import org.jboss.mx.loading.HeirarchicalLoaderRepository3;
036: import org.jboss.mx.loading.UnifiedClassLoader3;
037: import org.jboss.mx.loading.UnifiedLoaderRepository3;
038: import org.jboss.mx.loading.RepositoryClassLoader;
039: import org.jboss.test.util.ClassMover;
040: import org.apache.log4j.Logger;
041: import javassist.ClassPool;
042: import javassist.CtClass;
043: import javassist.CtField;
044: import javassist.Modifier;
045:
046: /** Basic tests of the org.jboss.mx.loading.* classes
047: *
048: * @author Scott.Stark@jboss.org
049: * @version $Revision: 63653 $
050: */
051: public class BasicLoaderUnitTestCase extends TestCase {
052: static Logger log = Logger.getLogger(BasicLoaderUnitTestCase.class);
053: String jbosstestDeployDir;
054:
055: public BasicLoaderUnitTestCase(String name) {
056: super (name);
057: }
058:
059: protected void setUp() throws Exception {
060: jbosstestDeployDir = System.getProperty("jbosstest.deploy.dir");
061: if (jbosstestDeployDir == null) {
062: // Try to use ./output/lib
063: File libDir = new File("output/lib");
064: if (libDir.exists() == false)
065: throw new Exception(
066: "System property jbosstest.deploy.dir is not defined");
067: jbosstestDeployDir = libDir.getAbsolutePath();
068: }
069: }
070:
071: /** Test the UnifiedLoaderRepository for multi-threaded class loading
072: */
073: public void testNoClassDefFoundError() throws Exception {
074: UnifiedLoaderRepository3 ulr = new UnifiedLoaderRepository3();
075: File cwd = new File(jbosstestDeployDir);
076: URL cp = new URL(cwd.toURL(), "../classes");
077: log.info("Using cp: " + cp);
078: ClassLoader loader = ulr.newClassLoader(cp, true);
079:
080: File bakFile = null;
081: try {
082: bakFile = ClassMover
083: .move("org.jboss.test.classloader.test.ex.BaseException");
084: loader
085: .loadClass("org.jboss.test.classloader.test.ex.DerivedException");
086: fail("Should not have loaded DerivedException");
087: } catch (NoClassDefFoundError e) {
088: String msg = e.getMessage();
089: log.info("NCDFE msg: " + msg, e);
090: int index = msg.indexOf("BaseException");
091: assertTrue("Saw BaseException in NCDFE: (" + index
092: + "), msg=" + msg, index > 0);
093: } finally {
094: if (bakFile != null)
095: ClassMover.restore(bakFile);
096: }
097:
098: }
099:
100: public void testNoClassDefFoundError2() throws Exception {
101: UnifiedLoaderRepository3 ulr = new UnifiedLoaderRepository3();
102: File cwd = new File(jbosstestDeployDir);
103: URL cp = new URL(cwd.toURL(), "../classes");
104: log.info("Using cp: " + cp);
105: File bakFile = ClassMover
106: .move("org.jboss.test.classloader.test.ex.BaseException");
107: ClassLoader loader = ulr.newClassLoader(cp, true);
108:
109: try {
110: Class c = loader
111: .loadClass("org.jboss.test.classloader.test.ex.ExThrower");
112: Method[] methods = c.getMethods();
113: for (int n = 0; n < methods.length; n++) {
114: Method m = methods[n];
115: m.getExceptionTypes();
116: }
117: fail("Should not have gotten ExThrower methods");
118: } catch (NoClassDefFoundError e) {
119: String msg = e.getMessage();
120: log.info("CNFE msg: " + msg, e);
121: int index = msg.indexOf("BaseException");
122: assertTrue("Saw BaseException in CNFE: (" + index
123: + "), msg=" + msg, index > 0);
124: } finally {
125: if (bakFile != null)
126: ClassMover.restore(bakFile);
127: }
128:
129: }
130:
131: public void testDeadlockScenario1() throws Exception {
132: File libDir = new File(jbosstestDeployDir);
133: log.info("Using cp: " + libDir);
134: DeadlockTests32 test = new DeadlockTests32(libDir);
135: test.testDeadLock();
136: }
137:
138: public void testDeadlockScenario2() throws Exception {
139: File libDir = new File(jbosstestDeployDir);
140: log.info("Using cp: " + libDir);
141: DeadlockTests32 test = new DeadlockTests32(libDir);
142: test.testDeadLockAndCircularity();
143: }
144:
145: /**
146: Validate that the added order/classpath order is used when loading classes
147: from the ULR.
148:
149: @throws Exception
150: */
151: public void testClasspathOrdering() throws Exception {
152: File libDir = new File(jbosstestDeployDir);
153: File classes1 = new File(libDir, "classes1");
154: classes1.mkdir();
155:
156: // Create a test.Info class with a static String version = "Version 1.0"
157: ClassPool defaultPool = ClassPool.getDefault();
158: ClassPool classes1Pool = new ClassPool(defaultPool);
159: CtClass info = classes1Pool.makeClass("test.Info");
160: CtClass s = classes1Pool.get("java.lang.String");
161: CtField version = new CtField(s, "version", info);
162: version.setModifiers(Modifier.PUBLIC | Modifier.STATIC);
163: info.addField(version, CtField.Initializer
164: .constant("Version 1.0"));
165: info.writeFile(classes1.getAbsolutePath());
166:
167: // Create a test.Info class with a static String version = "Version 2.0"
168: ClassPool classes2Pool = new ClassPool(defaultPool);
169: info = classes2Pool.makeClass("test.Info");
170: File classes2 = new File(libDir, "classes2");
171: classes2.mkdir();
172: version = new CtField(s, "version", info);
173: version.setModifiers(Modifier.PUBLIC | Modifier.STATIC);
174: info.addField(version, CtField.Initializer
175: .constant("Version 2.0"));
176: info.writeFile(classes2.getAbsolutePath());
177:
178: // Create a test.Info class with a static String version = "Version 3.0"
179: ClassPool classes3Pool = new ClassPool(defaultPool);
180: info = classes3Pool.makeClass("test.Info");
181: File classes3 = new File(libDir, "classes3");
182: classes3.mkdir();
183: version = new CtField(s, "version", info);
184: version.setModifiers(Modifier.PUBLIC | Modifier.STATIC);
185: info.addField(version, CtField.Initializer
186: .constant("Version 3.0"));
187: info.writeFile(classes3.getAbsolutePath());
188:
189: // Create a URL with classpath {classes1, classes2, classes3}
190: UnifiedLoaderRepository3 ulr = new UnifiedLoaderRepository3();
191: RepositoryClassLoader loader1 = ulr.newClassLoader(classes1
192: .toURL(), true);
193: loader1.addURL(classes2.toURL());
194: RepositoryClassLoader loader2 = ulr.newClassLoader(classes3
195: .toURL(), true);
196:
197: // This should see version 1
198: Class infoClass = loader1.loadClass("test.Info");
199: log.info("#1.1"
200: + infoClass.getProtectionDomain().getCodeSource());
201: Field theVersion = infoClass.getField("version");
202: String v = (String) theVersion.get(null);
203: assertTrue(v, v.equals("Version 1.0"));
204:
205: // This should also see version 1
206: infoClass = loader2.loadClass("test.Info");
207: log.info("#1.2"
208: + infoClass.getProtectionDomain().getCodeSource());
209: theVersion = infoClass.getField("version");
210: v = (String) theVersion.get(null);
211: assertTrue(v, v.equals("Version 1.0"));
212: ulr.removeClassLoader(loader1);
213: ulr.removeClassLoader(loader2);
214: ulr.flush();
215:
216: // Create a URL with classpath {classes2, classes1, classes3}
217: ulr = new UnifiedLoaderRepository3();
218: loader1 = ulr.newClassLoader(classes2.toURL(), true);
219: loader1.addURL(classes1.toURL());
220: loader2 = ulr.newClassLoader(classes3.toURL(), true);
221:
222: // This should see version 2
223: infoClass = loader1.loadClass("test.Info");
224: log.info("#2.1"
225: + infoClass.getProtectionDomain().getCodeSource());
226: theVersion = infoClass.getField("version");
227: v = (String) theVersion.get(null);
228: assertTrue(v, v.equals("Version 2.0"));
229:
230: // This should also see version 2
231: infoClass = loader2.loadClass("test.Info");
232: log.info("#2.2"
233: + infoClass.getProtectionDomain().getCodeSource());
234: theVersion = infoClass.getField("version");
235: v = (String) theVersion.get(null);
236: assertTrue(v, v.equals("Version 2.0"));
237: ulr.removeClassLoader(loader1);
238: ulr.removeClassLoader(loader2);
239: ulr.flush();
240:
241: // Create a URL with classpath {classes3, classes1, classes2}
242: ulr = new UnifiedLoaderRepository3();
243: loader1 = ulr.newClassLoader(classes3.toURL(), true);
244: loader1.addURL(classes1.toURL());
245: loader2 = ulr.newClassLoader(classes2.toURL(), true);
246:
247: // This should see version 3
248: infoClass = loader1.loadClass("test.Info");
249: log.info("#3.1"
250: + infoClass.getProtectionDomain().getCodeSource());
251: theVersion = infoClass.getField("version");
252: v = (String) theVersion.get(null);
253: assertTrue(v, v.equals("Version 3.0"));
254:
255: // This should also see version 3
256: infoClass = loader2.loadClass("test.Info");
257: log.info("#3.2"
258: + infoClass.getProtectionDomain().getCodeSource());
259: theVersion = infoClass.getField("version");
260: v = (String) theVersion.get(null);
261: assertTrue(v, v.equals("Version 3.0"));
262: }
263:
264: /**
265: * Force a LinkageError during loading of a class to validate that
266: * a legitimate LinkageError does not cause an infinite loop.
267: * JBAS-4441
268: * @throws Exception
269: */
270: public void testLinkageError() throws Exception {
271: log.info("Begin testLinkageError");
272: UnifiedLoaderRepository3 parentRepo = new UnifiedLoaderRepository3();
273: HeirarchicalLoaderRepository3 repo2 = new HeirarchicalLoaderRepository3(
274: parentRepo);
275: repo2.setUseParentFirst(false);
276: File libDir = new File(jbosstestDeployDir);
277: URL origURL = libDir.toURL();
278: log.info("Lib origURL=" + origURL);
279: URL j2 = new URL(origURL, "xsub2.jar");
280: log.info("j2 = " + j2);
281: URL j1 = new URL(origURL, "xsub1.jar");
282: log.info("j1 = " + j1);
283: ClassLoader parent = new ClassLoader() {
284: @Override
285: protected synchronized Class<?> loadClass(String name,
286: boolean resolve) throws ClassNotFoundException {
287: if (name.startsWith("java"))
288: return super .loadClass(name, resolve);
289: throw new ClassNotFoundException("No class loading");
290: }
291: };
292: final UnifiedClassLoader3 ucl0 = new UnifiedClassLoader3(j1,
293: j1, parent, parentRepo);
294: parentRepo.addClassLoader(ucl0);
295: final UnifiedClassLoader3 ucl2 = new UnifiedClassLoader3(j2,
296: j2, parent, repo2) {
297: /**
298: * Throw a LinkageError to trigger the LoadMgr retry logic
299: */
300: @Override
301: public Class loadClassLocally(String name, boolean resolve)
302: throws ClassNotFoundException {
303: if (name
304: .equals("org.jboss.test.classloader.circularity.support.linkage.X"))
305: throw new LinkageError("Cannot load X");
306: return super .loadClassLocally(name, resolve);
307: }
308: };
309: repo2.addClassLoader(ucl2);
310:
311: try {
312: Class c = ucl2
313: .loadClass("org.jboss.test.classloader.circularity.support.linkage.Xsub");
314: fail("Was able to load Xsub");
315: } catch (NoClassDefFoundError e) {
316: log.info("Saw NoClassDefFoundError as expected", e);
317: }
318:
319: }
320:
321: public static Test suite() {
322: TestSuite suite = new TestSuite();
323: suite.addTest(new BasicLoaderUnitTestCase(
324: "testNoClassDefFoundError"));
325: suite.addTest(new BasicLoaderUnitTestCase(
326: "testNoClassDefFoundError2"));
327: suite.addTest(new BasicLoaderUnitTestCase(
328: "testDeadlockScenario1"));
329: suite.addTest(new BasicLoaderUnitTestCase(
330: "testDeadlockScenario2"));
331: suite.addTest(new BasicLoaderUnitTestCase(
332: "testClasspathOrdering"));
333: suite.addTest(new BasicLoaderUnitTestCase("testLinkageError"));
334: return suite;
335: }
336: }
|