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
84 for (final String element : LOG_PCKG) {
85 if (name.startsWith(element) && name.indexOf("Exception") == -1) {
86 return def(name);
87 }
88 }
89 return super.loadClass(name);
90 }
91
92 }
93
94
95 static private String[] LOG_PCKG = {"org.apache.commons.logging",
96 "org.apache.commons.logging.impl"};
97
98 private ClassLoader origContextClassLoader;
99
100 private void execute(final Class cls) throws Exception {
101 cls.getConstructor().newInstance();
102 }
103
104
105
106
107
108 private Class reload() throws Exception {
109 Class testObjCls = null;
110 final AppClassLoader appLoader = new AppClassLoader(this.getClass().getClassLoader());
111 try {
112
113 testObjCls = appLoader.loadClass(UserClass.class.getName());
114
115 } catch (final ClassNotFoundException cnfe) {
116 throw cnfe;
117 } catch (final Throwable t) {
118 t.printStackTrace();
119 fail("AppClassLoader failed ");
120 }
121
122 assertSame("app isolated", testObjCls.getClassLoader(), appLoader);
123
124 return testObjCls;
125
126 }
127
128
129
130
131
132
133 private void setAllowFlawedContext(final Class<?> c, final String state) throws Exception {
134 final Class<?>[] params = {String.class};
135 final java.lang.reflect.Method m = c.getDeclaredMethod("setAllowFlawedContext", params);
136 m.invoke(null, state);
137 }
138
139 @Override
140 public void setUp() {
141
142 origContextClassLoader = Thread.currentThread().getContextClassLoader();
143 }
144
145 @Override
146 public void tearDown() {
147
148 Thread.currentThread().setContextClassLoader(origContextClassLoader);
149 }
150
151
152
153
154
155
156
157
158 public void testInContainer() throws Exception {
159
160
161
162
163
164
165
166
167
168 Class<?> cls = reload();
169 Thread.currentThread().setContextClassLoader(cls.getClassLoader());
170 execute(cls);
171
172
173
174
175 cls = reload();
176 Thread.currentThread().setContextClassLoader(null);
177 execute(cls);
178
179
180
181
182 cls = reload();
183 Thread.currentThread().setContextClassLoader(null);
184 try {
185 setAllowFlawedContext(cls, "false");
186 execute(cls);
187 fail("Logging config succeeded when context class loader was null!");
188 } catch (final InvocationTargetException ex) {
189 final Throwable targetException = ex.getTargetException();
190
191 if (!(targetException instanceof LogConfigurationException)) {
192 throw ex;
193 }
194 }
195
196
197
198
199
200
201
202
203 cls = reload();
204 Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
205 execute(cls);
206
207
208
209
210 cls = reload();
211 Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
212 try {
213 setAllowFlawedContext(cls, "false");
214 execute(cls);
215 fail("Error: somehow downcast a Logger loaded via system class loader"
216 + " to the Log interface loaded via a custom class loader");
217 } catch (final InvocationTargetException ex) {
218 final Throwable targetException = ex.getTargetException();
219
220 if (!(targetException instanceof LogConfigurationException)) {
221 throw ex;
222 }
223 }
224 }
225 }