1   package org.codehaus.classworlds;
2   
3   /*
4    $Id: ClassRealmImplTest.java,v 1.1.1.1 2004/07/01 13:59:20 jvanzyl Exp $
5   
6    Copyright 2002 (C) The Werken Company. All Rights Reserved.
7   
8    Redistribution and use of this software and associated documentation
9    ("Software"), with or without modification, are permitted provided
10   that the following conditions are met:
11  
12   1. Redistributions of source code must retain copyright
13      statements and notices.  Redistributions must also contain a
14      copy of this document.
15  
16   2. Redistributions in binary form must reproduce the
17      above copyright notice, this list of conditions and the
18      following disclaimer in the documentation and/or other
19      materials provided with the distribution.
20  
21   3. The name "classworlds" must not be used to endorse or promote
22      products derived from this Software without prior written
23      permission of The Werken Company.  For written permission,
24      please contact bob@werken.com.
25  
26   4. Products derived from this Software may not be called "classworlds"
27      nor may "classworlds" appear in their names without prior written
28      permission of The Werken Company. "classworlds" is a registered
29      trademark of The Werken Company.
30  
31   5. Due credit should be given to The Werken Company.
32      (http://classworlds.werken.com/).
33  
34   THIS SOFTWARE IS PROVIDED BY THE WERKEN COMPANY AND CONTRIBUTORS
35   ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
36   NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
37   FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
38   THE WERKEN COMPANY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
39   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
40   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
41   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
43   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
44   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
45   OF THE POSSIBILITY OF SUCH DAMAGE.
46  
47   */
48  
49  import junit.framework.TestCase;
50  
51  import java.net.MalformedURLException;
52  
53  import java.net.URL;
54  
55  public class ClassRealmImplTest
56      extends TestCase
57  {
58      private ClassWorld world;
59  
60      public ClassRealmImplTest( String name )
61      {
62          super( name );
63      }
64  
65      public void setUp()
66      {
67          this.world = new ClassWorld();
68      }
69  
70      public void tearDown()
71      {
72          this.world = null;
73      }
74  
75      public void testNewRealm()
76          throws Exception
77      {
78          ClassRealm realm = this.world.newRealm( "foo" );
79  
80          assertNotNull( realm );
81  
82          assertSame( this.world, realm.getWorld() );
83  
84          assertEquals( "foo", realm.getId() );
85      }
86  
87      public void testLocateSourceRealm_NoImports()
88          throws Exception
89      {
90          DefaultClassRealm realm = new DefaultClassRealm( this.world, "foo" );
91  
92          assertSame( realm, realm.locateSourceRealm( "com.werken.Stuff" ) );
93      }
94  
95      public void testLocateSourceRealm_SimpleImport()
96          throws Exception
97      {
98          DefaultClassRealm mainRealm = (DefaultClassRealm) this.world.newRealm( "main" );
99  
100         ClassRealm werkflowRealm = this.world.newRealm( "werkflow" );
101 
102         mainRealm.importFrom( "werkflow", "com.werken.werkflow" );
103 
104         assertSame( werkflowRealm, mainRealm.locateSourceRealm( "com.werken.werkflow.WerkflowEngine" ) );
105 
106         assertSame( werkflowRealm, mainRealm.locateSourceRealm( "com.werken.werkflow.process.ProcessManager" ) );
107 
108         assertSame( mainRealm, mainRealm.locateSourceRealm( "com.werken.blissed.Process" ) );
109 
110         assertSame( mainRealm, mainRealm.locateSourceRealm( "java.lang.Object" ) );
111 
112         assertSame( mainRealm, mainRealm.locateSourceRealm( "NoviceProgrammerClass" ) );
113     }
114 
115     public void testLocateSourceRealm_MultipleImport()
116         throws Exception
117     {
118         DefaultClassRealm mainRealm = (DefaultClassRealm) this.world.newRealm( "main" );
119 
120         ClassRealm werkflowRealm = this.world.newRealm( "werkflow" );
121 
122         ClassRealm blissedRealm = this.world.newRealm( "blissed" );
123 
124         mainRealm.importFrom( "werkflow", "com.werken.werkflow" );
125 
126         mainRealm.importFrom( "blissed", "com.werken.blissed" );
127 
128         assertSame( werkflowRealm, mainRealm.locateSourceRealm( "com.werken.werkflow.WerkflowEngine" ) );
129 
130         assertSame( werkflowRealm, mainRealm.locateSourceRealm( "com.werken.werkflow.process.ProcessManager" ) );
131 
132         assertSame( blissedRealm, mainRealm.locateSourceRealm( "com.werken.blissed.Process" ) );
133 
134         assertSame( blissedRealm, mainRealm.locateSourceRealm( "com.werken.blissed.guard.BooleanGuard" ) );
135 
136         assertSame( mainRealm, mainRealm.locateSourceRealm( "java.lang.Object" ) );
137 
138         assertSame( mainRealm, mainRealm.locateSourceRealm( "NoviceProgrammerClass" ) );
139     }
140 
141     public void testLocateSourceRealm_Hierachy() throws Exception
142     {
143         DefaultClassRealm mainRealm = (DefaultClassRealm) this.world.newRealm( "main" );
144 
145         ClassRealm fooRealm = this.world.newRealm( "foo" );
146 
147         ClassRealm fooBarRealm = this.world.newRealm( "fooBar" );
148 
149         ClassRealm fooBarBazRealm = this.world.newRealm( "fooBarBaz" );
150 
151         mainRealm.importFrom( "foo", "foo" );
152 
153         mainRealm.importFrom( "fooBar", "foo.bar" );
154 
155         mainRealm.importFrom( "fooBarBaz", "foo.bar.baz" );
156 
157         assertSame( fooRealm, mainRealm.locateSourceRealm( "foo.Goober" ) );
158 
159         assertSame( fooRealm, mainRealm.locateSourceRealm( "foo.cheese.Goober" ) );
160 
161         assertSame( fooBarRealm, mainRealm.locateSourceRealm( "foo.bar.Goober" ) );
162 
163         assertSame( fooBarRealm, mainRealm.locateSourceRealm( "foo.bar.cheese.Goober" ) );
164 
165         assertSame( fooBarBazRealm, mainRealm.locateSourceRealm( "foo.bar.baz.Goober" ) );
166 
167         assertSame( fooBarBazRealm,
168                     mainRealm.locateSourceRealm( "foo.bar.baz.cheese.Goober" ) );
169 
170         assertSame( mainRealm, mainRealm.locateSourceRealm( "java.lang.Object" ) );
171 
172         assertSame( mainRealm, mainRealm.locateSourceRealm( "NoviceProgrammerClass" ) );
173     }
174 
175     public void testLocateSourceRealm_Hierachy_Reverse() throws Exception
176     {
177         ClassRealm fooBarBazRealm = this.world.newRealm( "fooBarBaz" );
178 
179         ClassRealm fooBarRealm = this.world.newRealm( "fooBar" );
180 
181         ClassRealm fooRealm = this.world.newRealm( "foo" );
182 
183         DefaultClassRealm mainRealm = (DefaultClassRealm) this.world.newRealm( "main" );
184 
185         mainRealm.importFrom( "fooBarBaz", "foo.bar.baz" );
186 
187         mainRealm.importFrom( "fooBar", "foo.bar" );
188 
189         mainRealm.importFrom( "foo", "foo" );
190 
191         assertSame( fooRealm, mainRealm.locateSourceRealm( "foo.Goober" ) );
192 
193         assertSame( fooRealm, mainRealm.locateSourceRealm( "foo.cheese.Goober" ) );
194 
195         assertSame( fooBarRealm, mainRealm.locateSourceRealm( "foo.bar.Goober" ) );
196 
197         assertSame( fooBarRealm, mainRealm.locateSourceRealm( "foo.bar.cheese.Goober" ) );
198 
199         assertSame( fooBarBazRealm, mainRealm.locateSourceRealm( "foo.bar.baz.Goober" ) );
200 
201         assertSame( fooBarBazRealm, mainRealm.locateSourceRealm( "foo.bar.baz.cheese.Goober" ) );
202 
203         assertSame( mainRealm, mainRealm.locateSourceRealm( "java.lang.Object" ) );
204 
205         assertSame( mainRealm, mainRealm.locateSourceRealm( "NoviceProgrammerClass" ) );
206     }
207 
208     public void testLoadClass_SystemClass() throws Exception
209     {
210         ClassRealm mainRealm = this.world.newRealm( "main" );
211 
212         Class cls = mainRealm.loadClass( "java.lang.Object" );
213 
214         assertNotNull( cls );
215     }
216 
217     public void testLoadClass_NonSystemClass() throws Exception
218     {
219         ClassRealm mainRealm = this.world.newRealm( "main" );
220 
221         try
222         {
223             Class c = mainRealm.loadClass( "com.werken.projectz.UberThing" );
224 
225             System.out.println( "c = " + c );
226 
227             fail( "A ClassNotFoundException should be thrown!" );
228         }
229         catch ( ClassNotFoundException e )
230         {
231             // expected and correct
232         }
233     }
234 
235     public void testLoadClass_ClassWorldsClass() throws Exception
236     {
237         ClassRealm mainRealm = this.world.newRealm( "main" );
238 
239         Class cls = mainRealm.loadClass( "org.codehaus.classworlds.ClassWorld" );
240 
241         assertNotNull( cls );
242 
243         assertSame( ClassWorld.class, cls );
244     }
245 
246     public void testLoadClass_Local() throws Exception
247     {
248         ClassRealm mainRealm = this.world.newRealm( "main" );
249 
250         try
251         {
252             mainRealm.loadClass( "a.A" );
253         }
254         catch ( ClassNotFoundException e )
255         {
256             // expected and correct
257         }
258 
259         mainRealm.addConstituent( getJarUrl( "a.jar" ) );
260 
261         Class classA = mainRealm.loadClass( "a.A" );
262 
263         assertNotNull( classA );
264 
265         ClassRealm otherRealm = this.world.newRealm( "other" );
266 
267         try
268         {
269             otherRealm.loadClass( "a.A" );
270         }
271         catch ( ClassNotFoundException e )
272         {
273             // expected and correct
274         }
275     }
276 
277     public void testLoadClass_Imported() throws Exception
278     {
279         ClassRealm mainRealm = this.world.newRealm( "main" );
280 
281         ClassRealm realmA = this.world.newRealm( "realmA" );
282 
283         try
284         {
285             realmA.loadClass( "a.A" );
286 
287             fail( "realmA.loadClass(a.A) should have thrown a ClassNotFoundException" );
288         }
289         catch ( ClassNotFoundException e )
290         {
291             // expected and correct
292         }
293 
294         realmA.addConstituent( getJarUrl( "a.jar" ) );
295 
296         try
297         {
298             mainRealm.loadClass( "a.A" );
299 
300             fail( "mainRealm.loadClass(a.A) should have thrown a ClassNotFoundException" );
301         }
302         catch ( ClassNotFoundException e )
303         {
304             // expected and correct
305         }
306 
307         mainRealm.importFrom( "realmA", "a" );
308 
309         Class classA = realmA.loadClass( "a.A" );
310 
311         assertNotNull( classA );
312 
313         assertEquals( realmA.getClassLoader(), classA.getClassLoader() );
314 
315         Class classMain = mainRealm.loadClass( "a.A" );
316 
317         assertNotNull( classMain );
318 
319         assertEquals( realmA.getClassLoader(), classMain.getClassLoader() );
320 
321         assertSame( classA, classMain );
322     }
323 
324     public void testLoadClass_Package() throws Exception
325     {
326         ClassRealm realmA = this.world.newRealm( "realmA" );
327         realmA.addConstituent( getJarUrl( "a.jar" ) );
328 
329         Class clazz = realmA.loadClass( "a.A" );
330         assertNotNull( clazz );
331         assertEquals( "a.A", clazz.getName() );
332 
333         Package p = clazz.getPackage();
334         assertNotNull( p );
335         assertEquals( "p.getName()", "a", p.getName() );
336     }
337 
338 
339     public void testLoadClass_Complex() throws Exception
340     {
341         ClassRealm realmA = this.world.newRealm( "realmA" );
342         ClassRealm realmB = this.world.newRealm( "realmB" );
343         ClassRealm realmC = this.world.newRealm( "realmC" );
344 
345         realmA.addConstituent( getJarUrl( "a.jar" ) );
346         realmB.addConstituent( getJarUrl( "b.jar" ) );
347         realmC.addConstituent( getJarUrl( "c.jar" ) );
348 
349         realmC.importFrom( "realmA",
350                            "a" );
351 
352         realmC.importFrom( "realmB",
353                            "b" );
354 
355         realmA.importFrom( "realmC",
356                            "c" );
357 
358         Class classA_A = realmA.loadClass( "a.A" );
359         Class classB_B = realmB.loadClass( "b.B" );
360         Class classC_C = realmC.loadClass( "c.C" );
361 
362         assertNotNull( classA_A );
363         assertNotNull( classB_B );
364         assertNotNull( classC_C );
365 
366         assertEquals( realmA.getClassLoader(),
367                       classA_A.getClassLoader() );
368 
369         assertEquals( realmB.getClassLoader(),
370                       classB_B.getClassLoader() );
371 
372         assertEquals( realmC.getClassLoader(),
373                       classC_C.getClassLoader() );
374 
375         // load from C
376 
377         Class classA_C = realmC.loadClass( "a.A" );
378 
379         assertNotNull( classA_C );
380 
381         assertSame( classA_A,
382                     classA_C );
383 
384         assertEquals( realmA.getClassLoader(),
385                       classA_C.getClassLoader() );
386 
387         Class classB_C = realmC.loadClass( "b.B" );
388 
389         assertNotNull( classB_C );
390 
391         assertSame( classB_B,
392                     classB_C );
393 
394         assertEquals( realmB.getClassLoader(),
395                       classB_C.getClassLoader() );
396 
397         // load from A
398 
399         Class classC_A = realmA.loadClass( "c.C" );
400 
401         assertNotNull( classC_A );
402 
403         assertSame( classC_C,
404                     classC_A );
405 
406         assertEquals( realmC.getClassLoader(),
407                       classC_A.getClassLoader() );
408 
409         try
410         {
411             realmA.loadClass( "b.B" );
412             fail( "throw ClassNotFoundException" );
413         }
414         catch ( ClassNotFoundException e )
415         {
416             // expected and correct
417         }
418 
419         // load from B
420 
421         try
422         {
423             realmB.loadClass( "a.A" );
424             fail( "throw ClassNotFoundException" );
425         }
426         catch ( ClassNotFoundException e )
427         {
428             // expected and correct
429         }
430 
431         try
432         {
433             realmB.loadClass( "c.C" );
434             fail( "throw ClassNotFoundException" );
435         }
436         catch ( ClassNotFoundException e )
437         {
438             // expected and correct
439         }
440     }
441 
442     protected URL getJarUrl( String jarName ) throws MalformedURLException
443     {
444         return TestUtil.getTestResourceUrl( jarName );
445     }
446 
447     public void testLoadClass_ClassWorldsClassRepeatedly() throws Exception
448     {
449         ClassRealm mainRealm = this.world.newRealm( "main" );
450 
451         for ( int i = 0; i < 100; i++ )
452         {
453             Class cls = mainRealm.loadClass( "org.codehaus.classworlds.ClassWorld" );
454 
455             assertNotNull( cls );
456 
457             assertSame( ClassWorld.class, cls );
458         }
459     }
460 }