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