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 }