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 }