Repository: logging-log4j2 Updated Branches: refs/heads/master e5c8122bc -> 500a5aea9
Fix stack locator calc location on JDK 9 This commit fixes a bug in StackLocator#calcLocation on JDK 9. The particular issue here is that on JDK 9, all stack trace locations report as line 71 of StackLocatorUtil. This is due to a bug in the JDK 9 implementation of StackLocator. The bug is that instead of dropping the top frames of the stack until the first frame that matches the fully-qualified class name of the logger, the implementation would drop all frames from the top that match the fully-qualified class name of the logger. Of course, at this point in the stack trace, there would be none. The fix is to reverse the condition, that we drop all frames until we reach a frame matching the fully-qualified class name of the logger, and then drop all frames matching the fully-qualified class name of the logger. This commit also adds a test that was broken before this change and now passes. Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/02eee31c Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/02eee31c Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/02eee31c Branch: refs/heads/master Commit: 02eee31cb537c6a2a3dd192b71f5d9636ffed55e Parents: e67bf82 Author: Jason Tedor <[email protected]> Authored: Fri Sep 1 11:26:18 2017 -0400 Committer: Jason Tedor <[email protected]> Committed: Sat Sep 2 10:43:15 2017 -0400 ---------------------------------------------------------------------- .../apache/logging/log4j/util/StackLocator.java | 8 +++- .../logging/log4j/util/StackLocatorTest.java | 50 ++++++++++++++++++-- 2 files changed, 53 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/02eee31c/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/StackLocator.java ---------------------------------------------------------------------- diff --git a/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/StackLocator.java b/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/StackLocator.java index 9450fda..b0661d0 100644 --- a/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/StackLocator.java +++ b/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/StackLocator.java @@ -68,8 +68,12 @@ public class StackLocator { } public StackTraceElement calcLocation(final String fqcnOfLogger) { - return stackWalker.walk(s -> s.dropWhile(f -> f.getClassName().equals(fqcnOfLogger)). - dropWhile(f -> f.getClassName().equals(fqcnOfLogger)).findFirst()).get().toStackTraceElement(); + return stackWalker.walk( + s -> s.dropWhile(f -> !f.getClassName().equals(fqcnOfLogger)) // drop the top frames until we reach the logger + .dropWhile(f -> f.getClassName().equals(fqcnOfLogger)) // drop the logger frames + .findFirst()) + .get() + .toStackTraceElement(); } public StackTraceElement getStackTraceElement(final int depth) { http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/02eee31c/log4j-api-java9/src/test/java/org/apache/logging/log4j/util/StackLocatorTest.java ---------------------------------------------------------------------- diff --git a/log4j-api-java9/src/test/java/org/apache/logging/log4j/util/StackLocatorTest.java b/log4j-api-java9/src/test/java/org/apache/logging/log4j/util/StackLocatorTest.java index bcf4d74..77396c9 100644 --- a/log4j-api-java9/src/test/java/org/apache/logging/log4j/util/StackLocatorTest.java +++ b/log4j-api-java9/src/test/java/org/apache/logging/log4j/util/StackLocatorTest.java @@ -16,14 +16,17 @@ */ package org.apache.logging.log4j.util; -import java.util.Stack; - import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.BlockJUnit4ClassRunner; import org.junit.runners.ParentRunner; -import static org.junit.Assert.*; + +import java.util.Stack; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; @RunWith(BlockJUnit4ClassRunner.class) public class StackLocatorTest { @@ -91,6 +94,47 @@ public class StackLocatorTest { assertEquals("Incorrect class", this.getClass(), clazz); } + private final class Foo { + + private StackTraceElement foo() { + return new Bar().bar(); + } + + } + + private final class Bar { + + private StackTraceElement bar() { + return baz(); + } + + private StackTraceElement baz() { + return quux(); + } + + } + + private StackTraceElement quux() { + return stackLocator.calcLocation("org.apache.logging.log4j.util.StackLocatorTest$Bar"); + } + + @Test + public void testCalcLocation() { + /* + * We are setting up a stack trace that looks like: + * - org.apache.logging.log4j.util.StackLocatorTest#quux(line:118) + * - org.apache.logging.log4j.util.StackLocatorTest$Bar#baz(line:112) + * - org.apache.logging.log4j.util.StackLocatorTest$Bar#bar(line:108) + * - org.apache.logging.log4j.util.StackLocatorTest$Foo(line:100) + * + * We are pretending that org.apache.logging.log4j.util.StackLocatorTest$Bar is the logging class, and + * org.apache.logging.log4j.util.StackLocatorTest$Foo is where the log line emanated. + */ + final StackTraceElement element = new Foo().foo(); + assertEquals("org.apache.logging.log4j.util.StackLocatorTest$Foo", element.getClassName()); + assertEquals(100, element.getLineNumber()); + } + class ClassLocator { public Class<?> locateClass() {
