Repository: logging-log4j2 Updated Branches: refs/heads/master 2a300c020 -> 66ca9c8b6
LOG4J2-1688 parameterized message array may be a user-specified array (not a varargs array), so do not return it from the swap() method or its elements will be nulled out by the caller Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/66ca9c8b Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/66ca9c8b Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/66ca9c8b Branch: refs/heads/master Commit: 66ca9c8b6abde541e5ad65c289dddf52808a34f0 Parents: 2a300c0 Author: rpopma <[email protected]> Authored: Sat Nov 19 21:14:55 2016 +0900 Committer: rpopma <[email protected]> Committed: Sat Nov 19 21:14:55 2016 +0900 ---------------------------------------------------------------------- .../message/ReusableParameterizedMessage.java | 10 +-- .../core/async/Log4j2Jira1688AsyncTest.java | 1 - .../log4j/core/async/Log4j2Jira1688Test.java | 75 ++++++++++++++++++++ 3 files changed, 81 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/66ca9c8b/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableParameterizedMessage.java ---------------------------------------------------------------------- diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableParameterizedMessage.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableParameterizedMessage.java index 1ff1c04..dd42385 100644 --- a/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableParameterizedMessage.java +++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableParameterizedMessage.java @@ -82,14 +82,16 @@ public class ReusableParameterizedMessage implements ReusableMessage { // Therefore we want to avoid returning arrays with less than 10 elements. // If the vararg array is less than 10 params we just copy its content into the specified array // and return it. This helps the caller to retain a reusable array of at least 10 elements. + // NOTE: LOG4J2-1688 unearthed the use case that an application array (not a varargs array) is passed + // as the argument array. This array should not be modified, so it cannot be passed to the caller + // who will at some point null out the elements in the array). if (argCount <= emptyReplacement.length) { - // copy params into the specified replacement array and return that - System.arraycopy(varargs, 0, emptyReplacement, 0, argCount); result = emptyReplacement; } else { - result = varargs; - varargs = emptyReplacement; + result = new Object[argCount]; // LOG4J2-1688 } + // copy params into the specified replacement array and return that + System.arraycopy(varargs, 0, result, 0, argCount); } return result; } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/66ca9c8b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/Log4j2Jira1688AsyncTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/Log4j2Jira1688AsyncTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/Log4j2Jira1688AsyncTest.java index e63bb1f..27f23b0 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/Log4j2Jira1688AsyncTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/Log4j2Jira1688AsyncTest.java @@ -59,7 +59,6 @@ public class Log4j2Jira1688AsyncTest { } @Test - @Ignore("until LOG4J2-1688 is fixed") public void testLog4j2Only() throws InterruptedException { final org.apache.logging.log4j.Logger log4JLogger = LogManager.getLogger(this.getClass()); final int limit = 11; // more than unrolled varargs http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/66ca9c8b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/Log4j2Jira1688Test.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/Log4j2Jira1688Test.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/Log4j2Jira1688Test.java new file mode 100644 index 0000000..5eade5b --- /dev/null +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/Log4j2Jira1688Test.java @@ -0,0 +1,75 @@ +package org.apache.logging.log4j.core.async; + +import java.util.Arrays; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.config.ConfigurationFactory; +import org.apache.logging.log4j.core.util.Constants; +import org.apache.logging.log4j.junit.LoggerContextRule; +import org.apache.logging.log4j.spi.ExtendedLogger; +import org.apache.logging.log4j.test.appender.ListAppender; +import org.apache.logging.log4j.util.Strings; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.BlockJUnit4ClassRunner; + +/** + * Tests LOG4J2-1688 Multiple loggings of arguments are setting these arguments to null. + */ +@RunWith(BlockJUnit4ClassRunner.class) +public class Log4j2Jira1688Test { + + @BeforeClass + public static void beforeClass() { + System.setProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY, + "log4j-list.xml"); + } + + @AfterClass + public static void afterClass() { + System.setProperty(Constants.LOG4J_CONTEXT_SELECTOR, Strings.EMPTY); + } + + @Rule + public LoggerContextRule context = new LoggerContextRule("log4j-list.xml"); + private ListAppender listAppender; + + @Before + public void before() throws Exception { + listAppender = context.getListAppender("List"); + } + + private static Object[] createArray(final int size) { + final Object[] args = new Object[size]; + for (int i = 0; i < args.length; i++) { + args[i] = i; + } + return args; + } + + @Test + public void testLog4j2Only() throws InterruptedException { + final org.apache.logging.log4j.Logger log4JLogger = LogManager.getLogger(this.getClass()); + final int limit = 11; // more than unrolled varargs + final Object[] args = createArray(limit); + final Object[] originalArgs = Arrays.copyOf(args, args.length); + + listAppender.countDownLatch = new CountDownLatch(1); + ((ExtendedLogger)log4JLogger).logIfEnabled("test", Level.ERROR, null, "test {}", args); + + listAppender.countDownLatch.await(1, TimeUnit.SECONDS); + Assert.assertArrayEquals(Arrays.toString(args), originalArgs, args); + + ((ExtendedLogger)log4JLogger).logIfEnabled("test", Level.ERROR, null, "test {}", args); + Assert.assertArrayEquals(Arrays.toString(args), originalArgs, args); + } + +} \ No newline at end of file
