1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.util;
18
19 import java.io.IOException;
20 import java.lang.reflect.InvocationTargetException;
21 import java.net.URL;
22 import java.security.AccessController;
23 import java.security.PrivilegedAction;
24 import java.util.Collection;
25 import java.util.Enumeration;
26 import java.util.LinkedHashSet;
27
28
29
30
31
32
33
34
35 public final class LoaderUtil {
36 private LoaderUtil() {}
37
38
39
40
41
42
43 public static final String IGNORE_TCCL_PROPERTY = "log4j.ignoreTCL";
44
45 private static final SecurityManager SECURITY_MANAGER = System.getSecurityManager();
46
47
48
49 private static Boolean ignoreTCCL;
50
51 private static final boolean GET_CLASS_LOADER_DISABLED;
52
53 private static final PrivilegedAction<ClassLoader> TCCL_GETTER = new ThreadContextClassLoaderGetter();
54
55 static {
56 if (SECURITY_MANAGER != null) {
57 boolean getClassLoaderDisabled;
58 try {
59 SECURITY_MANAGER.checkPermission(new RuntimePermission("getClassLoader"));
60 getClassLoaderDisabled = false;
61 } catch (final SecurityException ignored) {
62 getClassLoaderDisabled = true;
63 }
64 GET_CLASS_LOADER_DISABLED = getClassLoaderDisabled;
65 } else {
66 GET_CLASS_LOADER_DISABLED = false;
67 }
68 }
69
70
71
72
73
74
75
76
77
78 public static ClassLoader getThreadContextClassLoader() {
79 if (GET_CLASS_LOADER_DISABLED) {
80
81
82 return LoaderUtil.class.getClassLoader();
83 }
84 return SECURITY_MANAGER == null
85 ? TCCL_GETTER.run()
86 : AccessController.doPrivileged(TCCL_GETTER);
87 }
88
89 private static class ThreadContextClassLoaderGetter implements PrivilegedAction<ClassLoader> {
90 @Override
91 public ClassLoader run() {
92 final ClassLoader cl = Thread.currentThread().getContextClassLoader();
93 if (cl != null) {
94 return cl;
95 }
96 final ClassLoader ccl = LoaderUtil.class.getClassLoader();
97 return ccl == null ? ClassLoader.getSystemClassLoader() : ccl;
98 }
99 }
100
101
102
103
104
105
106
107
108
109
110 public static Class<?> loadClass(final String className) throws ClassNotFoundException {
111 if (isIgnoreTccl()) {
112 return Class.forName(className);
113 }
114 try {
115 return getThreadContextClassLoader().loadClass(className);
116 } catch (final Throwable ignored) {
117 return Class.forName(className);
118 }
119 }
120
121
122
123
124
125
126
127
128
129
130
131
132
133 public static Object newInstanceOf(final String className)
134 throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException,
135 InvocationTargetException {
136 final Class<?> clazz = loadClass(className);
137 try {
138 return clazz.getConstructor().newInstance();
139 } catch (final NoSuchMethodException ignored) {
140
141 return clazz.newInstance();
142 }
143 }
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160 public static <T> T newCheckedInstanceOf(final String className, final Class<T> clazz)
161 throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException,
162 IllegalAccessException {
163 return clazz.cast(newInstanceOf(className));
164 }
165
166 private static boolean isIgnoreTccl() {
167
168 if (ignoreTCCL == null) {
169 final String ignoreTccl = PropertiesUtil.getProperties().getStringProperty(IGNORE_TCCL_PROPERTY, null);
170 ignoreTCCL = ignoreTccl != null && !"false".equalsIgnoreCase(ignoreTccl.trim());
171 }
172 return ignoreTCCL;
173 }
174
175
176
177
178
179
180
181
182 public static Collection<URL> findResources(final String resource) {
183 final Collection<UrlResource> urlResources = findUrlResources(resource);
184 final Collection<URL> resources = new LinkedHashSet<URL>(urlResources.size());
185 for (final UrlResource urlResource : urlResources) {
186 resources.add(urlResource.getUrl());
187 }
188 return resources;
189 }
190
191 static Collection<UrlResource> findUrlResources(final String resource) {
192 final ClassLoader[] candidates = {
193 getThreadContextClassLoader(),
194 LoaderUtil.class.getClassLoader(),
195 ClassLoader.getSystemClassLoader()
196 };
197 final Collection<UrlResource> resources = new LinkedHashSet<UrlResource>();
198 for (final ClassLoader cl : candidates) {
199 if (cl != null) {
200 try {
201 final Enumeration<URL> resourceEnum = cl.getResources(resource);
202 while (resourceEnum.hasMoreElements()) {
203 resources.add(new UrlResource(cl, resourceEnum.nextElement()));
204 }
205 } catch (final IOException e) {
206 e.printStackTrace();
207 }
208 }
209 }
210 return resources;
211 }
212
213
214
215
216 static class UrlResource {
217 private final ClassLoader classLoader;
218 private final URL url;
219
220 public UrlResource(final ClassLoader classLoader, final URL url) {
221 this.classLoader = classLoader;
222 this.url = url;
223 }
224
225 public ClassLoader getClassLoader() {
226 return classLoader;
227 }
228
229 public URL getUrl() {
230 return url;
231 }
232
233 @Override
234 public boolean equals(final Object o) {
235 if (this == o) {
236 return true;
237 }
238 if (o == null || getClass() != o.getClass()) {
239 return false;
240 }
241
242 final UrlResource that = (UrlResource) o;
243
244 if (classLoader != null ? !classLoader.equals(that.classLoader) : that.classLoader != null) {
245 return false;
246 }
247 if (url != null ? !url.equals(that.url) : that.url != null) {
248 return false;
249 }
250
251 return true;
252 }
253
254 @Override
255 public int hashCode() {
256 int result = classLoader != null ? classLoader.hashCode() : 0;
257 result = 31 * result + (url != null ? url.hashCode() : 0);
258 return result;
259 }
260 }
261 }