1 package it.com.atlassian.plugin.classloader;
2
3 import com.atlassian.plugin.classloader.PluginClassLoader;
4 import com.atlassian.plugin.test.PluginTestUtils;
5 import com.opensymphony.util.BeanUtils;
6 import junit.framework.TestCase;
7 import org.apache.commons.io.FileUtils;
8 import org.apache.commons.io.IOUtils;
9
10 import java.io.File;
11 import java.io.IOException;
12 import java.io.InputStream;
13 import java.net.URL;
14 import java.util.List;
15
16
17
18
19
20
21 public class TestPluginClassLoader extends TestCase {
22 private PluginClassLoader pluginClassLoader;
23 private File tmpDir;
24
25 protected void setUp() throws Exception {
26 super.setUp();
27 tmpDir = PluginTestUtils.createTempDirectory(TestPluginClassLoader.class);
28
29 final URL url = getClass().getClassLoader().getResource(PluginTestUtils.SIMPLE_TEST_JAR);
30 assertNotNull("Can't find test resource '" + PluginTestUtils.SIMPLE_TEST_JAR + "' -- see class Javadoc, and be sure to set the 'project.version' system property!", url);
31 pluginClassLoader = new PluginClassLoader(new File(url.toURI()), getClass().getClassLoader(), tmpDir);
32 }
33
34 protected void tearDown() throws Exception {
35 FileUtils.deleteDirectory(tmpDir);
36 super.tearDown();
37 }
38
39 public void testPluginClassLoaderFindsInnerJars() throws Exception {
40 List innerJars = pluginClassLoader.getPluginInnerJars();
41 assertEquals(2, innerJars.size());
42 }
43
44 public void testPluginClassLoaderLoadsResourceFromOuterJarFirst() throws Exception {
45 URL resourceUrl = pluginClassLoader.getResource("testresource.txt");
46 assertNotNull(resourceUrl);
47 assertEquals("outerjar", IOUtils.toString(resourceUrl.openStream()));
48 }
49
50 public void testPluginClassLoaderLoadsClassFromOuterJar() throws Exception {
51 Class c = pluginClassLoader.loadClass("com.atlassian.plugin.simpletest.TestClassOne");
52 assertEquals("com.atlassian.plugin.simpletest", c.getPackage().getName());
53 assertEquals("com.atlassian.plugin.simpletest.TestClassOne", c.getName());
54 }
55
56 public void testPluginClassLoaderHandlesDeletedExtractedInnerJars() throws Exception {
57 InputStream inputStream = pluginClassLoader.getResource("innerresource.txt").openStream();
58 assertNotNull(inputStream);
59 inputStream.close();
60 FileUtils.deleteDirectory(tmpDir);
61 assertTrue(tmpDir.mkdirs());
62 try {
63 assertNotNull(pluginClassLoader.getResource("innerresource.txt").openStream());
64 fail("underlying extracted inner jar was deleted and should throw FileNotFoundException");
65 } catch (IOException e) {
66
67 }
68 }
69
70 public void testPluginClassLoaderExtractsInnerJarsToSpecifiedDirectory() throws Exception {
71 final List<File> files = pluginClassLoader.getPluginInnerJars();
72 for (File file : files) {
73 assertEquals(tmpDir, file.getParentFile());
74 }
75 }
76
77 public void testPluginClassLoaderDetectsMissingTempDirectory() throws Exception {
78 try {
79 new PluginClassLoader(null, getClass().getClassLoader(), new File("/doesnotexisthopefully"));
80 fail("should throw IllegalArgumentException when temp directory does not exist");
81 } catch (IllegalStateException e) {
82
83 }
84 }
85
86 public void testPluginClassLoaderLoadsResourceFromInnerJarIfNotInOuterJar() throws Exception {
87 final URL resourceUrl = pluginClassLoader.getResource("innerresource.txt");
88 assertNotNull(resourceUrl);
89 InputStream inputStream = resourceUrl.openStream();
90 assertEquals("innerresource", IOUtils.toString(inputStream));
91 inputStream.close();
92 }
93
94 public void testPluginClassLoaderDoesNotSwallowClassesFromADifferentClassLoader() throws Exception {
95 final Class c = Class.forName(getClass().getName(), true, pluginClassLoader);
96 assertEquals(getClass().getClassLoader(), c.getClassLoader());
97 }
98
99 public void testPluginClassLoaderOverridesContainerClassesWithInnerJarClasses() throws Exception {
100 Class mockVersionedClass =
101 Class.forName("com.atlassian.plugin.mock.MockVersionedClass", true, pluginClassLoader);
102 Object instance = mockVersionedClass.newInstance();
103
104 assertEquals("PluginClassLoader is searching the parent classloader for classes before inner JARs",
105 2, BeanUtils.getValue(instance, "version"));
106 }
107
108 public void testPluginClassLoaderDoesNotLockTheJarsPermanently() throws Exception {
109
110 File original = new File(getClass().getClassLoader().getResource(PluginTestUtils.SIMPLE_TEST_JAR).toURI());
111 File tmpFile = new File(original.getAbsolutePath() + ".tmp");
112 FileUtils.copyFile(original, tmpFile);
113
114 PluginClassLoader pluginClassLoaderThatHasNotLockedFileYet = new
115 PluginClassLoader(tmpFile, getClass().getClassLoader());
116 Class mockVersionedClass =
117 Class.forName("com.atlassian.plugin.mock.MockVersionedClass", true, pluginClassLoader);
118 assertTrue(tmpFile.delete());
119 }
120 }