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