Skip to content

Commit 6dafba3

Browse files
committed
Add test and use older API
Turns out Android doesn't support Java 8 all that much.
1 parent 8255ffa commit 6dafba3

File tree

3 files changed

+81
-42
lines changed

3 files changed

+81
-42
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to you under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.logging.log4j.util;
18+
19+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
20+
import static org.junit.jupiter.api.Assertions.assertFalse;
21+
22+
import java.security.Permission;
23+
import org.apache.logging.log4j.test.junit.SecurityManagerTestRule;
24+
import org.junit.Rule;
25+
import org.junit.Test;
26+
import org.junit.jupiter.api.parallel.ResourceLock;
27+
28+
@ResourceLock("java.lang.SecurityManager")
29+
public class LoaderUtilSecurityManagerTest {
30+
@Rule
31+
public final SecurityManagerTestRule rule = new SecurityManagerTestRule(new TestSecurityManager());
32+
33+
private static class TestSecurityManager extends SecurityManager {
34+
@Override
35+
public void checkPermission(final Permission perm) {
36+
if (perm.equals(LoaderUtil.GET_CLASS_LOADER)) {
37+
throw new SecurityException("disabled");
38+
}
39+
}
40+
}
41+
42+
@Test
43+
public void canGetClassLoaderThroughPrivileges() {
44+
assertFalse(LoaderUtil.GET_CLASS_LOADER_DISABLED);
45+
assertDoesNotThrow(() -> LoaderUtil.getClassLoader(LoaderUtilSecurityManagerTest.class, String.class));
46+
}
47+
}

log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java

Lines changed: 29 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -50,36 +50,31 @@ public final class LoaderUtil {
5050
// wants to use PropertiesUtil, but then PropertiesUtil wants to use LoaderUtil.
5151
private static Boolean ignoreTCCL;
5252

53-
private static final RuntimePermission GET_CLASS_LOADER = new RuntimePermission("getClassLoader");
54-
private static final boolean GET_CLASS_LOADER_DISABLED;
55-
56-
private static final PrivilegedAction<ClassLoader> TCCL_GETTER = new ThreadContextClassLoaderGetter();
57-
58-
static {
59-
if (System.getSecurityManager() != null) {
60-
boolean getClassLoaderDisabled;
53+
static final RuntimePermission GET_CLASS_LOADER = new RuntimePermission("getClassLoader");
54+
static final LazyBoolean GET_CLASS_LOADER_DISABLED = new LazyBoolean(() -> {
55+
if (System.getSecurityManager() == null) {
56+
return false;
57+
}
58+
try {
59+
AccessController.checkPermission(GET_CLASS_LOADER);
60+
// seems like we'll be ok
61+
return false;
62+
} catch (final SecurityException ignored) {
6163
try {
62-
AccessController.checkPermission(GET_CLASS_LOADER);
63-
// seems like we'll be ok
64-
getClassLoaderDisabled = false;
65-
} catch (final SecurityException ignored) {
66-
try {
67-
// let's see if we can obtain that permission
68-
runPrivilegedActionWithGetClassLoaderPermission((PrivilegedAction<Void>) () -> {
69-
AccessController.checkPermission(GET_CLASS_LOADER);
70-
return null;
71-
});
72-
getClassLoaderDisabled = false;
73-
} catch (final SecurityException ignore) {
74-
// no chance
75-
getClassLoaderDisabled = true;
76-
}
64+
// let's see if we can obtain that permission
65+
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
66+
AccessController.checkPermission(GET_CLASS_LOADER);
67+
return null;
68+
});
69+
return false;
70+
} catch (final SecurityException ignore) {
71+
// no chance
72+
return true;
7773
}
78-
GET_CLASS_LOADER_DISABLED = getClassLoaderDisabled;
79-
} else {
80-
GET_CLASS_LOADER_DISABLED = false;
8174
}
82-
}
75+
});
76+
77+
private static final PrivilegedAction<ClassLoader> TCCL_GETTER = new ThreadContextClassLoaderGetter();
8378

8479
private LoaderUtil() {}
8580

@@ -97,15 +92,15 @@ public static ClassLoader getClassLoader(final Class<?> class1, final Class<?> c
9792
PrivilegedAction<ClassLoader> action = () -> {
9893
final ClassLoader loader1 = class1 == null ? null : class1.getClassLoader();
9994
final ClassLoader loader2 = class2 == null ? null : class2.getClassLoader();
100-
final ClassLoader referenceLoader = GET_CLASS_LOADER_DISABLED
95+
final ClassLoader referenceLoader = GET_CLASS_LOADER_DISABLED.getAsBoolean()
10196
? getThisClassLoader()
10297
: Thread.currentThread().getContextClassLoader();
10398
if (isChild(referenceLoader, loader1)) {
10499
return isChild(referenceLoader, loader2) ? referenceLoader : loader2;
105100
}
106101
return isChild(loader1, loader2) ? loader1 : loader2;
107102
};
108-
return runActionInvolvingGetClassLoaderPermission(action);
103+
return runPrivileged(action);
109104
}
110105

111106
/**
@@ -141,9 +136,7 @@ private static boolean isChild(final ClassLoader loader1, final ClassLoader load
141136
*/
142137
public static ClassLoader getThreadContextClassLoader() {
143138
try {
144-
return GET_CLASS_LOADER_DISABLED
145-
? getThisClassLoader()
146-
: runActionInvolvingGetClassLoaderPermission(TCCL_GETTER);
139+
return GET_CLASS_LOADER_DISABLED.getAsBoolean() ? getThisClassLoader() : runPrivileged(TCCL_GETTER);
147140
} catch (final SecurityException ignored) {
148141
return null;
149142
}
@@ -153,14 +146,8 @@ private static ClassLoader getThisClassLoader() {
153146
return LoaderUtil.class.getClassLoader();
154147
}
155148

156-
private static <T> T runActionInvolvingGetClassLoaderPermission(final PrivilegedAction<T> action) {
157-
return System.getSecurityManager() != null
158-
? runPrivilegedActionWithGetClassLoaderPermission(action)
159-
: action.run();
160-
}
161-
162-
private static <T> T runPrivilegedActionWithGetClassLoaderPermission(final PrivilegedAction<T> action) {
163-
return AccessController.doPrivileged(action, null, GET_CLASS_LOADER);
149+
private static <T> T runPrivileged(final PrivilegedAction<T> action) {
150+
return System.getSecurityManager() != null ? AccessController.doPrivileged(action) : action.run();
164151
}
165152

166153
private static class ThreadContextClassLoaderGetter implements PrivilegedAction<ClassLoader> {
@@ -171,7 +158,7 @@ public ClassLoader run() {
171158
return contextClassLoader;
172159
}
173160
final ClassLoader thisClassLoader = getThisClassLoader();
174-
if (thisClassLoader != null || GET_CLASS_LOADER_DISABLED) {
161+
if (thisClassLoader != null || GET_CLASS_LOADER_DISABLED.getAsBoolean()) {
175162
return thisClassLoader;
176163
}
177164
return ClassLoader.getSystemClassLoader();
@@ -476,7 +463,7 @@ static Collection<UrlResource> findUrlResources(final String resource, final boo
476463
final ClassLoader[] candidates = {
477464
useTccl ? getThreadContextClassLoader() : null,
478465
LoaderUtil.class.getClassLoader(),
479-
GET_CLASS_LOADER_DISABLED ? null : ClassLoader.getSystemClassLoader()
466+
GET_CLASS_LOADER_DISABLED.getAsBoolean() ? null : ClassLoader.getSystemClassLoader()
480467
};
481468
// @formatter:on
482469
final Collection<UrlResource> resources = new LinkedHashSet<>();

src/site/_release-notes/_2.x.x.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ This releases contains ...
3838
3939
* Deprecated the `RingBufferLogEventHandler` class for removal from the public API in 3.x.
4040
41+
[#release-notes-2-x-x-fixed]
42+
=== Fixed
43+
44+
* Fixed use of `SecurityManager` in `LoaderUtil` where `AccessController::doPrivileged` should only be invoked when a `SecurityManager` is installed. Some runtimes do not seem to have this method available. (https://github.com/apache/logging-log4j2/issues/2129[2129])
45+
4146
[#release-notes-2-x-x-updated]
4247
=== Updated
4348

0 commit comments

Comments
 (0)