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