View Javadoc
1   package com.atlassian.plugin.util;
2   
3   import com.atlassian.plugin.test.PluginJarBuilder;
4   import junit.framework.TestCase;
5   import org.apache.commons.io.IOUtils;
6   
7   import java.io.IOException;
8   import java.net.URL;
9   import java.net.URLClassLoader;
10  import java.util.Enumeration;
11  import java.util.HashMap;
12  import java.util.Map;
13  
14  import static java.util.Collections.singletonMap;
15  
16  /**
17   *
18   */
19  public class TestChainingClassLoader extends TestCase {
20      public void testLoadClassInFirst() throws Exception {
21          final ClassLoader cl1 = new PluginJarBuilder().addFormattedJava("my.Foo", "package my; public class Foo {}").getClassLoader();
22          final ClassLoader cl2 = new PluginJarBuilder().getClassLoader();
23  
24          assertEquals(cl1, new ChainingClassLoader(cl1, cl2).loadClass("my.Foo").getClassLoader());
25      }
26  
27      public void testLoadClassInSecond() throws Exception {
28          final ClassLoader cl1 = new PluginJarBuilder().getClassLoader();
29          final ClassLoader cl2 = new PluginJarBuilder().addFormattedJava("my.Foo", "package my; public class Foo {}").getClassLoader();
30  
31          assertEquals(cl2, new ChainingClassLoader(cl1, cl2).loadClass("my.Foo").getClassLoader());
32      }
33  
34      public void testLoadClassInFirstHidesSecond() throws Exception {
35          final ClassLoader cl1 = new PluginJarBuilder().addFormattedJava("my.Foo", "package my; public class Foo {}").getClassLoader();
36          final ClassLoader cl2 = new PluginJarBuilder().addFormattedJava("my.Foo", "package my; public class Foo {}").getClassLoader();
37  
38          assertEquals(cl1, new ChainingClassLoader(cl1, cl2).loadClass("my.Foo").getClassLoader());
39      }
40  
41      public void testLoadResourceInFirst() throws Exception {
42          ClassLoader cl1 = buildClassLoaderWithResources(new HashMap<String, String>() {{
43              put("my/foo.txt", "foo");
44          }});
45          ClassLoader cl2 = buildClassLoaderWithResources(new HashMap<String, String>() {{
46          }});
47          ChainingClassLoader ccl = new ChainingClassLoader(cl1, cl2);
48          assertEquals("foo", IOUtils.readLines(ccl.getResourceAsStream("my/foo.txt")).get(0));
49      }
50  
51      public void testLoadResourceInSecond() throws Exception {
52          ClassLoader cl1 = buildClassLoaderWithResources(new HashMap<String, String>() {{
53          }});
54          ClassLoader cl2 = buildClassLoaderWithResources(new HashMap<String, String>() {{
55              put("my/foo.txt", "foo");
56          }});
57          ChainingClassLoader ccl = new ChainingClassLoader(cl1, cl2);
58          assertEquals("foo", IOUtils.readLines(ccl.getResourceAsStream("my/foo.txt")).get(0));
59      }
60  
61      public void testLoadResourceInFirstHidesSecond() throws Exception {
62          ClassLoader cl1 = buildClassLoaderWithResources(new HashMap<String, String>() {{
63              put("my/foo.txt", "foo");
64          }});
65          ClassLoader cl2 = buildClassLoaderWithResources(new HashMap<String, String>() {{
66              put("my/foo.txt", "bar");
67          }});
68          ChainingClassLoader ccl = new ChainingClassLoader(cl1, cl2);
69          assertEquals("foo", IOUtils.readLines(ccl.getResourceAsStream("my/foo.txt")).get(0));
70      }
71  
72      public void testLoadResources() throws Exception {
73          ClassLoader cl1 = buildClassLoaderWithResources(new HashMap<String, String>() {{
74              put("my/foo.txt", "foo");
75          }});
76          ClassLoader cl2 = buildClassLoaderWithResources(new HashMap<String, String>() {{
77              put("my/foo.txt", "bar");
78          }});
79          ChainingClassLoader ccl = new ChainingClassLoader(cl1, cl2);
80          Enumeration<URL> e = ccl.getResources("my/foo.txt");
81          assertEquals("foo", IOUtils.readLines(e.nextElement().openStream()).get(0));
82          assertEquals("bar", IOUtils.readLines(e.nextElement().openStream()).get(0));
83      }
84  
85      public void testLoadResourceWithNameOverride() throws Exception {
86          ClassLoader cl1 = buildClassLoaderWithResources(new HashMap<String, String>() {{
87              put("my/foo.txt", "foo");
88              put("my/bar.txt", "bar");
89          }});
90          ClassLoader cl2 = buildClassLoaderWithResources(new HashMap<String, String>() {{
91          }});
92          ChainingClassLoader ccl = new ChainingClassLoader(singletonMap("my/bar.txt", "my/foo.txt"), cl1, cl2);
93          assertEquals("foo", IOUtils.readLines(ccl.getResourceAsStream("my/bar.txt")).get(0));
94          assertEquals("foo", IOUtils.readLines(ccl.getResourceAsStream("my/foo.txt")).get(0));
95      }
96  
97      public void testLoadClassOnlyInChainedClassloaders() throws Exception {
98          ClassLoader cl1 = new PluginJarBuilder().
99                  getClassLoader();
100         ClassLoader cl2 = new PluginJarBuilder().
101                 getClassLoader();
102         ChainingClassLoader ccl = new ChainingClassLoader(cl1, cl2);
103         assertEquals(cl1, ccl.loadClass(getClass().getName()).getClassLoader());
104     }
105 
106     private URLClassLoader buildClassLoaderWithResources(Map<String, String> files)
107             throws IOException {
108         PluginJarBuilder builder = new PluginJarBuilder();
109         for (Map.Entry<String, String> entry : files.entrySet()) {
110             builder.addResource(entry.getKey(), entry.getValue());
111         }
112         return new URLClassLoader(new URL[]{builder.build().toURI().toURL()}, null);
113     }
114 }