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  {
21      public void testLoadClassInFirst() throws Exception
22      {
23          ClassLoader cl1 = new PluginJarBuilder().
24                  addFormattedJava("my.Foo", "package my; public class Foo {}").
25                  getClassLoader();
26          ClassLoader cl2 = new PluginJarBuilder().
27                  getClassLoader();
28          ChainingClassLoader ccl = new ChainingClassLoader(cl1, cl2);
29          assertEquals(cl1, ccl.loadClass("my.Foo").getClassLoader());
30      }
31  
32      public void testLoadClassInSecond() throws Exception
33      {
34          ClassLoader cl1 = new PluginJarBuilder().
35                  getClassLoader();
36          ClassLoader cl2 = new PluginJarBuilder().
37                  addFormattedJava("my.Foo", "package my; public class Foo {}").
38                  getClassLoader();
39          ChainingClassLoader ccl = new ChainingClassLoader(cl1, cl2);
40          assertEquals(cl2, ccl.loadClass("my.Foo").getClassLoader());
41      }
42  
43      public void testLoadClassInFirstHidesSecond() throws Exception
44      {
45          ClassLoader cl1 = new PluginJarBuilder().
46                  addFormattedJava("my.Foo", "package my; public class Foo {}").
47                  getClassLoader();
48          ClassLoader cl2 = new PluginJarBuilder().
49                  addFormattedJava("my.Foo", "package my; public class Foo {}").
50                  getClassLoader();
51          ChainingClassLoader ccl = new ChainingClassLoader(cl1, cl2);
52          assertEquals(cl1, ccl.loadClass("my.Foo").getClassLoader());
53      }
54  
55      public void testLoadResourceInFirst() throws Exception
56      {
57          ClassLoader cl1 = buildClassLoaderWithResources(new HashMap<String,String>() {{
58              put("my/foo.txt", "foo");
59          }});
60          ClassLoader cl2 = buildClassLoaderWithResources(new HashMap<String,String>() {{
61          }});
62          ChainingClassLoader ccl = new ChainingClassLoader(cl1, cl2);
63          assertEquals("foo", IOUtils.readLines(ccl.getResourceAsStream("my/foo.txt")).get(0));
64      }
65  
66      public void testLoadResourceInSecond() throws Exception
67      {
68          ClassLoader cl1 = buildClassLoaderWithResources(new HashMap<String,String>() {{
69          }});
70          ClassLoader cl2 = buildClassLoaderWithResources(new HashMap<String,String>() {{
71              put("my/foo.txt", "foo");
72          }});
73          ChainingClassLoader ccl = new ChainingClassLoader(cl1, cl2);
74          assertEquals("foo", IOUtils.readLines(ccl.getResourceAsStream("my/foo.txt")).get(0));
75      }
76  
77      public void testLoadResourceInFirstHidesSecond() throws Exception
78      {
79          ClassLoader cl1 = buildClassLoaderWithResources(new HashMap<String,String>() {{
80              put("my/foo.txt", "foo");
81          }});
82          ClassLoader cl2 = buildClassLoaderWithResources(new HashMap<String,String>() {{
83              put("my/foo.txt", "bar");
84          }});
85          ChainingClassLoader ccl = new ChainingClassLoader(cl1, cl2);
86          assertEquals("foo", IOUtils.readLines(ccl.getResourceAsStream("my/foo.txt")).get(0));
87      }
88  
89      public void testLoadResources() throws Exception
90      {
91          ClassLoader cl1 = buildClassLoaderWithResources(new HashMap<String,String>() {{
92              put("my/foo.txt", "foo");
93          }});
94          ClassLoader cl2 = buildClassLoaderWithResources(new HashMap<String,String>() {{
95              put("my/foo.txt", "bar");
96          }});
97          ChainingClassLoader ccl = new ChainingClassLoader(cl1, cl2);
98          Enumeration<URL> e = ccl.getResources("my/foo.txt");
99          assertEquals("foo", IOUtils.readLines(e.nextElement().openStream()).get(0));
100         assertEquals("bar", IOUtils.readLines(e.nextElement().openStream()).get(0));
101     }
102 
103     public void testLoadResourceWithNameOverride() throws Exception
104     {
105         ClassLoader cl1 = buildClassLoaderWithResources(new HashMap<String,String>() {{
106             put("my/foo.txt", "foo");
107             put("my/bar.txt", "bar");
108         }});
109         ClassLoader cl2 = buildClassLoaderWithResources(new HashMap<String,String>() {{
110         }});
111         ChainingClassLoader ccl = new ChainingClassLoader(singletonMap("my/bar.txt", "my/foo.txt"), cl1, cl2);
112         assertEquals("foo", IOUtils.readLines(ccl.getResourceAsStream("my/bar.txt")).get(0));
113         assertEquals("foo", IOUtils.readLines(ccl.getResourceAsStream("my/foo.txt")).get(0));
114     }
115 
116     public void testLoadClassOnlyInChainedClassloaders() throws Exception
117     {
118         ClassLoader cl1 = new PluginJarBuilder().
119                 getClassLoader();
120         ClassLoader cl2 = new PluginJarBuilder().
121                 getClassLoader();
122         ChainingClassLoader ccl = new ChainingClassLoader(cl1, cl2);
123         assertEquals(cl1, ccl.loadClass(getClass().getName()).getClassLoader());
124     }
125 
126     private URLClassLoader buildClassLoaderWithResources(Map<String,String> files)
127             throws IOException
128     {
129         PluginJarBuilder builder = new PluginJarBuilder();
130         for (Map.Entry<String,String> entry : files.entrySet())
131         {
132             builder.addResource(entry.getKey(), entry.getValue());
133         }
134         return new URLClassLoader(new URL[] {builder.build().toURI().toURL()}, null);
135     }
136 }