You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by pk...@apache.org on 2022/03/29 14:05:33 UTC
[logging-log4j2] 13/25: Log4j 1.2 bridge missing some LocationInfo constructors.
This is an automated email from the ASF dual-hosted git repository.
pkarwasz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit c4ce19f4f6134ce36551ace8c9c7d65b70ea4d4f
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sat Feb 5 15:53:20 2022 -0500
Log4j 1.2 bridge missing some LocationInfo constructors.
Conflicts:
log4j-1.2-api/src/main/java/org/apache/log4j/spi/LocationInfo.java
---
.../java/org/apache/log4j/spi/LocationInfo.java | 96 +++++++++++++++++-----
.../org/apache/log4j/spi/LocationInfoTest.java | 82 ++++++++++++++++++
src/changes/changes.xml | 3 +
3 files changed, 162 insertions(+), 19 deletions(-)
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/spi/LocationInfo.java b/log4j-1.2-api/src/main/java/org/apache/log4j/spi/LocationInfo.java
index c5e5b5e..a3f2fd1 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/spi/LocationInfo.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/spi/LocationInfo.java
@@ -16,62 +16,120 @@
*/
package org.apache.log4j.spi;
+import java.io.Serializable;
+import java.util.Objects;
+
/**
* The internal representation of caller location information.
- *
+ *
* @since 0.8.3
*/
-public class LocationInfo implements java.io.Serializable {
+public class LocationInfo implements Serializable {
+
+ /**
+ * When location information is not available the constant <code>NA</code> is returned. Current value of this string
+ * constant is <b>?</b>.
+ */
+ public final static String NA = "?";
+
+ static final long serialVersionUID = -1325822038990805636L;
- private final StackTraceElement element;
+ private final StackTraceElement stackTraceElement;
public String fullInfo;
/**
- * Constructor for LocationInfo.
- * @param element The StackTraceElement representing the caller.
+ * Constructs a new instance.
*/
- public LocationInfo(StackTraceElement element) {
- this.element = element;
+ public LocationInfo(final StackTraceElement stackTraceElement) {
+ this.stackTraceElement = Objects.requireNonNull(stackTraceElement, "stackTraceElement");
+ this.fullInfo = stackTraceElement.toString();
}
/**
- * When location information is not available the constant <code>NA</code> is returned. Current value of this string
- * constant is <b>?</b>.
+ * Constructs a new instance.
+ *
+ * @param file source file name
+ * @param declaringClass class name
+ * @param methodName method
+ * @param line source line number
+ *
+ * @since 1.2.15
*/
- public final static String NA = "?";
+ public LocationInfo(final String file, final String declaringClass, final String methodName, final String line) {
+ this(new StackTraceElement(declaringClass, methodName, file, Integer.parseInt(line)));
+ }
- static final long serialVersionUID = -1325822038990805636L;
+ /**
+ * Constructs a new instance.
+ */
+ public LocationInfo(final Throwable throwable, final String fqnOfCallingClass) {
+ String declaringClass = null, methodName = null, file = null, line = null;
+ if (throwable != null && fqnOfCallingClass != null) {
+ final StackTraceElement[] elements = throwable.getStackTrace();
+ String prevClass = NA;
+ for (int i = elements.length - 1; i >= 0; i--) {
+ final String thisClass = elements[i].getClassName();
+ if (fqnOfCallingClass.equals(thisClass)) {
+ final int caller = i + 1;
+ if (caller < elements.length) {
+ declaringClass = prevClass;
+ methodName = elements[caller].getMethodName();
+ file = elements[caller].getFileName();
+ if (file == null) {
+ file = NA;
+ }
+ final int lineNo = elements[caller].getLineNumber();
+ if (lineNo < 0) {
+ line = NA;
+ } else {
+ line = String.valueOf(lineNo);
+ }
+ final StringBuilder builder = new StringBuilder();
+ builder.append(declaringClass);
+ builder.append(".");
+ builder.append(methodName);
+ builder.append("(");
+ builder.append(file);
+ builder.append(":");
+ builder.append(line);
+ builder.append(")");
+ this.fullInfo = builder.toString();
+ }
+ break;
+ }
+ prevClass = thisClass;
+ }
+ }
+ this.stackTraceElement = new StackTraceElement(declaringClass, methodName, file, Integer.parseInt(line));
+ this.fullInfo = stackTraceElement.toString();
+ }
/**
* Return the fully qualified class name of the caller making the logging request.
- @return The class name.
*/
public String getClassName() {
- return element.getClassName();
+ return stackTraceElement.getClassName();
}
/**
* Return the file name of the caller.
- @return the file name.
*/
public String getFileName() {
- return element.getFileName();
+ return stackTraceElement.getFileName();
}
/**
* Returns the line number of the caller.
- @return The line number.
*/
public String getLineNumber() {
- return Integer.toString(element.getLineNumber());
+ return Integer.toString(stackTraceElement.getLineNumber());
}
/**
* Returns the method name of the caller.
- @return The method name.
*/
public String getMethodName() {
- return element.getMethodName();
+ return stackTraceElement.getMethodName();
}
}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/spi/LocationInfoTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/spi/LocationInfoTest.java
new file mode 100644
index 0000000..a6daefc
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/spi/LocationInfoTest.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.log4j.spi;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for LocationInfo.
+ */
+public class LocationInfoTest extends TestCase {
+
+ /**
+ * Tests four parameter constructor.
+ */
+ public void testFourParamConstructor() {
+ final String className = LocationInfoTest.class.getName();
+ final String methodName = "testFourParamConstructor";
+ final String fileName = "LocationInfoTest.java";
+ final String lineNumber = "41";
+ LocationInfo li = new LocationInfo(fileName, className, methodName, lineNumber);
+ assertEquals(className, li.getClassName());
+ assertEquals(methodName, li.getMethodName());
+ assertEquals(fileName, li.getFileName());
+ assertEquals(lineNumber, li.getLineNumber());
+ assertEquals(className + "." + methodName + "(" + fileName + ":" + lineNumber + ")", li.fullInfo);
+ }
+
+ /**
+ * Class with name that is a substring of its caller.
+ */
+ private static class NameSubstring {
+ /**
+ * Construct a LocationInfo. Location should be immediate caller of this method.
+ *
+ * @return location info.
+ */
+ public static LocationInfo getInfo() {
+ return new LocationInfo(new Throwable(), NameSubstring.class.getName());
+
+ }
+ }
+
+ /**
+ * Class whose name is contains the name of the class that obtains the LocationInfo.
+ */
+ private static class NameSubstringCaller {
+ /**
+ * Construct a locationInfo. Location should be this location.
+ *
+ * @return location info.
+ */
+ public static LocationInfo getInfo() {
+ return NameSubstring.getInfo();
+ }
+
+ }
+
+ /**
+ * Tests creation of location info when the logger class name is a substring of one of the other classes in the stack
+ * trace. See bug 44888.
+ */
+ public void testLocationInfo() {
+ LocationInfo li = NameSubstringCaller.getInfo();
+ assertEquals(NameSubstringCaller.class.getName(), li.getClassName());
+ assertEquals("getInfo", li.getMethodName());
+ }
+
+}
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 7d288e7..0226b41 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -331,6 +331,9 @@
<action dev="ggregory" type="fix" due-to="Gary Gregory">
Log4j 1.2 bridge missing some ThrowableInformation constructors.
</action>
+ <action dev="ggregory" type="fix" due-to="Gary Gregory">
+ Log4j 1.2 bridge missing some LocationInfo constructors.
+ </action>
<action dev="ggregory" type="fix">
JndiManager reverts to 2.17.0 behavior: Read the system property for each call.
</action>