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