1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.logging;
18
19 import java.lang.reflect.InvocationTargetException;
20
21 import junit.framework.TestCase;
22
23
24
25
26 public class LoadTestCase extends TestCase {
27
28
29
30
31
32
33
34
35
36
37 static class AppClassLoader extends ClassLoader {
38
39 java.util.Map classes = new java.util.HashMap();
40
41 AppClassLoader(final ClassLoader parent) {
42 super(parent);
43 }
44
45 private Class<?> def(final String name) throws ClassNotFoundException {
46
47 Class<?> result = (Class<?>) classes.get(name);
48 if (result != null) {
49 return result;
50 }
51
52 try {
53
54 final ClassLoader cl = this.getClass().getClassLoader();
55 final String classFileName = name.replace('.', '/') + ".class";
56 final java.io.InputStream is = cl.getResourceAsStream(classFileName);
57 final java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
58
59 while (is.available() > 0) {
60 out.write(is.read());
61 }
62
63 final byte[] data = out.toByteArray();
64
65 result = super.defineClass(name, data, 0, data.length);
66 classes.put(name, result);
67
68 return result;
69
70 } catch (final java.io.IOException ioe) {
71
72 throw new ClassNotFoundException(name + " caused by " + ioe.getMessage());
73 }
74
75 }
76
77
78
79 @Override
80 public Class loadClass(final String name) throws ClassNotFoundException {
81
82
83 for (final String element : LOG_PCKG) {
84 if (name.startsWith(element) && !name.contains("Exception")) {
85 return def(name);
86 }
87 }
88 return super.loadClass(name);
89 }
90
91 }
92
93
94 static private String[] LOG_PCKG = {"org.apache.commons.logging",
95 "org.apache.commons.logging.impl"};
96
97 private ClassLoader origContextClassLoader;
98
99 private void execute(final Class cls) throws Exception {
100 cls.getConstructor().newInstance();
101 }
102
103
104
105
106
107 private Class reload() throws Exception {
108 Class testObjCls = null;
109 final AppClassLoader appLoader = new AppClassLoader(this.getClass().getClassLoader());
110 try {
111
112 testObjCls = appLoader.loadClass(UserClass.class.getName());
113
114 } catch (final ClassNotFoundException cnfe) {
115 throw cnfe;
116 } catch (final Throwable t) {
117 t.printStackTrace();
118 fail("AppClassLoader failed ");
119 }
120
121 assertSame("app isolated", testObjCls.getClassLoader(), appLoader);
122
123 return testObjCls;
124
125 }
126
127
128
129
130
131
132 private void setAllowFlawedContext(final Class<?> c, final String state) throws Exception {
133 final Class<?>[] params = {String.class};
134 final java.lang.reflect.Method m = c.getDeclaredMethod("setAllowFlawedContext", params);
135 m.invoke(null, state);
136 }
137
138 @Override
139 public void setUp() {
140
141 origContextClassLoader = Thread.currentThread().getContextClassLoader();
142 }
143
144 @Override
145 public void tearDown() {
146
147 Thread.currentThread().setContextClassLoader(origContextClassLoader);
148 }
149
150
151
152
153
154
155
156
157 public void testInContainer() throws Exception {
158
159
160
161
162
163
164
165
166
167 Class<?> cls = reload();
168 Thread.currentThread().setContextClassLoader(cls.getClassLoader());
169 execute(cls);
170
171
172
173
174 cls = reload();
175 Thread.currentThread().setContextClassLoader(null);
176 execute(cls);
177
178
179
180
181 cls = reload();
182 Thread.currentThread().setContextClassLoader(null);
183 try {
184 setAllowFlawedContext(cls, "false");
185 execute(cls);
186 fail("Logging config succeeded when context class loader was null!");
187 } catch (final InvocationTargetException ex) {
188 final Throwable targetException = ex.getTargetException();
189
190 if (!(targetException instanceof LogConfigurationException)) {
191 throw ex;
192 }
193 }
194
195
196
197
198
199
200
201
202 cls = reload();
203 Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
204 execute(cls);
205
206
207
208
209 cls = reload();
210 Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
211 try {
212 setAllowFlawedContext(cls, "false");
213 execute(cls);
214 fail("Error: somehow downcast a Logger loaded via system class loader"
215 + " to the Log interface loaded via a custom class loader");
216 } catch (final InvocationTargetException ex) {
217 final Throwable targetException = ex.getTargetException();
218
219 if (!(targetException instanceof LogConfigurationException)) {
220 throw ex;
221 }
222 }
223 }
224 }