1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.jxpath.util;
19
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertThrows;
22
23 import java.io.IOException;
24 import java.lang.reflect.InvocationTargetException;
25 import java.lang.reflect.Method;
26 import java.net.URL;
27
28 import org.apache.commons.io.IOUtils;
29 import org.apache.commons.jxpath.JXPathContext;
30 import org.apache.commons.jxpath.JXPathException;
31 import org.apache.commons.lang3.ArrayUtils;
32 import org.junit.jupiter.api.AfterEach;
33 import org.junit.jupiter.api.BeforeEach;
34 import org.junit.jupiter.api.Test;
35
36
37
38
39 public class ClassLoaderUtilTest {
40
41
42
43
44
45
46
47
48 private static final class TestClassLoader extends ClassLoader {
49
50 private Class<?> testCaseClass = null;
51
52 public TestClassLoader(final ClassLoader classLoader) {
53 super(classLoader);
54 }
55
56 @Override
57 public synchronized Class<?> loadClass(final String name, final boolean resolved) throws ClassNotFoundException {
58 if (EXAMPLE_CLASS_NAME.equals(name)) {
59 throw new ClassNotFoundException();
60 }
61 if (TEST_CASE_CLASS_NAME.equals(name)) {
62 if (testCaseClass == null) {
63 final URL classUrl = getParent().getResource("org/apache/commons/jxpath/util/ClassLoaderUtilTest.class");
64 byte[] clazzBytes;
65 try {
66 clazzBytes = IOUtils.toByteArray(classUrl);
67 } catch (final IOException e) {
68 throw new ClassNotFoundException(classUrl.toString(), e);
69 }
70 this.testCaseClass = this.defineClass(TEST_CASE_CLASS_NAME, clazzBytes, 0, clazzBytes.length);
71 }
72 return this.testCaseClass;
73 }
74 return getParent().loadClass(name);
75 }
76 }
77
78
79
80
81 private static final String TEST_CASE_CLASS_NAME = "org.apache.commons.jxpath.util.ClassLoaderUtilTest";
82 private static final String EXAMPLE_CLASS_NAME = "org.apache.commons.jxpath.util.ClassLoadingExampleClass";
83
84
85
86
87 public static void callExampleMessageMethodAndAssertClassNotFoundJXPathException() {
88 final JXPathContext context = JXPathContext.newContext(new Object());
89 assertThrows(JXPathException.class, () -> context.selectSingleNode(EXAMPLE_CLASS_NAME + ".getMessage()"),
90 "We should not be able to load " + EXAMPLE_CLASS_NAME + ".");
91 }
92
93
94
95
96 public static void callExampleMessageMethodAndAssertSuccess() {
97 final JXPathContext context = JXPathContext.newContext(new Object());
98 assertEquals("an example class", context.selectSingleNode(EXAMPLE_CLASS_NAME + ".getMessage()"));
99 }
100
101 private ClassLoader orginalContextClassLoader;
102
103
104
105
106
107
108
109
110 private void executeTestMethodUnderClassLoader(final ClassLoader cl, final String methodName) throws ReflectiveOperationException {
111 final Class<?> testClass = cl.loadClass(TEST_CASE_CLASS_NAME);
112 final Method testMethod = testClass.getMethod(methodName, ArrayUtils.EMPTY_CLASS_ARRAY);
113 try {
114 testMethod.invoke(null, (Object[]) null);
115 } catch (final InvocationTargetException e) {
116 if (e.getCause() instanceof RuntimeException) {
117
118 throw (RuntimeException) e.getCause();
119 }
120 }
121 }
122
123
124
125
126 @BeforeEach
127 public void setUp() {
128 this.orginalContextClassLoader = Thread.currentThread().getContextClassLoader();
129 }
130
131
132
133
134 @AfterEach
135 public void tearDown() {
136 Thread.currentThread().setContextClassLoader(this.orginalContextClassLoader);
137 }
138
139
140
141
142
143
144 @Test
145 public void testClassLoadFailWithoutContextClassLoader() throws ReflectiveOperationException {
146 Thread.currentThread().setContextClassLoader(null);
147 final ClassLoader cl = new TestClassLoader(getClass().getClassLoader());
148 executeTestMethodUnderClassLoader(cl, "callExampleMessageMethodAndAssertClassNotFoundJXPathException");
149 }
150
151
152
153
154
155
156 @Test
157 public void testClassLoadSuccessWithContextClassLoader() throws ReflectiveOperationException {
158 Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
159 final ClassLoader cl = new TestClassLoader(getClass().getClassLoader());
160 executeTestMethodUnderClassLoader(cl, "callExampleMessageMethodAndAssertSuccess");
161 }
162
163
164
165
166 @Test
167 public void testClassLoadSuccessWithoutContextClassLoader() {
168 Thread.currentThread().setContextClassLoader(null);
169 callExampleMessageMethodAndAssertSuccess();
170 }
171
172
173
174
175 @Test
176 public void testCurrentClassLoaderFallback() {
177 final ClassLoader cl = new TestClassLoader(getClass().getClassLoader());
178 Thread.currentThread().setContextClassLoader(cl);
179 callExampleMessageMethodAndAssertSuccess();
180 }
181 }