Initial import
[jpf-core.git] / src / tests / gov / nasa / jpf / test / java / net / URLClassLoaderTest.java
1 /*
2  * Copyright (C) 2014, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
6  * The Java Pathfinder core (jpf-core) platform is licensed under the
7  * Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  * 
10  *        http://www.apache.org/licenses/LICENSE-2.0. 
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and 
16  * limitations under the License.
17  */
18 package gov.nasa.jpf.test.java.net;
19
20 import java.io.IOException;
21 import java.lang.reflect.InvocationTargetException;
22 import java.lang.reflect.Method;
23 import java.net.MalformedURLException;
24 import java.net.URL;
25 import java.net.URLClassLoader;
26 import java.util.ArrayList;
27 import java.util.Enumeration;
28 import java.util.List;
29
30 import org.junit.Test;
31
32 /**
33  * @author Nastaran Shafiei <nastaran.shafiei@gmail.com>
34  * 
35  * test of java.lang.ClassLoader API
36  */
37 public class URLClassLoaderTest extends LoadUtility {
38
39   public class TestClassLoader extends URLClassLoader {
40
41     public TestClassLoader(URL[] urls) {
42         super(urls);
43     }
44
45     public TestClassLoader(URL[] urls, ClassLoader parent) {
46       super(urls, parent);
47     }
48     
49     @Override
50         public Class<?> findClass(String name) throws ClassNotFoundException {
51         return super.findClass(name);
52     }
53
54     public Class<?> getLoadedClass(String name) {
55       return findLoadedClass(name);
56     }
57
58     public Class<?> delegateTofindSystemClass(String cname) throws ClassNotFoundException {
59       return this.findSystemClass(cname);
60     }
61
62     @Override
63         protected Package[] getPackages() {
64       return super.getPackages();
65     }
66
67     @Override
68         protected Package getPackage(String name) {
69       return super.getPackage(name);
70     }
71   }
72
73   @Test
74   public void testConstructor_NullPointerException() {
75     if (verifyUnhandledException("java.lang.NullPointerException")) {
76       new URLClassLoader(null);
77     }
78   }
79
80   @Test 
81   public void testConstructorEmptyURLs () {
82     if (verifyNoPropertyViolation()) {
83       URLClassLoader cl = new URLClassLoader(new URL[0]);
84       assertNotNull(cl.getParent());
85       assertEquals(cl.getParent(), ClassLoader.getSystemClassLoader());
86     }
87   }
88
89   @Test
90   public void testConstructorParent() {
91     if (verifyNoPropertyViolation()) {
92       URL[] urls = new URL[0];
93       ClassLoader parent = new TestClassLoader(urls);
94       URLClassLoader cl =  new URLClassLoader(urls, parent);
95
96       assertNotNull(parent.getParent());
97       assertEquals(parent.getParent(), ClassLoader.getSystemClassLoader());
98
99       assertNotNull(cl.getParent());
100       assertEquals(cl.getParent(), parent);
101     }
102   }
103
104   @Test
105   public void testLoadClass_NoClassDefFoundError() throws ClassNotFoundException {
106     if (verifyUnhandledException("java.lang.NoClassDefFoundError")) {
107       URL[] urls = new URL[0];
108       URLClassLoader cl = new URLClassLoader(urls);
109       cl.loadClass("java/lang/Class");
110     }
111   }
112
113   @Test
114   public void testLoadClass_ClassNotFoundException() throws ClassNotFoundException {
115     if (verifyUnhandledException("java.lang.ClassNotFoundException")) {
116       URL[] urls = new URL[0];
117       URLClassLoader cl =  new URLClassLoader(urls);
118       cl.loadClass("java.lang.Does_Not_Exist");
119     }
120   }
121
122   @Test
123   public void testLoadClass_ClassNotFoundException2() throws ClassNotFoundException {
124     if (verifyUnhandledException("java.lang.ClassNotFoundException")) {
125       URL[] urls = new URL[0];
126       URLClassLoader cl =  new URLClassLoader(urls);
127       cl.loadClass("java.lang.Class.class");
128     }
129   }
130
131   @Test
132   public void testSystemLoaderLoadClass() throws ClassNotFoundException {
133    if (verifyNoPropertyViolation()) {
134       URL[] urls = new URL[0];
135       ClassLoader systemCl = ClassLoader.getSystemClassLoader();
136       ClassLoader parent = new TestClassLoader(urls);
137       URLClassLoader cl =  new URLClassLoader(urls, parent);
138
139       String cname = "java.lang.Class";
140       Class<?> c1 = systemCl.loadClass(cname);
141       Class<?> c2 = parent.loadClass(cname);
142       Class<?> c3 = cl.loadClass(cname);
143
144       assertSame(c1, c2);
145       assertSame(c1, c3);
146       // this test fails on the host VM, cause java.lang.Class is loaded by
147       // bootstrap classloader and therefore c1.getClassLoader() returns null,
148       // but the test passes on JPF.
149       assertSame(c1.getClassLoader(), systemCl);
150     }
151   }
152
153   @Test
154   public void testFindLoadedClass() throws ClassNotFoundException, MalformedURLException {
155     if (verifyNoPropertyViolation()) {
156       URL[] urls = new URL[0];
157       TestClassLoader ucl1 = new TestClassLoader(urls);
158       TestClassLoader ucl2 = new TestClassLoader(urls, ucl1);
159
160       String cname = "java.lang.Class";
161
162       Class<?> c = ucl2.loadClass(cname);
163       assertNotNull(c);
164       assertEquals(c.getName(), cname);
165
166       // systemClassLoader is going to be the defining classloader
167       assertNull(ucl2.getLoadedClass(cname));
168       assertNull(ucl1.getLoadedClass(cname));
169     }
170   }
171
172   @Test
173   public void testNonSystemLoaderLoadClass() throws MalformedURLException, ClassNotFoundException {
174     movePkgOut();
175     if (verifyNoPropertyViolation()) {
176       // create a url from a dir
177       URL[] urls = { new URL(dirUrl) };
178       URLClassLoader cl =  new URLClassLoader(urls);
179
180       String cname = pkg + ".Class1";
181       Class<?> cls = cl.loadClass(cname);
182
183       assertEquals(cls.getClassLoader(), cl);
184       assertFalse(cls.getClassLoader() == ClassLoader.getSystemClassLoader());
185
186       assertEquals(cls.getInterfaces().length, 2);
187       for(Class<?>ifc: cls.getInterfaces()) {
188         assertEquals(cls.getClassLoader(), ifc.getClassLoader());
189       }
190
191       // create a url from jar
192       urls[0] = new URL(jarUrl);
193       cl =  new URLClassLoader(urls);
194       cls = cl.loadClass(cname);
195
196       assertEquals(cls.getClassLoader(), cl);
197       assertFalse(cls.getClassLoader() == ClassLoader.getSystemClassLoader());
198       assertEquals(cls.getInterfaces().length, 2);
199       for(Class<?>ifc: cls.getInterfaces()) {
200         assertEquals(cls.getClassLoader(), ifc.getClassLoader());
201       }
202     }
203     movePkgBack();
204   }
205
206   @Test
207   public void testFindResource() throws MalformedURLException {
208     movePkgOut();
209     if (verifyNoPropertyViolation()) {
210       URL[] urls = { new URL(dirUrl) };
211       URLClassLoader cl =  new URLClassLoader(urls);
212
213       String resClass1 = pkg + "/Class1.class";
214       URL url = cl.findResource(resClass1);
215       String expectedUrl = dirUrl + "/" + resClass1;
216       assertEquals(url.toString(), expectedUrl);
217
218       String resInterface1 = pkg + "/Interface1.class";
219       url = cl.findResource(resInterface1);
220       expectedUrl = dirUrl + "/" + resInterface1;
221       assertEquals(url.toString(), expectedUrl);
222
223       url = cl.findResource("non_existence_resource");
224       assertNull(url);
225
226       url = cl.findResource("java/lang/Class.class");
227       assertNull(url);
228
229       // create a url from jar
230       urls[0] = new URL(jarUrl);
231       cl =  new URLClassLoader(urls);
232       url = cl.findResource(resClass1);
233       expectedUrl = jarUrl + resClass1;
234       assertEquals(url.toString(), expectedUrl);
235
236       url = cl.findResource(resInterface1);
237       expectedUrl = jarUrl + resInterface1;
238       assertEquals(url.toString(), expectedUrl);
239
240       url = cl.findResource("non_existence_resource");
241       assertNull(url);
242
243       url = cl.findResource("java/lang/Class.class");
244       assertNull(url);
245     }
246     movePkgBack();
247   }
248
249   @Test
250   public void testFindResources() throws IOException {
251     movePkgOut();
252     if (verifyNoPropertyViolation()) {
253       URL[] urls = { new URL(dirUrl), new URL(jarUrl), new URL(jarUrl) };
254       URLClassLoader cl =  new URLClassLoader(urls);
255       String resource = pkg + "/Class1.class";
256       Enumeration<URL> e = cl.findResources(resource);
257
258       List<String> urlList = new ArrayList<String>();
259       while(e.hasMoreElements()) {
260         urlList.add(e.nextElement().toString());
261       }
262
263       assertTrue(urlList.contains(jarUrl + resource));
264       assertTrue(urlList.contains(dirUrl + "/" + resource));
265
266       // we added the same url path twice, but findResource return value should only 
267       // include one entry for the same resource
268       assertEquals(urlList.size(), 2);
269
270       e = cl.findResources(null);
271       assertNotNull(e);
272       assertFalse(e.hasMoreElements());
273     }
274     movePkgBack();
275   }
276
277   @Test
278   public void testGetURLs() throws MalformedURLException {
279     if (verifyNoPropertyViolation()) {
280       URL[] urls = new URL[5];
281       urls[0] = new URL("file://" + "/x/y/z/" );
282       urls[1] = new URL("file://" + "/a/b/c/" );
283       urls[2] = new URL("file://" + "/a/b/c/" );
284       urls[3] = new URL(dirUrl);;
285       urls[4] = new URL(jarUrl);
286
287       URLClassLoader cl =  new URLClassLoader(urls);
288       URL[] clUrls = cl.getURLs();
289
290       assertEquals(clUrls.length, urls.length);
291       for (int i=0; i<urls.length; i++) {
292         assertEquals(clUrls[i], urls[i]);
293       }
294     }
295   }
296
297   @Test
298   public void testNewInstance1() throws MalformedURLException, ClassNotFoundException {
299     movePkgOut();
300     if (verifyNoPropertyViolation()) {
301       URL[] urls = new URL[1];
302       urls[0] = new URL(dirUrl);
303       URLClassLoader cl =  URLClassLoader.newInstance(urls);
304       Class<?> c = cl.loadClass(pkg + ".Class1");
305       assertNotNull(c);
306       assertSame(c.getClassLoader(), cl);
307       URL resource = cl.getResource(pkg + "/Interface1.class");
308       assertNotNull(resource);
309     }
310     movePkgBack();
311   }
312
313   @Test
314   public void testNewInstance2() throws MalformedURLException, ClassNotFoundException {
315     movePkgOut();
316     if (verifyNoPropertyViolation()) {
317       URL[] urls = new URL[1];
318       urls[0] = new URL(dirUrl);
319       URLClassLoader parent =  URLClassLoader.newInstance(urls);
320       URLClassLoader cl =  URLClassLoader.newInstance(urls, parent);
321       assertSame(parent, cl.getParent());
322
323       Class<?> c = cl.loadClass(pkg + ".Class1");
324       assertNotNull(c);
325       assertSame(c.getClassLoader(), parent);
326
327       String resName = pkg + "/Interface1.class";
328       URL resource = cl.getResource(resName);
329       assertNotNull(resource);
330
331       resource = cl.getParent().getResource(resName);
332       assertNotNull(resource);
333     }
334     movePkgBack();
335   }
336
337   public class Standard extends URLClassLoader {
338     public Standard (URL[] urls) {
339       super(urls);
340     }
341
342     public Standard(URL[] urls, ClassLoader parent) {
343       super(urls, parent);
344     }
345   }
346
347   public class Custom extends URLClassLoader {
348     public Custom (URL[] urls) {
349       super(urls);
350     }
351     
352     public Custom(URL[] urls, ClassLoader parent) {
353       super(urls, parent);
354     }
355     
356     @Override
357         protected Class<?> findClass(String name) throws ClassNotFoundException {
358       return super.findClass(name);
359     }
360     
361     @Override
362         public Class<?> loadClass(String name) throws ClassNotFoundException {
363       return super.loadClass(name);
364     }
365   }
366     
367   @Test
368   public void testClassResolution() throws MalformedURLException, ClassNotFoundException {
369     movePkgOut();
370     if (verifyNoPropertyViolation()) {
371       // create a url from a dir
372       URL[] urls = { new URL(dirUrl) };
373       String cname = pkg + ".Class1";
374       String objClass = "java.lang.Object";
375
376       Standard cl1 = new Standard(new URL[0]);
377       Standard cl2 = new Standard(urls, cl1);
378       Standard cl3 =  new Standard(urls, cl2);
379
380       Class<?> c = cl3.loadClass(cname);
381       assertEquals(c.getClassLoader(), cl2);
382
383       c = cl3.loadClass(objClass);
384       assertEquals(c.getClassLoader(), ClassLoader.getSystemClassLoader());
385
386       Custom cl4 = new Custom(urls, null);
387       Standard cl5 = new Standard(urls, cl4);
388
389       c = cl5.loadClass(cname);  // delegates to cl4 (Custom)
390       assertEquals(c.getClassLoader(), cl4);
391       
392       Class<?> c4 = cl4.loadClass(cname);
393       assertSame(c, c4);
394
395       c = cl5.loadClass(objClass);
396       assertEquals(c.getClassLoader(), ClassLoader.getSystemClassLoader());
397       assertSame(c, cl4.loadClass(objClass));
398
399       cl4 = new Custom(urls, cl3);
400       cl5 = new Standard(urls, cl4);
401
402       c = cl5.loadClass(cname);
403       assertEquals(c.getClassLoader(), cl2);
404       assertSame(c, cl4.loadClass(cname));
405
406       c = cl5.loadClass(objClass);
407       assertEquals(c.getClassLoader(), ClassLoader.getSystemClassLoader());
408       assertSame(c, cl4.loadClass(objClass));
409     }
410     movePkgBack();
411   }
412
413   @Test
414   public void testFindSystemClass() throws MalformedURLException, ClassNotFoundException {
415     movePkgOut();
416     if (verifyNoPropertyViolation()) {
417       URL[] urls = { new URL(dirUrl) };
418       TestClassLoader loader = new TestClassLoader(urls);
419       assertNotNull(loader.delegateTofindSystemClass("java.lang.Class"));
420
421       String cname = pkg + ".Class1";
422       assertNotNull(loader.loadClass(cname));
423
424       try {
425         loader.delegateTofindSystemClass(cname);
426       } catch(ClassNotFoundException e) {
427         
428       }
429     }
430     movePkgBack();
431   }
432
433   @Test
434   public void testFindSystemClass_ClassNotFoundException() throws MalformedURLException, ClassNotFoundException {
435     movePkgOut();
436     if (verifyUnhandledException("java.lang.ClassNotFoundException")) {
437       URL[] urls = { new URL(dirUrl) };
438       TestClassLoader cl = new TestClassLoader(urls);
439       String cname = pkg + ".Class1";
440
441       // this should fail, cause our SystemClassLoader cannot find a non-standard 
442       // class that is not on the classpath
443       cl.delegateTofindSystemClass(cname);
444     }
445     movePkgBack();
446   }
447
448   @Test
449   public void testGetPackages() throws ClassNotFoundException, MalformedURLException {
450     movePkgOut();
451     if(verifyNoPropertyViolation()) {
452       URL[] urls = { new URL(dirUrl) };
453       TestClassLoader cl = new TestClassLoader(urls);
454       Package[] pkgs = cl.getPackages();
455
456       boolean java_lang = false;
457       boolean classloader_specific_tests = false;
458       for(int i=0; i<pkgs.length; i++) {
459         if(pkgs[i].getName().equals("java.lang")) {
460           java_lang = true;
461         } else if(pkgs[i].getName().equals("classloader_specific_tests")) {
462           classloader_specific_tests = true;
463         }
464       }
465       assertTrue(java_lang && !classloader_specific_tests);
466
467       String cname = pkg + ".Class1";
468       cl.loadClass(cname);
469       pkgs = cl.getPackages();
470       for(int i=0; i<pkgs.length; i++) {
471         if(pkgs[i].getName().equals("java.lang")) {
472           java_lang = true;
473         } else if(pkgs[i].getName().equals("classloader_specific_tests")) {
474           classloader_specific_tests = true;
475         }
476       }
477       assertTrue(java_lang && classloader_specific_tests);
478     }
479     movePkgBack();
480   }
481
482   @Test
483   public void testGetPackage() throws ClassNotFoundException, MalformedURLException {
484     movePkgOut();
485     if(verifyNoPropertyViolation()) {
486       URL[] urls = { new URL(dirUrl) };
487       TestClassLoader cl = new TestClassLoader(urls);
488       assertNotNull(cl.getPackage("java.lang"));
489       assertNull(cl.getPackage("non_existing_package"));
490       assertNull(cl.getPackage("classloader_specific_tests"));
491
492       String cname = pkg + ".Class1";
493       cl.loadClass(cname);
494       assertNotNull(cl.getPackage("classloader_specific_tests"));
495     }
496     movePkgBack();
497   }
498
499   @Test
500   public void testThrownException() throws ClassNotFoundException, MalformedURLException, SecurityException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
501     movePkgOut();
502     if(verifyNoPropertyViolation()) {
503       URL[] urls = { new URL(dirUrl) };
504       TestClassLoader loader = new TestClassLoader(urls);
505       String cname = pkg + ".Class1";
506
507       Class<?> c = loader.loadClass(cname);
508       Method m = c.getMethod("causeArithmeticException", new Class<?>[0]);
509
510       try {
511         m.invoke(null, new Object[0]);
512         fail("Should have thrown java.lang.ArithmeticException: division by zero");
513         
514       } catch (InvocationTargetException ite) {
515         Throwable cause = ite.getCause();
516         assertTrue( cause instanceof ArithmeticException && cause.getMessage().equals("division by zero"));
517       }
518     }
519     movePkgBack();
520   }
521 }