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