@@ -44,6 +44,7 @@ public final class LoaderUtil {
44
44
* @since 2.1
45
45
*/
46
46
public static final String IGNORE_TCCL_PROPERTY = "log4j.ignoreTCL" ;
47
+ public static final String FORCE_TCL_ONLY_PROPERTY = "log4j.forceTCLOnly" ;
47
48
48
49
private static final SecurityManager SECURITY_MANAGER = System .getSecurityManager ();
49
50
@@ -53,6 +54,8 @@ public final class LoaderUtil {
53
54
54
55
private static final boolean GET_CLASS_LOADER_DISABLED ;
55
56
57
+ protected static Boolean forceTcclOnly ;
58
+
56
59
private static final PrivilegedAction <ClassLoader > TCCL_GETTER = new ThreadContextClassLoaderGetter ();
57
60
58
61
static {
@@ -109,21 +112,23 @@ public static ClassLoader[] getClassLoaders() {
109
112
List <ClassLoader > classLoaders = new ArrayList <>();
110
113
ClassLoader tcl = getThreadContextClassLoader ();
111
114
classLoaders .add (tcl );
112
- ClassLoader current = LoaderUtil .class .getClassLoader ();
113
- if (current != tcl ) {
114
- classLoaders .add (current );
115
- ClassLoader parent = current .getParent ();
115
+ if (!isForceTccl ()) {
116
+ ClassLoader current = LoaderUtil .class .getClassLoader ();
117
+ if (current != tcl ) {
118
+ classLoaders .add (current );
119
+ ClassLoader parent = current .getParent ();
120
+ while (parent != null && !classLoaders .contains (parent )) {
121
+ classLoaders .add (parent );
122
+ }
123
+ }
124
+ ClassLoader parent = tcl .getParent ();
116
125
while (parent != null && !classLoaders .contains (parent )) {
117
126
classLoaders .add (parent );
127
+ parent = parent .getParent ();
128
+ }
129
+ if (!classLoaders .contains (ClassLoader .getSystemClassLoader ())) {
130
+ classLoaders .add (ClassLoader .getSystemClassLoader ());
118
131
}
119
- }
120
- ClassLoader parent = tcl .getParent ();
121
- while (parent != null && !classLoaders .contains (parent )) {
122
- classLoaders .add (parent );
123
- parent = parent .getParent ();
124
- }
125
- if (!classLoaders .contains (ClassLoader .getSystemClassLoader ())) {
126
- classLoaders .add (ClassLoader .getSystemClassLoader ());
127
132
}
128
133
return classLoaders .toArray (new ClassLoader [classLoaders .size ()]);
129
134
}
@@ -260,6 +265,21 @@ private static boolean isIgnoreTccl() {
260
265
return ignoreTCCL ;
261
266
}
262
267
268
+ private static boolean isForceTccl () {
269
+ if (forceTcclOnly == null ) {
270
+ // PropertiesUtil.getProperties() uses that code path so don't use that!
271
+ forceTcclOnly = System .getSecurityManager () == null ?
272
+ Boolean .getBoolean (FORCE_TCL_ONLY_PROPERTY ) :
273
+ AccessController .doPrivileged (new PrivilegedAction <Boolean >() {
274
+ @ Override
275
+ public Boolean run () {
276
+ return Boolean .getBoolean (FORCE_TCL_ONLY_PROPERTY );
277
+ }
278
+ });
279
+ }
280
+ return forceTcclOnly ;
281
+ }
282
+
263
283
/**
264
284
* Finds classpath {@linkplain URL resources}.
265
285
*
@@ -279,9 +299,9 @@ public static Collection<URL> findResources(final String resource) {
279
299
static Collection <UrlResource > findUrlResources (final String resource ) {
280
300
// @formatter:off
281
301
final ClassLoader [] candidates = {
282
- getThreadContextClassLoader (),
283
- LoaderUtil .class .getClassLoader (),
284
- GET_CLASS_LOADER_DISABLED ? null : ClassLoader .getSystemClassLoader ()};
302
+ getThreadContextClassLoader (),
303
+ isForceTccl () ? null : LoaderUtil .class .getClassLoader (),
304
+ isForceTccl () || GET_CLASS_LOADER_DISABLED ? null : ClassLoader .getSystemClassLoader ()};
285
305
// @formatter:on
286
306
final Collection <UrlResource > resources = new LinkedHashSet <>();
287
307
for (final ClassLoader cl : candidates ) {
0 commit comments