Skip to content

Commit ea9944f

Browse files
committed
only create necessary map
1 parent e8d5ffc commit ea9944f

File tree

2 files changed

+42
-32
lines changed

2 files changed

+42
-32
lines changed

log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ClassResourceInfo.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,21 @@ final class ClassResourceInfo {
2626

2727
static final ClassResourceInfo UNKNOWN = new ClassResourceInfo();
2828

29-
private final String text;
29+
private final String exactnessPrefix;
30+
31+
private final String location;
32+
33+
private final String version;
3034

3135
final Class<?> clazz;
3236

3337
/**
3438
* Constructs an instance modelling an unknown class resource.
3539
*/
3640
private ClassResourceInfo() {
37-
this.text = "~[?:?]";
41+
this.exactnessPrefix = "~";
42+
this.location = "?";
43+
this.version = "?";
3844
this.clazz = null;
3945
}
4046

@@ -44,14 +50,9 @@ private ClassResourceInfo() {
4450
*/
4551
ClassResourceInfo(final Class<?> clazz, final boolean exact) {
4652
this.clazz = clazz;
47-
this.text = getText(clazz, exact);
48-
}
49-
50-
private static String getText(final Class<?> clazz, final boolean exact) {
51-
final String exactnessPrefix = exact ? "" : "~";
52-
final String location = getLocation(clazz);
53-
final String version = getVersion(clazz);
54-
return String.format("%s[%s:%s]", exactnessPrefix, location, version);
53+
this.exactnessPrefix = exact ? "" : "~";
54+
this.location = getLocation(clazz);
55+
this.version = getVersion(clazz);
5556
}
5657

5758
private static String getLocation(final Class<?> clazz) {
@@ -87,6 +88,6 @@ private static String getVersion(final Class<?> clazz) {
8788

8889
@Override
8990
public String toString() {
90-
return text;
91+
return String.format("%s[%s:%s]", exactnessPrefix, location, version);
9192
}
9293
}

log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowableExtendedStackTraceRenderer.java

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,20 @@
1616
*/
1717
package org.apache.logging.log4j.core.pattern;
1818

19+
import org.apache.logging.log4j.util.LoaderUtil;
20+
import org.apache.logging.log4j.util.StackLocatorUtil;
21+
1922
import java.util.ArrayDeque;
2023
import java.util.Collections;
24+
import java.util.Deque;
25+
import java.util.HashMap;
2126
import java.util.HashSet;
2227
import java.util.List;
2328
import java.util.Map;
2429
import java.util.Objects;
2530
import java.util.Queue;
2631
import java.util.Set;
27-
import java.util.stream.Collectors;
2832
import java.util.stream.Stream;
29-
import org.apache.logging.log4j.util.LoaderUtil;
30-
import org.apache.logging.log4j.util.StackLocatorUtil;
3133

3234
/**
3335
* {@link ThrowableStackTraceRenderer} variant where the rendered {@link StackTraceElement}s are enriched with the enclosing JAR file and its version information, if available.
@@ -105,12 +107,8 @@ private static Map<String, ClassResourceInfo> createClassResourceInfoByName(
105107
// But we need the associated `Class<?>` to extract its resource information, i.e., JAR file and version.
106108
// We are capturing the current stack to find suitable class loaders.
107109
// We will use this as a bootstrap to go from a class name in a stack trace to a `Class<?>`.
108-
final Map<String, ClassResourceInfo> classResourceInfoByName =
109-
StackLocatorUtil.getCurrentStackTrace().stream()
110-
.collect(Collectors.toMap(
111-
Class::getName,
112-
clazz -> new ClassResourceInfo(clazz, true),
113-
(classResourceInfo1, classResourceInfo2) -> classResourceInfo1));
110+
final Deque<Class<?>> rootStackTrace = StackLocatorUtil.getCurrentStackTrace();
111+
final Map<String, ClassResourceInfo> classResourceInfoByName = new HashMap<>();
114112

115113
// Walk over the causal chain
116114
final Set<Throwable> visitedThrowables = new HashSet<>();
@@ -130,7 +128,9 @@ private static Map<String, ClassResourceInfo> createClassResourceInfoByName(
130128
continue;
131129
}
132130

131+
Class<?> clazz = rootStackTrace.isEmpty() ? null : rootStackTrace.peekLast();
133132
ClassLoader lastLoader = null;
133+
ClassResourceInfo classResourceInfo;
134134
final StackTraceElement[] stackTraceElements = throwable.getStackTrace();
135135
for (int throwableStackIndex = metadata.stackLength - 1;
136136
throwableStackIndex >= 0;
@@ -139,20 +139,29 @@ private static Map<String, ClassResourceInfo> createClassResourceInfoByName(
139139
// Skip if the current class name is either known, or already visited and is unknown
140140
final StackTraceElement stackTraceElement = stackTraceElements[throwableStackIndex];
141141
final String stackTraceElementClassName = stackTraceElement.getClassName();
142-
ClassResourceInfo classResourceInfo = classResourceInfoByName.get(stackTraceElementClassName);
143-
if (classResourceInfo != null) {
144-
if (classResourceInfo.clazz != null) {
145-
lastLoader = classResourceInfo.clazz.getClassLoader();
142+
if (clazz != null && stackTraceElementClassName.equals(clazz.getName())) {
143+
classResourceInfo = new ClassResourceInfo(clazz, true);
144+
classResourceInfoByName.put(clazz.getName(), classResourceInfo);
145+
lastLoader = classResourceInfo.clazz.getClassLoader();
146+
rootStackTrace.pollLast();
147+
clazz = rootStackTrace.peekLast();
148+
} else {
149+
classResourceInfo = classResourceInfoByName.get(stackTraceElementClassName);
150+
if (classResourceInfo != null) {
151+
if (classResourceInfo.clazz != null) {
152+
lastLoader = classResourceInfo.clazz.getClassLoader();
153+
}
154+
} else {
155+
final Class<?> stackTraceElementClass = loadClass(lastLoader, stackTraceElementClassName);
156+
classResourceInfo = stackTraceElementClass != null
157+
? new ClassResourceInfo(stackTraceElementClass, false)
158+
: ClassResourceInfo.UNKNOWN;
159+
classResourceInfoByName.put(stackTraceElementClassName, classResourceInfo);
160+
if (classResourceInfo.clazz != null) {
161+
lastLoader = classResourceInfo.clazz.getClassLoader();
162+
}
146163
}
147-
continue;
148164
}
149-
150-
// Try to determine the stack trace element class, and register the result to the lookup table
151-
final Class<?> stackTraceElementClass = loadClass(lastLoader, stackTraceElementClassName);
152-
classResourceInfo = stackTraceElementClass != null
153-
? new ClassResourceInfo(stackTraceElementClass, false)
154-
: ClassResourceInfo.UNKNOWN;
155-
classResourceInfoByName.put(stackTraceElementClassName, classResourceInfo);
156165
}
157166
}
158167
return classResourceInfoByName;

0 commit comments

Comments
 (0)