You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rp...@apache.org on 2016/09/09 17:27:55 UTC

[01/21] logging-log4j2 git commit: Fix ExtendedLevelsTest to match documentation

Repository: logging-log4j2
Updated Branches:
  refs/heads/LOG4J2-1349-gcfree-threadcontext 7c1406ce5 -> 213ad7c4f


Fix ExtendedLevelsTest to match documentation

The existing test did not use custom log levels the same way as they're documented in the manual. Confusing!


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/5cbf04fc
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/5cbf04fc
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/5cbf04fc

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: 5cbf04fcfbf5af7618665dc8080c8138ce221bff
Parents: d1e2e96
Author: Matt Sicker <bo...@gmail.com>
Authored: Thu Sep 8 09:55:24 2016 -0500
Committer: Matt Sicker <bo...@gmail.com>
Committed: Thu Sep 8 09:55:24 2016 -0500

----------------------------------------------------------------------
 .../java/org/apache/logging/log4j/test/ExtendedLevels.java    | 2 --
 log4j-core/src/test/resources/log4j-customLevel.xml           | 7 ++++++-
 2 files changed, 6 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/5cbf04fc/log4j-core/src/test/java/org/apache/logging/log4j/test/ExtendedLevels.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/test/ExtendedLevels.java b/log4j-core/src/test/java/org/apache/logging/log4j/test/ExtendedLevels.java
index cf0aaae..5002ac9 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/test/ExtendedLevels.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/test/ExtendedLevels.java
@@ -17,12 +17,10 @@
 package org.apache.logging.log4j.test;
 
 import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.core.config.plugins.Plugin;
 
 /**
  *
  */
-@Plugin(name="ExtendedLevel", category="Level")
 public class ExtendedLevels {
 
     public static final Level NOTE = Level.forName("NOTE", 350);

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/5cbf04fc/log4j-core/src/test/resources/log4j-customLevel.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/log4j-customLevel.xml b/log4j-core/src/test/resources/log4j-customLevel.xml
index a80d07d..7a9c569 100644
--- a/log4j-core/src/test/resources/log4j-customLevel.xml
+++ b/log4j-core/src/test/resources/log4j-customLevel.xml
@@ -18,6 +18,11 @@
 -->
 <Configuration status="OFF" name="XMLConfigTest">
 
+  <CustomLevels>
+    <CustomLevel name="NOTE" intLevel="350"/>
+    <CustomLevel name="DETAIL" intLevel="450"/>
+  </CustomLevels>
+
   <Appenders>
     <Console name="STDOUT">
       <PatternLayout pattern="%m%n"/>
@@ -45,4 +50,4 @@
     </Root>
   </Loggers>
 
-</Configuration>
\ No newline at end of file
+</Configuration>


[13/21] logging-log4j2 git commit: Try to fix test on Jenkins by waiting a little longer for messages to come.

Posted by rp...@apache.org.
Try to fix test on Jenkins by waiting a little longer for messages to
come.

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/099775bf
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/099775bf
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/099775bf

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: 099775bfce75e401167a714ed859e24e2c920c4b
Parents: bdd0e36
Author: Gary Gregory <gg...@apache.org>
Authored: Thu Sep 8 14:51:01 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Thu Sep 8 14:51:01 2016 -0700

----------------------------------------------------------------------
 .../org/apache/logging/log4j/core/appender/AsyncAppenderTest.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/099775bf/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
index 601ddb5..26488a5 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
@@ -39,7 +39,7 @@ import static org.junit.Assert.*;
 @RunWith(Parameterized.class)
 public class AsyncAppenderTest {
 
-    private static final int TIMEOUT_MILLIS = 1000;
+    private static final int TIMEOUT_MILLIS = 2000;
 
     @Parameterized.Parameters(name = "{0}")
     public static Object[] data() {


[05/21] logging-log4j2 git commit: Revert "Remove internal method that is @deprecated Use {@link #createLogger(boolean, Level, String, String, AppenderRef[], Property[], Configuration, Filter)}"

Posted by rp...@apache.org.
Revert "Remove internal method that is @deprecated Use {@link #createLogger(boolean, Level, String, String, AppenderRef[], Property[], Configuration, Filter)}"

This reverts commit facb281ba2f5f83903a7aedf385f83d7f9520561.


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/21581e28
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/21581e28
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/21581e28

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: 21581e28ee361316a8d02b099efc64da336b3e76
Parents: 99c0d01
Author: Gary Gregory <gg...@apache.org>
Authored: Thu Sep 8 11:50:35 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Thu Sep 8 11:50:35 2016 -0700

----------------------------------------------------------------------
 .../logging/log4j/core/config/LoggerConfig.java | 34 ++++++++++++++++++++
 1 file changed, 34 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/21581e28/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java
index eb8e671..12f8615 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java
@@ -399,6 +399,40 @@ public class LoggerConfig extends AbstractFilterable {
     /**
      * Factory method to create a LoggerConfig.
      *
+     * @param additivity True if additive, false otherwise.
+     * @param level The Level to be associated with the Logger.
+     * @param loggerName The name of the Logger.
+     * @param includeLocation whether location should be passed downstream
+     * @param refs An array of Appender names.
+     * @param properties Properties to pass to the Logger.
+     * @param config The Configuration.
+     * @param filter A Filter.
+     * @return A new LoggerConfig.
+     * @deprecated Use {@link #createLogger(boolean, Level, String, String, AppenderRef[], Property[], Configuration, Filter)}
+     */
+    @Deprecated
+    public static LoggerConfig createLogger(final String additivity,
+            final Level level, @PluginAttribute("name") final String loggerName,
+            final String includeLocation,
+            final AppenderRef[] refs,
+            final Property[] properties, @PluginConfiguration final Configuration config,
+            final Filter filter) {
+        if (loggerName == null) {
+            LOGGER.error("Loggers cannot be configured without a name");
+            return null;
+        }
+
+        final List<AppenderRef> appenderRefs = Arrays.asList(refs);
+        final String name = loggerName.equals(ROOT) ? Strings.EMPTY : loggerName;
+        final boolean additive = Booleans.parseBoolean(additivity, true);
+
+        return new LoggerConfig(name, appenderRefs, filter, level, additive, properties, config,
+                includeLocation(includeLocation));
+    }
+
+    /**
+     * Factory method to create a LoggerConfig.
+     *
      * @param additivity true if additive, false otherwise.
      * @param level The Level to be associated with the Logger.
      * @param loggerName The name of the Logger.


[06/21] logging-log4j2 git commit: Javadoc.

Posted by rp...@apache.org.
Javadoc.

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/5d796697
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/5d796697
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/5d796697

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: 5d79669753c954a57f81a74b44efc32b0567f278
Parents: 21581e2
Author: Gary Gregory <gg...@apache.org>
Authored: Thu Sep 8 11:52:28 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Thu Sep 8 11:52:28 2016 -0700

----------------------------------------------------------------------
 .../java/org/apache/logging/log4j/core/config/LoggerConfig.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/5d796697/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java
index 12f8615..886b78d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java
@@ -408,7 +408,7 @@ public class LoggerConfig extends AbstractFilterable {
      * @param config The Configuration.
      * @param filter A Filter.
      * @return A new LoggerConfig.
-     * @deprecated Use {@link #createLogger(boolean, Level, String, String, AppenderRef[], Property[], Configuration, Filter)}
+     * @deprecated Deprecated in 2.7; use {@link #createLogger(boolean, Level, String, String, AppenderRef[], Property[], Configuration, Filter)}
      */
     @Deprecated
     public static LoggerConfig createLogger(final String additivity,


[08/21] logging-log4j2 git commit: Format nits.

Posted by rp...@apache.org.
Format nits.

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/08cad980
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/08cad980
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/08cad980

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: 08cad98046a3b54de632a9b428153acf0a7a1ddd
Parents: a107355
Author: Gary Gregory <gg...@apache.org>
Authored: Thu Sep 8 11:54:29 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Thu Sep 8 11:54:29 2016 -0700

----------------------------------------------------------------------
 .../apache/logging/log4j/core/config/LoggerConfig.java    | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/08cad980/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java
index 886b78d..c7170c7 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java
@@ -412,11 +412,15 @@ public class LoggerConfig extends AbstractFilterable {
      */
     @Deprecated
     public static LoggerConfig createLogger(final String additivity,
-            final Level level, @PluginAttribute("name") final String loggerName,
+            // @formatter:off
+            final Level level, 
+            @PluginAttribute("name") final String loggerName,
             final String includeLocation,
             final AppenderRef[] refs,
-            final Property[] properties, @PluginConfiguration final Configuration config,
+            final Property[] properties, 
+            @PluginConfiguration final Configuration config,
             final Filter filter) {
+            // @formatter:on
         if (loggerName == null) {
             LOGGER.error("Loggers cannot be configured without a name");
             return null;
@@ -446,6 +450,7 @@ public class LoggerConfig extends AbstractFilterable {
      */
     @PluginFactory
     public static LoggerConfig createLogger(
+         // @formatter:off
         @PluginAttribute(value = "additivity", defaultBoolean = true) final boolean additivity,
         @PluginAttribute("level") final Level level,
         @Required(message = "Loggers cannot be configured without a name") @PluginAttribute("name") final String loggerName,
@@ -454,6 +459,7 @@ public class LoggerConfig extends AbstractFilterable {
         @PluginElement("Properties") final Property[] properties,
         @PluginConfiguration final Configuration config,
         @PluginElement("Filter") final Filter filter
+        // @formatter:on
     ) {
         final String name = loggerName.equals(ROOT) ? Strings.EMPTY : loggerName;
         return new LoggerConfig(name, Arrays.asList(refs), filter, level, additivity, properties, config,


[18/21] logging-log4j2 git commit: Better error message for IllegalArgumentException.

Posted by rp...@apache.org.
Better error message for IllegalArgumentException.

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/40fbc2a2
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/40fbc2a2
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/40fbc2a2

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: 40fbc2a20482dacddcd6bd19bb2b0d51ea6b37a6
Parents: 4d84bd5
Author: Gary Gregory <gg...@apache.org>
Authored: Fri Sep 9 08:59:52 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Fri Sep 9 08:59:52 2016 -0700

----------------------------------------------------------------------
 .../org/apache/logging/log4j/core/appender/ConsoleAppender.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/40fbc2a2/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
index 3650172..e2d9452 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
@@ -193,7 +193,7 @@ public final class ConsoleAppender extends AbstractOutputStreamAppender<OutputSt
         @Override
         public ConsoleAppender build() {
             if (follow && direct) {
-                throw new IllegalArgumentException("Cannot use both follow and direct on ConsoleAppender");
+                throw new IllegalArgumentException("Cannot use both follow and direct on ConsoleAppender '" + getName() + "'");
             }
             final Layout<? extends Serializable> layout = getOrCreateLayout();
             return new ConsoleAppender(getName(), layout, getFilter(), getManager(target, follow, direct, layout),


[21/21] logging-log4j2 git commit: Merge remote-tracking branch 'remotes/origin/master' into LOG4J2-1349-gcfree-threadcontext

Posted by rp...@apache.org.
Merge remote-tracking branch 'remotes/origin/master' into LOG4J2-1349-gcfree-threadcontext


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/213ad7c4
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/213ad7c4
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/213ad7c4

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: 213ad7c4f8efd7ce3ca89db969ef82e279818634
Parents: 7c1406c f2a07e6
Author: rpopma <rp...@apache.org>
Authored: Sat Sep 10 02:27:12 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Sat Sep 10 02:27:12 2016 +0900

----------------------------------------------------------------------
 .../log4j/core/appender/ConsoleAppender.java    |   6 +-
 .../rolling/CompositeTriggeringPolicy.java      |   5 +-
 .../appender/rolling/RollingFileManager.java    | 962 ++++++++++---------
 .../core/appender/rolling/TriggeringPolicy.java |   3 +-
 .../logging/log4j/core/config/LoggerConfig.java |  40 +
 .../logging/log4j/core/impl/ThrowableProxy.java | 282 +++---
 .../log4j/core/appender/AsyncAppenderTest.java  |  21 +-
 .../async/AsyncLoggerClassLoadDeadlock.java     |  32 +
 .../async/AsyncLoggerClassLoadDeadlockTest.java |  45 +
 .../logging/log4j/junit/LoggerContextRule.java  |  11 +
 .../logging/log4j/test/ExtendedLevels.java      |   2 +-
 .../log4j/test/appender/ListAppender.java       |  12 +
 .../test/resources/AsyncLoggerConsoleTest.xml   |  16 +
 .../src/test/resources/log4j-customLevel.xml    |   7 +-
 src/changes/changes.xml                         |   6 +-
 15 files changed, 799 insertions(+), 651 deletions(-)
----------------------------------------------------------------------



[03/21] logging-log4j2 git commit: Revert removal of @Plugin in test

Posted by rp...@apache.org.
Revert removal of @Plugin in test


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/99c0d011
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/99c0d011
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/99c0d011

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: 99c0d011d483242d9e8b98a11c621876c6cc07f1
Parents: 7c2fc7c
Author: Matt Sicker <bo...@gmail.com>
Authored: Thu Sep 8 10:13:30 2016 -0500
Committer: Matt Sicker <bo...@gmail.com>
Committed: Thu Sep 8 10:13:30 2016 -0500

----------------------------------------------------------------------
 .../test/java/org/apache/logging/log4j/test/ExtendedLevels.java    | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/99c0d011/log4j-core/src/test/java/org/apache/logging/log4j/test/ExtendedLevels.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/test/ExtendedLevels.java b/log4j-core/src/test/java/org/apache/logging/log4j/test/ExtendedLevels.java
index 5002ac9..d69433e 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/test/ExtendedLevels.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/test/ExtendedLevels.java
@@ -17,10 +17,12 @@
 package org.apache.logging.log4j.test;
 
 import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
 
 /**
  *
  */
+@Plugin(name="ExtendedLevel", category=Level.CATEGORY)
 public class ExtendedLevels {
 
     public static final Level NOTE = Level.forName("NOTE", 350);


[11/21] logging-log4j2 git commit: Use constant.

Posted by rp...@apache.org.
Use constant.

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/86a037ff
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/86a037ff
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/86a037ff

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: 86a037ffc4487cf025669c44137e3790bbf90e97
Parents: a8d52f2
Author: Gary Gregory <gg...@apache.org>
Authored: Thu Sep 8 13:25:07 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Thu Sep 8 13:25:07 2016 -0700

----------------------------------------------------------------------
 .../apache/logging/log4j/core/appender/AsyncAppenderTest.java  | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/86a037ff/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
index e4b43c7..8031909 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
@@ -38,6 +38,8 @@ import static org.junit.Assert.*;
 @RunWith(Parameterized.class)
 public class AsyncAppenderTest {
 
+    private static final int SLEEP_MILLIS = 100;
+
     @Parameterized.Parameters(name = "{0}")
     public static Object[] data() {
         return new String[]{
@@ -75,7 +77,7 @@ public class AsyncAppenderTest {
         final Logger logger = LogManager.getLogger(AsyncAppender.class);
         logger.error("This is a test");
         logger.warn("Hello world!");
-        Thread.sleep(100);
+        Thread.sleep(SLEEP_MILLIS);
         final List<String> list = listAppender.getMessages();
         assertNotNull("No events generated", list);
         assertTrue("Incorrect number of events. Expected 2, got " + list.size(), list.size() == 2);
@@ -93,7 +95,7 @@ public class AsyncAppenderTest {
         final Exception parent = new IllegalStateException("Test");
         final Throwable child = new LoggingException("This is a test", parent);
         logger.error("This is a test", child);
-        Thread.sleep(100);
+        Thread.sleep(SLEEP_MILLIS);
         final List<String> list = listAppender.getMessages();
         assertNotNull("No events generated", list);
         assertTrue("Incorrect number of events. Expected 1, got " + list.size(), list.size() == 1);


[10/21] logging-log4j2 git commit: Use config file name as JUnit test parameter name.

Posted by rp...@apache.org.
Use config file name as JUnit test parameter name.

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/a8d52f2c
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/a8d52f2c
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/a8d52f2c

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: a8d52f2c0e7d5e184b1290c8b3399cca0c4ed14f
Parents: d7cd3e3
Author: Gary Gregory <gg...@apache.org>
Authored: Thu Sep 8 13:23:46 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Thu Sep 8 13:23:46 2016 -0700

----------------------------------------------------------------------
 .../org/apache/logging/log4j/core/appender/AsyncAppenderTest.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/a8d52f2c/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
index af21d77..e4b43c7 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
@@ -38,7 +38,7 @@ import static org.junit.Assert.*;
 @RunWith(Parameterized.class)
 public class AsyncAppenderTest {
 
-    @Parameterized.Parameters
+    @Parameterized.Parameters(name = "{0}")
     public static Object[] data() {
         return new String[]{
             // default async config uses array blocking queue


[17/21] logging-log4j2 git commit: Restore binary compatibility for TriggerPolicy. Add TODO comment for 3.0.

Posted by rp...@apache.org.
Restore binary compatibility for TriggerPolicy. Add TODO comment for
3.0.

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/4d84bd58
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/4d84bd58
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/4d84bd58

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: 4d84bd581ae1c7262f1ecab25d5947a4bfdd139a
Parents: 6e79360
Author: Gary Gregory <gg...@apache.org>
Authored: Thu Sep 8 15:17:21 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Thu Sep 8 15:17:21 2016 -0700

----------------------------------------------------------------------
 .../rolling/CompositeTriggeringPolicy.java      |   5 +-
 .../appender/rolling/RollingFileManager.java    | 962 ++++++++++---------
 .../core/appender/rolling/TriggeringPolicy.java |   3 +-
 3 files changed, 488 insertions(+), 482 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4d84bd58/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/CompositeTriggeringPolicy.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/CompositeTriggeringPolicy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/CompositeTriggeringPolicy.java
index 6d49435..5e967a6 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/CompositeTriggeringPolicy.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/CompositeTriggeringPolicy.java
@@ -19,6 +19,7 @@ package org.apache.logging.log4j.core.appender.rolling;
 import java.util.Arrays;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.logging.log4j.core.LifeCycle;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
 import org.apache.logging.log4j.core.config.plugins.PluginElement;
@@ -82,7 +83,9 @@ public final class CompositeTriggeringPolicy extends AbstractTriggeringPolicy {
         setStopping();
         boolean stopped = true;
         for (final TriggeringPolicy triggeringPolicy : triggeringPolicies) {
-            stopped &= triggeringPolicy.stop(timeout, timeUnit);
+            if (triggeringPolicy instanceof LifeCycle) {
+                stopped &= ((LifeCycle) triggeringPolicy).stop(timeout, timeUnit);
+            }
         }
         setStopped();
         return stopped;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4d84bd58/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
index db6e9ae..2ec6645 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
@@ -1,479 +1,483 @@
-/*
- * 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.logging.log4j.core.appender.rolling;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.nio.ByteBuffer;
-import java.util.concurrent.Future;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
-
-import org.apache.logging.log4j.core.Layout;
-import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.core.appender.ConfigurationFactoryData;
-import org.apache.logging.log4j.core.appender.FileManager;
-import org.apache.logging.log4j.core.appender.ManagerFactory;
-import org.apache.logging.log4j.core.appender.rolling.action.AbstractAction;
-import org.apache.logging.log4j.core.appender.rolling.action.Action;
-import org.apache.logging.log4j.core.config.Configuration;
-import org.apache.logging.log4j.core.util.Constants;
-
-/**
- * The Rolling File Manager.
- */
-public class RollingFileManager extends FileManager {
-
-    private static RollingFileManagerFactory factory = new RollingFileManagerFactory();
-
-    protected long size;
-    private long initialTime;
-    private final PatternProcessor patternProcessor;
-    private final Semaphore semaphore = new Semaphore(1);
-    private volatile TriggeringPolicy triggeringPolicy;
-    private volatile RolloverStrategy rolloverStrategy;
-    private volatile boolean renameEmptyFiles = false;
-
-    private static final AtomicReferenceFieldUpdater<RollingFileManager, TriggeringPolicy> triggeringPolicyUpdater =
-            AtomicReferenceFieldUpdater.newUpdater(RollingFileManager.class, TriggeringPolicy.class, "triggeringPolicy");
-
-    private static final AtomicReferenceFieldUpdater<RollingFileManager, RolloverStrategy> rolloverStrategyUpdater =
-            AtomicReferenceFieldUpdater.newUpdater(RollingFileManager.class, RolloverStrategy.class, "rolloverStrategy");
-
-    @Deprecated
-    protected RollingFileManager(final String fileName, final String pattern, final OutputStream os,
-            final boolean append, final long size, final long time, final TriggeringPolicy triggeringPolicy,
-            final RolloverStrategy rolloverStrategy, final String advertiseURI,
-            final Layout<? extends Serializable> layout, final int bufferSize, final boolean writeHeader) {
-        this(fileName, pattern, os, append, size, time, triggeringPolicy, rolloverStrategy, advertiseURI, layout,
-                writeHeader, ByteBuffer.wrap(new byte[Constants.ENCODER_BYTE_BUFFER_SIZE]));
-    }
-
-    @Deprecated
-    protected RollingFileManager(final String fileName, final String pattern, final OutputStream os,
-            final boolean append, final long size, final long time, final TriggeringPolicy triggeringPolicy,
-            final RolloverStrategy rolloverStrategy, final String advertiseURI,
-            final Layout<? extends Serializable> layout, final boolean writeHeader, final ByteBuffer buffer) {
-        super(fileName, os, append, false, advertiseURI, layout, writeHeader, buffer);
-        this.size = size;
-        this.initialTime = time;
-        this.triggeringPolicy = triggeringPolicy;
-        this.rolloverStrategy = rolloverStrategy;
-        this.patternProcessor = new PatternProcessor(pattern);
-        this.patternProcessor.setPrevFileTime(time);
-    }
-
-    /**
-     * @since 2.7
-     */
-    protected RollingFileManager(final LoggerContext loggerContext, final String fileName, final String pattern, final OutputStream os,
-            final boolean append, final boolean createOnDemand, final long size, final long time,
-            final TriggeringPolicy triggeringPolicy, final RolloverStrategy rolloverStrategy,
-            final String advertiseURI, final Layout<? extends Serializable> layout, final boolean writeHeader, final ByteBuffer buffer) {
-        super(loggerContext, fileName, os, append, false, createOnDemand, advertiseURI, layout, writeHeader, buffer);
-        this.size = size;
-        this.initialTime = time;
-        this.triggeringPolicy = triggeringPolicy;
-        this.rolloverStrategy = rolloverStrategy;
-        this.patternProcessor = new PatternProcessor(pattern);
-        this.patternProcessor.setPrevFileTime(time);
-    }
-
-    public void initialize() {
-        triggeringPolicy.initialize(this);
-    }
-
-    /**
-     * Returns a RollingFileManager.
-     * @param fileName The file name.
-     * @param pattern The pattern for rolling file.
-     * @param append true if the file should be appended to.
-     * @param bufferedIO true if data should be buffered.
-     * @param policy The TriggeringPolicy.
-     * @param strategy The RolloverStrategy.
-     * @param advertiseURI the URI to use when advertising the file
-     * @param layout The Layout.
-     * @param bufferSize buffer size to use if bufferedIO is true
-     * @param immediateFlush flush on every write or not
-     * @param createOnDemand true if you want to lazy-create the file (a.k.a. on-demand.)
-     * @param configuration The configuration.
-     * @return A RollingFileManager.
-     */
-    public static RollingFileManager getFileManager(final String fileName, final String pattern, final boolean append,
-            final boolean bufferedIO, final TriggeringPolicy policy, final RolloverStrategy strategy,
-            final String advertiseURI, final Layout<? extends Serializable> layout, final int bufferSize,
-            final boolean immediateFlush, final boolean createOnDemand, final Configuration configuration) {
-
-        return (RollingFileManager) getManager(fileName, new FactoryData(pattern, append,
-            bufferedIO, policy, strategy, advertiseURI, layout, bufferSize, immediateFlush, createOnDemand, configuration), factory);
-    }
-
-    // override to make visible for unit tests
-    @Override
-    protected synchronized void write(final byte[] bytes, final int offset, final int length,
-            final boolean immediateFlush) {
-        super.write(bytes, offset, length, immediateFlush);
-    }
-
-    @Override
-    protected synchronized void writeToDestination(final byte[] bytes, final int offset, final int length) {
-        size += length;
-        super.writeToDestination(bytes, offset, length);
-    }
-
-    public boolean isRenameEmptyFiles() {
-        return renameEmptyFiles;
-    }
-
-    public void setRenameEmptyFiles(final boolean renameEmptyFiles) {
-        this.renameEmptyFiles = renameEmptyFiles;
-    }
-
-    /**
-     * Returns the current size of the file.
-     * @return The size of the file in bytes.
-     */
-    public long getFileSize() {
-        return size + byteBuffer.position();
-    }
-
-    /**
-     * Returns the time the file was created.
-     * @return The time the file was created.
-     */
-    public long getFileTime() {
-        return initialTime;
-    }
-
-    /**
-     * Determines if a rollover should occur.
-     * @param event The LogEvent.
-     */
-    public synchronized void checkRollover(final LogEvent event) {
-        if (triggeringPolicy.isTriggeringEvent(event)) {
-            rollover();
-        }
-    }
-
-    @Override
-    public boolean releaseSub(final long timeout, final TimeUnit timeUnit) {
-        boolean stopped = triggeringPolicy.stop(timeout, timeUnit);
-        return stopped && super.releaseSub(timeout, timeUnit);
-    }
-    
-    public synchronized void rollover() {
-        if (rollover(rolloverStrategy)) {
-            try {
-                size = 0;
-                initialTime = System.currentTimeMillis();
-                createFileAfterRollover();
-            } catch (final IOException e) {
-                logError("Failed to create file after rollover", e);
-            }
-        }
-    }
-
-    protected void createFileAfterRollover() throws IOException  {
-        setOutputStream(new FileOutputStream(getFileName(), isAppend()));
-    }
-
-    /**
-     * Returns the pattern processor.
-     * @return The PatternProcessor.
-     */
-    public PatternProcessor getPatternProcessor() {
-        return patternProcessor;
-    }
-
-    public void setTriggeringPolicy(final TriggeringPolicy triggeringPolicy) {
-        triggeringPolicy.initialize(this);
-        triggeringPolicyUpdater.compareAndSet(this, this.triggeringPolicy, triggeringPolicy);
-    }
-
-    public void setRolloverStrategy(final RolloverStrategy rolloverStrategy) {
-        rolloverStrategyUpdater.compareAndSet(this, this.rolloverStrategy, rolloverStrategy);
-    }
-
-    /**
-     * Returns the triggering policy.
-     * @param <T> TriggeringPolicy type
-     * @return The TriggeringPolicy
-     */
-    @SuppressWarnings("unchecked")
-    public <T extends TriggeringPolicy> T getTriggeringPolicy() {
-        // TODO We could parameterize this class with a TriggeringPolicy instead of type casting here.
-        return (T) this.triggeringPolicy;
-    }
-
-    /**
-     * Returns the rollover strategy.
-     * @return The RolloverStrategy
-     */
-    public RolloverStrategy getRolloverStrategy() {
-        return this.rolloverStrategy;
-    }
-
-    private boolean rollover(final RolloverStrategy strategy) {
-
-        try {
-            // Block until the asynchronous operation is completed.
-            semaphore.acquire();
-        } catch (final InterruptedException e) {
-            logError("Thread interrupted while attempting to check rollover", e);
-            return false;
-        }
-
-        boolean success = false;
-        Future<?> future = null;
-
-        try {
-            final RolloverDescription descriptor = strategy.rollover(this);
-            if (descriptor != null) {
-                writeFooter();
-                closeOutputStream();
-                if (descriptor.getSynchronous() != null) {
-                    LOGGER.debug("RollingFileManager executing synchronous {}", descriptor.getSynchronous());
-                    try {
-                        success = descriptor.getSynchronous().execute();
-                    } catch (final Exception ex) {
-                        logError("Caught error in synchronous task", ex);
-                    }
-                }
-
-                if (success && descriptor.getAsynchronous() != null) {
-                    LOGGER.debug("RollingFileManager executing async {}", descriptor.getAsynchronous());
-                    future = LoggerContext.getContext(false).submit(new AsyncAction(descriptor.getAsynchronous(), this));
-                }
-                return true;
-            }
-            return false;
-        } finally {
-            if (future == null || future.isDone() || future.isCancelled()) {
-                semaphore.release();
-            }
-        }
-
-    }
-
-    /**
-     * Performs actions asynchronously.
-     */
-    private static class AsyncAction extends AbstractAction {
-
-        private final Action action;
-        private final RollingFileManager manager;
-
-        /**
-         * Constructor.
-         * @param act The action to perform.
-         * @param manager The manager.
-         */
-        public AsyncAction(final Action act, final RollingFileManager manager) {
-            this.action = act;
-            this.manager = manager;
-        }
-
-        /**
-         * Executes an action.
-         *
-         * @return true if action was successful.  A return value of false will cause
-         *         the rollover to be aborted if possible.
-         * @throws java.io.IOException if IO error, a thrown exception will cause the rollover
-         *                             to be aborted if possible.
-         */
-        @Override
-        public boolean execute() throws IOException {
-            try {
-                return action.execute();
-            } finally {
-                manager.semaphore.release();
-            }
-        }
-
-        /**
-         * Cancels the action if not already initialized or waits till completion.
-         */
-        @Override
-        public void close() {
-            action.close();
-        }
-
-        /**
-         * Determines if action has been completed.
-         *
-         * @return true if action is complete.
-         */
-        @Override
-        public boolean isComplete() {
-            return action.isComplete();
-        }
-
-        @Override
-        public String toString() {
-            final StringBuilder builder = new StringBuilder();
-            builder.append(super.toString());
-            builder.append("[action=");
-            builder.append(action);
-            builder.append(", manager=");
-            builder.append(manager);
-            builder.append(", isComplete()=");
-            builder.append(isComplete());
-            builder.append(", isInterrupted()=");
-            builder.append(isInterrupted());
-            builder.append("]");
-            return builder.toString();
-        }
-    }
-
-    /**
-     * Factory data.
-     */
-    private static class FactoryData extends ConfigurationFactoryData {
-        private final String pattern;
-        private final boolean append;
-        private final boolean bufferedIO;
-        private final int bufferSize;
-        private final boolean immediateFlush;
-        private final boolean createOnDemand;
-        private final TriggeringPolicy policy;
-        private final RolloverStrategy strategy;
-        private final String advertiseURI;
-        private final Layout<? extends Serializable> layout;
-
-        /**
-         * Creates the data for the factory.
-         * @param pattern The pattern.
-         * @param append The append flag.
-         * @param bufferedIO The bufferedIO flag.
-         * @param advertiseURI
-         * @param layout The Layout.
-         * @param bufferSize the buffer size
-         * @param immediateFlush flush on every write or not
-         * @param createOnDemand true if you want to lazy-create the file (a.k.a. on-demand.)
-         * @param configuration The configuration
-         */
-        public FactoryData(final String pattern, final boolean append, final boolean bufferedIO,
-                final TriggeringPolicy policy, final RolloverStrategy strategy, final String advertiseURI,
-                final Layout<? extends Serializable> layout, final int bufferSize, final boolean immediateFlush, 
-                final boolean createOnDemand, final Configuration configuration) {
-            super(configuration);
-            this.pattern = pattern;
-            this.append = append;
-            this.bufferedIO = bufferedIO;
-            this.bufferSize = bufferSize;
-            this.policy = policy;
-            this.strategy = strategy;
-            this.advertiseURI = advertiseURI;
-            this.layout = layout;
-            this.immediateFlush = immediateFlush;
-            this.createOnDemand = createOnDemand;
-        }
-
-        public TriggeringPolicy getTriggeringPolicy()
-        {
-            return this.policy;
-        }
-
-        public RolloverStrategy getRolloverStrategy()
-        {
-            return this.strategy;
-        }
-
-        @Override
-        public String toString() {
-            final StringBuilder builder = new StringBuilder();
-            builder.append(super.toString());
-            builder.append("[pattern=");
-            builder.append(pattern);
-            builder.append(", append=");
-            builder.append(append);
-            builder.append(", bufferedIO=");
-            builder.append(bufferedIO);
-            builder.append(", bufferSize=");
-            builder.append(bufferSize);
-            builder.append(", policy=");
-            builder.append(policy);
-            builder.append(", strategy=");
-            builder.append(strategy);
-            builder.append(", advertiseURI=");
-            builder.append(advertiseURI);
-            builder.append(", layout=");
-            builder.append(layout);
-            builder.append("]");
-            return builder.toString();
-        }
-    }
-
-    @Override
-    public void updateData(final Object data)
-    {
-        final FactoryData factoryData = (FactoryData) data;
-        setRolloverStrategy(factoryData.getRolloverStrategy());
-        setTriggeringPolicy(factoryData.getTriggeringPolicy());
-    }
-
-    /**
-     * Factory to create a RollingFileManager.
-     */
-    private static class RollingFileManagerFactory implements ManagerFactory<RollingFileManager, FactoryData> {
-
-        /**
-         * Creates a RollingFileManager.
-         * @param name The name of the entity to manage.
-         * @param data The data required to create the entity.
-         * @return a RollingFileManager.
-         */
-        @Override
-        public RollingFileManager createManager(final String name, final FactoryData data) {
-            final File file = new File(name);
-            final File parent = file.getParentFile();
-            if (null != parent && !parent.exists()) {
-                parent.mkdirs();
-            }
-            // LOG4J2-1140: check writeHeader before creating the file
-            final boolean writeHeader = !data.append || !file.exists();
-            try {
-                final boolean created = data.createOnDemand ? false : file.createNewFile();
-                LOGGER.trace("New file '{}' created = {}", name, created);
-            } catch (final IOException ioe) {
-                LOGGER.error("Unable to create file " + name, ioe);
-                return null;
-            }
-            final long size = data.append ? file.length() : 0;
-
-            try {
-                final int actualSize = data.bufferedIO ? data.bufferSize : Constants.ENCODER_BYTE_BUFFER_SIZE;
-                final ByteBuffer buffer = ByteBuffer.wrap(new byte[actualSize]);
-                final OutputStream os = data.createOnDemand ? null : new FileOutputStream(name, data.append);
-                final long time = data.createOnDemand? System.currentTimeMillis() : file.lastModified(); // LOG4J2-531 create file first so time has valid value
-                
-                return new RollingFileManager(data.getLoggerContext(), name, data.pattern, os,
-                        data.append, data.createOnDemand, size, time, data.policy, data.strategy, data.advertiseURI,
-                        data.layout, writeHeader, buffer);
-            } catch (final IOException ex) {
-                LOGGER.error("RollingFileManager (" + name + ") " + ex, ex);
-            }
-            return null;
-        }
-    }
-
-}
+/*
+ * 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.logging.log4j.core.appender.rolling;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+import java.util.concurrent.Future;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.LifeCycle;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.ConfigurationFactoryData;
+import org.apache.logging.log4j.core.appender.FileManager;
+import org.apache.logging.log4j.core.appender.ManagerFactory;
+import org.apache.logging.log4j.core.appender.rolling.action.AbstractAction;
+import org.apache.logging.log4j.core.appender.rolling.action.Action;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.util.Constants;
+
+/**
+ * The Rolling File Manager.
+ */
+public class RollingFileManager extends FileManager {
+
+    private static RollingFileManagerFactory factory = new RollingFileManagerFactory();
+
+    protected long size;
+    private long initialTime;
+    private final PatternProcessor patternProcessor;
+    private final Semaphore semaphore = new Semaphore(1);
+    private volatile TriggeringPolicy triggeringPolicy;
+    private volatile RolloverStrategy rolloverStrategy;
+    private volatile boolean renameEmptyFiles = false;
+
+    private static final AtomicReferenceFieldUpdater<RollingFileManager, TriggeringPolicy> triggeringPolicyUpdater =
+            AtomicReferenceFieldUpdater.newUpdater(RollingFileManager.class, TriggeringPolicy.class, "triggeringPolicy");
+
+    private static final AtomicReferenceFieldUpdater<RollingFileManager, RolloverStrategy> rolloverStrategyUpdater =
+            AtomicReferenceFieldUpdater.newUpdater(RollingFileManager.class, RolloverStrategy.class, "rolloverStrategy");
+
+    @Deprecated
+    protected RollingFileManager(final String fileName, final String pattern, final OutputStream os,
+            final boolean append, final long size, final long time, final TriggeringPolicy triggeringPolicy,
+            final RolloverStrategy rolloverStrategy, final String advertiseURI,
+            final Layout<? extends Serializable> layout, final int bufferSize, final boolean writeHeader) {
+        this(fileName, pattern, os, append, size, time, triggeringPolicy, rolloverStrategy, advertiseURI, layout,
+                writeHeader, ByteBuffer.wrap(new byte[Constants.ENCODER_BYTE_BUFFER_SIZE]));
+    }
+
+    @Deprecated
+    protected RollingFileManager(final String fileName, final String pattern, final OutputStream os,
+            final boolean append, final long size, final long time, final TriggeringPolicy triggeringPolicy,
+            final RolloverStrategy rolloverStrategy, final String advertiseURI,
+            final Layout<? extends Serializable> layout, final boolean writeHeader, final ByteBuffer buffer) {
+        super(fileName, os, append, false, advertiseURI, layout, writeHeader, buffer);
+        this.size = size;
+        this.initialTime = time;
+        this.triggeringPolicy = triggeringPolicy;
+        this.rolloverStrategy = rolloverStrategy;
+        this.patternProcessor = new PatternProcessor(pattern);
+        this.patternProcessor.setPrevFileTime(time);
+    }
+
+    /**
+     * @since 2.7
+     */
+    protected RollingFileManager(final LoggerContext loggerContext, final String fileName, final String pattern, final OutputStream os,
+            final boolean append, final boolean createOnDemand, final long size, final long time,
+            final TriggeringPolicy triggeringPolicy, final RolloverStrategy rolloverStrategy,
+            final String advertiseURI, final Layout<? extends Serializable> layout, final boolean writeHeader, final ByteBuffer buffer) {
+        super(loggerContext, fileName, os, append, false, createOnDemand, advertiseURI, layout, writeHeader, buffer);
+        this.size = size;
+        this.initialTime = time;
+        this.triggeringPolicy = triggeringPolicy;
+        this.rolloverStrategy = rolloverStrategy;
+        this.patternProcessor = new PatternProcessor(pattern);
+        this.patternProcessor.setPrevFileTime(time);
+    }
+
+    public void initialize() {
+        triggeringPolicy.initialize(this);
+    }
+
+    /**
+     * Returns a RollingFileManager.
+     * @param fileName The file name.
+     * @param pattern The pattern for rolling file.
+     * @param append true if the file should be appended to.
+     * @param bufferedIO true if data should be buffered.
+     * @param policy The TriggeringPolicy.
+     * @param strategy The RolloverStrategy.
+     * @param advertiseURI the URI to use when advertising the file
+     * @param layout The Layout.
+     * @param bufferSize buffer size to use if bufferedIO is true
+     * @param immediateFlush flush on every write or not
+     * @param createOnDemand true if you want to lazy-create the file (a.k.a. on-demand.)
+     * @param configuration The configuration.
+     * @return A RollingFileManager.
+     */
+    public static RollingFileManager getFileManager(final String fileName, final String pattern, final boolean append,
+            final boolean bufferedIO, final TriggeringPolicy policy, final RolloverStrategy strategy,
+            final String advertiseURI, final Layout<? extends Serializable> layout, final int bufferSize,
+            final boolean immediateFlush, final boolean createOnDemand, final Configuration configuration) {
+
+        return (RollingFileManager) getManager(fileName, new FactoryData(pattern, append,
+            bufferedIO, policy, strategy, advertiseURI, layout, bufferSize, immediateFlush, createOnDemand, configuration), factory);
+    }
+
+    // override to make visible for unit tests
+    @Override
+    protected synchronized void write(final byte[] bytes, final int offset, final int length,
+            final boolean immediateFlush) {
+        super.write(bytes, offset, length, immediateFlush);
+    }
+
+    @Override
+    protected synchronized void writeToDestination(final byte[] bytes, final int offset, final int length) {
+        size += length;
+        super.writeToDestination(bytes, offset, length);
+    }
+
+    public boolean isRenameEmptyFiles() {
+        return renameEmptyFiles;
+    }
+
+    public void setRenameEmptyFiles(final boolean renameEmptyFiles) {
+        this.renameEmptyFiles = renameEmptyFiles;
+    }
+
+    /**
+     * Returns the current size of the file.
+     * @return The size of the file in bytes.
+     */
+    public long getFileSize() {
+        return size + byteBuffer.position();
+    }
+
+    /**
+     * Returns the time the file was created.
+     * @return The time the file was created.
+     */
+    public long getFileTime() {
+        return initialTime;
+    }
+
+    /**
+     * Determines if a rollover should occur.
+     * @param event The LogEvent.
+     */
+    public synchronized void checkRollover(final LogEvent event) {
+        if (triggeringPolicy.isTriggeringEvent(event)) {
+            rollover();
+        }
+    }
+
+    @Override
+    public boolean releaseSub(final long timeout, final TimeUnit timeUnit) {
+        boolean stopped = true;
+        if (triggeringPolicy instanceof LifeCycle) {
+            stopped &= ((LifeCycle) triggeringPolicy).stop(timeout, timeUnit);
+        }
+        return stopped && super.releaseSub(timeout, timeUnit);
+    }
+    
+    public synchronized void rollover() {
+        if (rollover(rolloverStrategy)) {
+            try {
+                size = 0;
+                initialTime = System.currentTimeMillis();
+                createFileAfterRollover();
+            } catch (final IOException e) {
+                logError("Failed to create file after rollover", e);
+            }
+        }
+    }
+
+    protected void createFileAfterRollover() throws IOException  {
+        setOutputStream(new FileOutputStream(getFileName(), isAppend()));
+    }
+
+    /**
+     * Returns the pattern processor.
+     * @return The PatternProcessor.
+     */
+    public PatternProcessor getPatternProcessor() {
+        return patternProcessor;
+    }
+
+    public void setTriggeringPolicy(final TriggeringPolicy triggeringPolicy) {
+        triggeringPolicy.initialize(this);
+        triggeringPolicyUpdater.compareAndSet(this, this.triggeringPolicy, triggeringPolicy);
+    }
+
+    public void setRolloverStrategy(final RolloverStrategy rolloverStrategy) {
+        rolloverStrategyUpdater.compareAndSet(this, this.rolloverStrategy, rolloverStrategy);
+    }
+
+    /**
+     * Returns the triggering policy.
+     * @param <T> TriggeringPolicy type
+     * @return The TriggeringPolicy
+     */
+    @SuppressWarnings("unchecked")
+    public <T extends TriggeringPolicy> T getTriggeringPolicy() {
+        // TODO We could parameterize this class with a TriggeringPolicy instead of type casting here.
+        return (T) this.triggeringPolicy;
+    }
+
+    /**
+     * Returns the rollover strategy.
+     * @return The RolloverStrategy
+     */
+    public RolloverStrategy getRolloverStrategy() {
+        return this.rolloverStrategy;
+    }
+
+    private boolean rollover(final RolloverStrategy strategy) {
+
+        try {
+            // Block until the asynchronous operation is completed.
+            semaphore.acquire();
+        } catch (final InterruptedException e) {
+            logError("Thread interrupted while attempting to check rollover", e);
+            return false;
+        }
+
+        boolean success = false;
+        Future<?> future = null;
+
+        try {
+            final RolloverDescription descriptor = strategy.rollover(this);
+            if (descriptor != null) {
+                writeFooter();
+                closeOutputStream();
+                if (descriptor.getSynchronous() != null) {
+                    LOGGER.debug("RollingFileManager executing synchronous {}", descriptor.getSynchronous());
+                    try {
+                        success = descriptor.getSynchronous().execute();
+                    } catch (final Exception ex) {
+                        logError("Caught error in synchronous task", ex);
+                    }
+                }
+
+                if (success && descriptor.getAsynchronous() != null) {
+                    LOGGER.debug("RollingFileManager executing async {}", descriptor.getAsynchronous());
+                    future = LoggerContext.getContext(false).submit(new AsyncAction(descriptor.getAsynchronous(), this));
+                }
+                return true;
+            }
+            return false;
+        } finally {
+            if (future == null || future.isDone() || future.isCancelled()) {
+                semaphore.release();
+            }
+        }
+
+    }
+
+    /**
+     * Performs actions asynchronously.
+     */
+    private static class AsyncAction extends AbstractAction {
+
+        private final Action action;
+        private final RollingFileManager manager;
+
+        /**
+         * Constructor.
+         * @param act The action to perform.
+         * @param manager The manager.
+         */
+        public AsyncAction(final Action act, final RollingFileManager manager) {
+            this.action = act;
+            this.manager = manager;
+        }
+
+        /**
+         * Executes an action.
+         *
+         * @return true if action was successful.  A return value of false will cause
+         *         the rollover to be aborted if possible.
+         * @throws java.io.IOException if IO error, a thrown exception will cause the rollover
+         *                             to be aborted if possible.
+         */
+        @Override
+        public boolean execute() throws IOException {
+            try {
+                return action.execute();
+            } finally {
+                manager.semaphore.release();
+            }
+        }
+
+        /**
+         * Cancels the action if not already initialized or waits till completion.
+         */
+        @Override
+        public void close() {
+            action.close();
+        }
+
+        /**
+         * Determines if action has been completed.
+         *
+         * @return true if action is complete.
+         */
+        @Override
+        public boolean isComplete() {
+            return action.isComplete();
+        }
+
+        @Override
+        public String toString() {
+            final StringBuilder builder = new StringBuilder();
+            builder.append(super.toString());
+            builder.append("[action=");
+            builder.append(action);
+            builder.append(", manager=");
+            builder.append(manager);
+            builder.append(", isComplete()=");
+            builder.append(isComplete());
+            builder.append(", isInterrupted()=");
+            builder.append(isInterrupted());
+            builder.append("]");
+            return builder.toString();
+        }
+    }
+
+    /**
+     * Factory data.
+     */
+    private static class FactoryData extends ConfigurationFactoryData {
+        private final String pattern;
+        private final boolean append;
+        private final boolean bufferedIO;
+        private final int bufferSize;
+        private final boolean immediateFlush;
+        private final boolean createOnDemand;
+        private final TriggeringPolicy policy;
+        private final RolloverStrategy strategy;
+        private final String advertiseURI;
+        private final Layout<? extends Serializable> layout;
+
+        /**
+         * Creates the data for the factory.
+         * @param pattern The pattern.
+         * @param append The append flag.
+         * @param bufferedIO The bufferedIO flag.
+         * @param advertiseURI
+         * @param layout The Layout.
+         * @param bufferSize the buffer size
+         * @param immediateFlush flush on every write or not
+         * @param createOnDemand true if you want to lazy-create the file (a.k.a. on-demand.)
+         * @param configuration The configuration
+         */
+        public FactoryData(final String pattern, final boolean append, final boolean bufferedIO,
+                final TriggeringPolicy policy, final RolloverStrategy strategy, final String advertiseURI,
+                final Layout<? extends Serializable> layout, final int bufferSize, final boolean immediateFlush, 
+                final boolean createOnDemand, final Configuration configuration) {
+            super(configuration);
+            this.pattern = pattern;
+            this.append = append;
+            this.bufferedIO = bufferedIO;
+            this.bufferSize = bufferSize;
+            this.policy = policy;
+            this.strategy = strategy;
+            this.advertiseURI = advertiseURI;
+            this.layout = layout;
+            this.immediateFlush = immediateFlush;
+            this.createOnDemand = createOnDemand;
+        }
+
+        public TriggeringPolicy getTriggeringPolicy()
+        {
+            return this.policy;
+        }
+
+        public RolloverStrategy getRolloverStrategy()
+        {
+            return this.strategy;
+        }
+
+        @Override
+        public String toString() {
+            final StringBuilder builder = new StringBuilder();
+            builder.append(super.toString());
+            builder.append("[pattern=");
+            builder.append(pattern);
+            builder.append(", append=");
+            builder.append(append);
+            builder.append(", bufferedIO=");
+            builder.append(bufferedIO);
+            builder.append(", bufferSize=");
+            builder.append(bufferSize);
+            builder.append(", policy=");
+            builder.append(policy);
+            builder.append(", strategy=");
+            builder.append(strategy);
+            builder.append(", advertiseURI=");
+            builder.append(advertiseURI);
+            builder.append(", layout=");
+            builder.append(layout);
+            builder.append("]");
+            return builder.toString();
+        }
+    }
+
+    @Override
+    public void updateData(final Object data)
+    {
+        final FactoryData factoryData = (FactoryData) data;
+        setRolloverStrategy(factoryData.getRolloverStrategy());
+        setTriggeringPolicy(factoryData.getTriggeringPolicy());
+    }
+
+    /**
+     * Factory to create a RollingFileManager.
+     */
+    private static class RollingFileManagerFactory implements ManagerFactory<RollingFileManager, FactoryData> {
+
+        /**
+         * Creates a RollingFileManager.
+         * @param name The name of the entity to manage.
+         * @param data The data required to create the entity.
+         * @return a RollingFileManager.
+         */
+        @Override
+        public RollingFileManager createManager(final String name, final FactoryData data) {
+            final File file = new File(name);
+            final File parent = file.getParentFile();
+            if (null != parent && !parent.exists()) {
+                parent.mkdirs();
+            }
+            // LOG4J2-1140: check writeHeader before creating the file
+            final boolean writeHeader = !data.append || !file.exists();
+            try {
+                final boolean created = data.createOnDemand ? false : file.createNewFile();
+                LOGGER.trace("New file '{}' created = {}", name, created);
+            } catch (final IOException ioe) {
+                LOGGER.error("Unable to create file " + name, ioe);
+                return null;
+            }
+            final long size = data.append ? file.length() : 0;
+
+            try {
+                final int actualSize = data.bufferedIO ? data.bufferSize : Constants.ENCODER_BYTE_BUFFER_SIZE;
+                final ByteBuffer buffer = ByteBuffer.wrap(new byte[actualSize]);
+                final OutputStream os = data.createOnDemand ? null : new FileOutputStream(name, data.append);
+                final long time = data.createOnDemand? System.currentTimeMillis() : file.lastModified(); // LOG4J2-531 create file first so time has valid value
+                
+                return new RollingFileManager(data.getLoggerContext(), name, data.pattern, os,
+                        data.append, data.createOnDemand, size, time, data.policy, data.strategy, data.advertiseURI,
+                        data.layout, writeHeader, buffer);
+            } catch (final IOException ex) {
+                LOGGER.error("RollingFileManager (" + name + ") " + ex, ex);
+            }
+            return null;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4d84bd58/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/TriggeringPolicy.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/TriggeringPolicy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/TriggeringPolicy.java
index f6fea59..ed6a3f1 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/TriggeringPolicy.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/TriggeringPolicy.java
@@ -16,7 +16,6 @@
  */
 package org.apache.logging.log4j.core.appender.rolling;
 
-import org.apache.logging.log4j.core.LifeCycle;
 import org.apache.logging.log4j.core.LogEvent;
 
 /**
@@ -26,7 +25,7 @@ import org.apache.logging.log4j.core.LogEvent;
  * 
  * @see AbstractTriggeringPolicy
  */
-public interface TriggeringPolicy extends LifeCycle {
+public interface TriggeringPolicy /* TODO 3.0: extends LifeCycle */ {
 
     /**
      * Initializes this triggering policy.


[12/21] logging-log4j2 git commit: Try to fix test on Jenkins by waiting a little longer for messages to come. Refactor this waiting in a new ListAppender method.

Posted by rp...@apache.org.
Try to fix test on Jenkins by waiting a little longer for messages to
come. Refactor this waiting in a new ListAppender method.

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/bdd0e362
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/bdd0e362
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/bdd0e362

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: bdd0e36237a8a30d46b814961140a08181a34ad1
Parents: 86a037f
Author: Gary Gregory <gg...@apache.org>
Authored: Thu Sep 8 13:29:45 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Thu Sep 8 13:29:45 2016 -0700

----------------------------------------------------------------------
 .../logging/log4j/core/appender/AsyncAppenderTest.java   |  9 ++++-----
 .../apache/logging/log4j/test/appender/ListAppender.java | 11 +++++++++++
 2 files changed, 15 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/bdd0e362/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
index 8031909..601ddb5 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
@@ -17,6 +17,7 @@
 package org.apache.logging.log4j.core.appender;
 
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -38,7 +39,7 @@ import static org.junit.Assert.*;
 @RunWith(Parameterized.class)
 public class AsyncAppenderTest {
 
-    private static final int SLEEP_MILLIS = 100;
+    private static final int TIMEOUT_MILLIS = 1000;
 
     @Parameterized.Parameters(name = "{0}")
     public static Object[] data() {
@@ -77,8 +78,7 @@ public class AsyncAppenderTest {
         final Logger logger = LogManager.getLogger(AsyncAppender.class);
         logger.error("This is a test");
         logger.warn("Hello world!");
-        Thread.sleep(SLEEP_MILLIS);
-        final List<String> list = listAppender.getMessages();
+        final List<String> list = listAppender.getMessages(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
         assertNotNull("No events generated", list);
         assertTrue("Incorrect number of events. Expected 2, got " + list.size(), list.size() == 2);
         String msg = list.get(0);
@@ -95,8 +95,7 @@ public class AsyncAppenderTest {
         final Exception parent = new IllegalStateException("Test");
         final Throwable child = new LoggingException("This is a test", parent);
         logger.error("This is a test", child);
-        Thread.sleep(SLEEP_MILLIS);
-        final List<String> list = listAppender.getMessages();
+        final List<String> list = listAppender.getMessages(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
         assertNotNull("No events generated", list);
         assertTrue("Incorrect number of events. Expected 1, got " + list.size(), list.size() == 1);
         final String msg = list.get(0);

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/bdd0e362/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/ListAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/ListAppender.java b/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/ListAppender.java
index 6ecf5c3..68ee55d 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/ListAppender.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/ListAppender.java
@@ -174,6 +174,17 @@ public class ListAppender extends AbstractAppender {
         return Collections.unmodifiableList(messages);
     }
 
+    /**
+     * Polls the messages for at most timeout timeUnits and return a copy of what we have so far. 
+     */
+    public List<String> getMessages(long timeout, TimeUnit timeUnit) throws InterruptedException {
+        final long endMillis = System.currentTimeMillis() + timeUnit.toMillis(timeout);
+        while (messages.isEmpty() && System.currentTimeMillis() < endMillis) {
+            Thread.sleep(100);
+        }
+        return Collections.unmodifiableList(messages);
+    }
+
     public synchronized List<byte[]> getData() {
         return Collections.unmodifiableList(data);
     }


[14/21] logging-log4j2 git commit: Better failure message.

Posted by rp...@apache.org.
Better failure message.

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/8c80cb9b
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/8c80cb9b
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/8c80cb9b

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: 8c80cb9b74e730283def89c25329ce3eab410472
Parents: 099775b
Author: Gary Gregory <gg...@apache.org>
Authored: Thu Sep 8 14:59:02 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Thu Sep 8 14:59:02 2016 -0700

----------------------------------------------------------------------
 .../log4j/core/appender/AsyncAppenderTest.java        | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/8c80cb9b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
index 26488a5..8c57efd 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
@@ -78,9 +78,12 @@ public class AsyncAppenderTest {
         final Logger logger = LogManager.getLogger(AsyncAppender.class);
         logger.error("This is a test");
         logger.warn("Hello world!");
-        final List<String> list = listAppender.getMessages(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+        final int timeoutMillis = TIMEOUT_MILLIS;
+        final TimeUnit timeUnit = TimeUnit.MILLISECONDS;
+        final List<String> list = listAppender.getMessages(timeoutMillis, timeUnit);
         assertNotNull("No events generated", list);
-        assertTrue("Incorrect number of events. Expected 2, got " + list.size(), list.size() == 2);
+        assertTrue("Incorrect number of events after " + timeoutMillis + " " + timeUnit + ". Expected 2, got "
+                + list.size(), list.size() == 2);
         String msg = list.get(0);
         String expected = AsyncAppenderTest.class.getName() + " rewriteTest This is a test";
         assertTrue("Expected " + expected + ", Actual " + msg, expected.equals(msg));
@@ -95,9 +98,12 @@ public class AsyncAppenderTest {
         final Exception parent = new IllegalStateException("Test");
         final Throwable child = new LoggingException("This is a test", parent);
         logger.error("This is a test", child);
-        final List<String> list = listAppender.getMessages(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+        final int timeoutMillis = TIMEOUT_MILLIS;
+        final TimeUnit timeUnit = TimeUnit.MILLISECONDS;
+        final List<String> list = listAppender.getMessages(timeoutMillis, timeUnit);
         assertNotNull("No events generated", list);
-        assertTrue("Incorrect number of events. Expected 1, got " + list.size(), list.size() == 1);
+        assertTrue("Incorrect number of events after " + timeoutMillis + " " + timeUnit + ". Expected 1, got "
+                + list.size(), list.size() == 1);
         final String msg = list.get(0);
         assertTrue("No parent exception", msg.contains("java.lang.IllegalStateException"));
     }


[19/21] logging-log4j2 git commit: Javadoc.

Posted by rp...@apache.org.
Javadoc.

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/74f59763
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/74f59763
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/74f59763

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: 74f5976352cab95f6bad5db9987b063084d54f1c
Parents: 40fbc2a
Author: Gary Gregory <gg...@apache.org>
Authored: Fri Sep 9 09:01:35 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Fri Sep 9 09:01:35 2016 -0700

----------------------------------------------------------------------
 .../org/apache/logging/log4j/core/appender/ConsoleAppender.java  | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/74f59763/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
index e2d9452..195ecbc 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
@@ -84,7 +84,7 @@ public final class ConsoleAppender extends AbstractOutputStreamAppender<OutputSt
      * @param ignore If {@code "true"} (default) exceptions encountered when appending events are logged; otherwise they
      *            are propagated to the caller.
      * @return The ConsoleAppender.
-     * @deprecated Use {@link #newBuilder()}.
+     * @deprecated Deprecated in 2.7; use {@link #newBuilder()}.
      */
     @Deprecated
     public static ConsoleAppender createAppender(Layout<? extends Serializable> layout,
@@ -119,7 +119,7 @@ public final class ConsoleAppender extends AbstractOutputStreamAppender<OutputSt
      * @param ignoreExceptions If {@code "true"} (default) exceptions encountered when appending events are logged; otherwise they
      *            are propagated to the caller.
      * @return The ConsoleAppender.
-     * @deprecated Use {@link #newBuilder()}.
+     * @deprecated Deprecated in 2.7; use {@link #newBuilder()}.
      */
     @Deprecated
     public static ConsoleAppender createAppender(


[09/21] logging-log4j2 git commit: Revert [LOG4J2-1546] Remove deprecated Core API org.apache.logging.log4j.core.config.LoggerConfig.createLogger(String, Level, String, String , AppenderRef[] refs, Property[], Configuration config, Filter). Posted by rp...@apache.org.
Revert [LOG4J2-1546] Remove deprecated Core API
org.apache.logging.log4j.core.config.LoggerConfig.createLogger(String,
Level, String, String , AppenderRef[] refs, Property[], Configuration
config, Filter).
      </action>


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/d7cd3e3e
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/d7cd3e3e
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/d7cd3e3e

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: d7cd3e3e572f9b6f96cede2e4b93b93623f47ed7
Parents: 08cad98
Author: Gary Gregory <gg...@apache.org>
Authored: Thu Sep 8 11:56:43 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Thu Sep 8 11:56:43 2016 -0700

----------------------------------------------------------------------
 src/changes/changes.xml | 3 ---
 1 file changed, 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d7cd3e3e/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index fa53129..130df6e 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -231,9 +231,6 @@
       <action issue="LOG4J2-1545" dev="ggregory" type="update">
         Remove deprecated Web API org.apache.logging.log4j.web.WebLookup.getServletContext().
       </action>
-      <action issue="LOG4J2-1546" dev="ggregory" type="update">
-        Remove deprecated Core API org.apache.logging.log4j.core.config.LoggerConfig.createLogger(String, Level, String, String , AppenderRef[] refs, Property[], Configuration config, Filter).
-      </action>
     </release>
     <release version="2.6.2" date="2016-07-05" description="GA Release 2.6.2">
       <action issue="LOG4J2-904" dev="rgoers" type="fix" due-to="Bernhard M�hr">


[07/21] logging-log4j2 git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/logging-log4j2.git

Posted by rp...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/logging-log4j2.git

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/a107355e
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/a107355e
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/a107355e

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: a107355edc95911622c1f642d1f5ac775ae3d53e
Parents: 5d79669 284067c
Author: Gary Gregory <gg...@apache.org>
Authored: Thu Sep 8 11:52:39 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Thu Sep 8 11:52:39 2016 -0700

----------------------------------------------------------------------
 .../logging/log4j/core/impl/ThrowableProxy.java |  9 ++--
 .../async/AsyncLoggerClassLoadDeadlock.java     | 32 ++++++++++++++
 .../async/AsyncLoggerClassLoadDeadlockTest.java | 45 ++++++++++++++++++++
 .../test/resources/AsyncLoggerConsoleTest.xml   | 16 +++++++
 src/changes/changes.xml                         |  3 ++
 5 files changed, 100 insertions(+), 5 deletions(-)
----------------------------------------------------------------------



[20/21] logging-log4j2 git commit: Add org.apache.logging.log4j.junit.LoggerContextRule.getLogger(Class).

Posted by rp...@apache.org.
Add
org.apache.logging.log4j.junit.LoggerContextRule.getLogger(Class<?>).

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/f2a07e66
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/f2a07e66
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/f2a07e66

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: f2a07e66a724f26554cb9f5ed62cfb4fbae889fb
Parents: 74f5976
Author: Gary Gregory <gg...@apache.org>
Authored: Fri Sep 9 09:31:54 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Fri Sep 9 09:31:54 2016 -0700

----------------------------------------------------------------------
 .../apache/logging/log4j/junit/LoggerContextRule.java    | 11 +++++++++++
 1 file changed, 11 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/f2a07e66/log4j-core/src/test/java/org/apache/logging/log4j/junit/LoggerContextRule.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/junit/LoggerContextRule.java b/log4j-core/src/test/java/org/apache/logging/log4j/junit/LoggerContextRule.java
index cc0b343..1f1a95e 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/junit/LoggerContextRule.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/junit/LoggerContextRule.java
@@ -208,6 +208,17 @@ public class LoggerContextRule implements TestRule {
     }
 
     /**
+     * Gets a named Logger for the given class in this LoggerContext.
+     *
+     * @param clazz
+     *            The Class whose name should be used as the Logger name. If null it will default to the calling class.
+     * @return the named Logger.
+     */
+    public Logger getLogger(final Class<?> clazz) {
+        return loggerContext.getLogger(clazz.getName());
+    }
+
+    /**
      * Gets a named Logger in this LoggerContext.
      *
      * @param name


[15/21] logging-log4j2 git commit: Use longs for timeouts.

Posted by rp...@apache.org.
Use longs for timeouts.

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/1b3c6af6
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/1b3c6af6
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/1b3c6af6

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: 1b3c6af6bc24461c736ee2c7a8aa1fc8c1bb4c4e
Parents: 8c80cb9
Author: Gary Gregory <gg...@apache.org>
Authored: Thu Sep 8 15:00:32 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Thu Sep 8 15:00:32 2016 -0700

----------------------------------------------------------------------
 .../apache/logging/log4j/core/appender/AsyncAppenderTest.java  | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1b3c6af6/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
index 8c57efd..01beb48 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
@@ -39,7 +39,7 @@ import static org.junit.Assert.*;
 @RunWith(Parameterized.class)
 public class AsyncAppenderTest {
 
-    private static final int TIMEOUT_MILLIS = 2000;
+    private static final long TIMEOUT_MILLIS = 2000;
 
     @Parameterized.Parameters(name = "{0}")
     public static Object[] data() {
@@ -78,7 +78,7 @@ public class AsyncAppenderTest {
         final Logger logger = LogManager.getLogger(AsyncAppender.class);
         logger.error("This is a test");
         logger.warn("Hello world!");
-        final int timeoutMillis = TIMEOUT_MILLIS;
+        final long timeoutMillis = TIMEOUT_MILLIS;
         final TimeUnit timeUnit = TimeUnit.MILLISECONDS;
         final List<String> list = listAppender.getMessages(timeoutMillis, timeUnit);
         assertNotNull("No events generated", list);
@@ -98,7 +98,7 @@ public class AsyncAppenderTest {
         final Exception parent = new IllegalStateException("Test");
         final Throwable child = new LoggingException("This is a test", parent);
         logger.error("This is a test", child);
-        final int timeoutMillis = TIMEOUT_MILLIS;
+        final long timeoutMillis = TIMEOUT_MILLIS;
         final TimeUnit timeUnit = TimeUnit.MILLISECONDS;
         final List<String> list = listAppender.getMessages(timeoutMillis, timeUnit);
         assertNotNull("No events generated", list);


[02/21] logging-log4j2 git commit: Fix formatting

Posted by rp...@apache.org.
Fix formatting


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/7c2fc7c5
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/7c2fc7c5
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/7c2fc7c5

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: 7c2fc7c54f25a399ca84ed08b7d664ca73887398
Parents: 5cbf04f
Author: Matt Sicker <bo...@gmail.com>
Authored: Thu Sep 8 10:11:02 2016 -0500
Committer: Matt Sicker <bo...@gmail.com>
Committed: Thu Sep 8 10:11:02 2016 -0500

----------------------------------------------------------------------
 .../logging/log4j/core/impl/ThrowableProxy.java | 273 +++++++++----------
 1 file changed, 124 insertions(+), 149 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7c2fc7c5/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableProxy.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableProxy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableProxy.java
index 5cd73bc..a052e4d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableProxy.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableProxy.java
@@ -38,13 +38,13 @@ import org.apache.logging.log4j.util.Strings;
 
 /**
  * Wraps a Throwable to add packaging information about each stack trace element.
- * 
+ *
  * <p>
  * A proxy is used to represent a throwable that may not exist in a different class loader or JVM. When an application
  * deserializes a ThrowableProxy, the throwable may not be set, but the throwable's information is preserved in other
  * fields of the proxy like the message and stack trace.
  * </p>
- * 
+ *
  * <p>
  * TODO: Move this class to org.apache.logging.log4j.core because it is used from LogEvent.
  * </p>
@@ -54,12 +54,12 @@ import org.apache.logging.log4j.util.Strings;
  */
 public class ThrowableProxy implements Serializable {
 
-	private static final String TAB = "\t";
+    private static final String TAB = "\t";
     private static final String CAUSED_BY_LABEL = "Caused by: ";
-	private static final String SUPPRESSED_LABEL = "Suppressed: ";
+    private static final String SUPPRESSED_LABEL = "Suppressed: ";
     private static final String WRAPPED_BY_LABEL = "Wrapped by: ";
 
-	/**
+    /**
      * Cached StackTracePackageElement and ClassLoader.
      * <p>
      * Consider this class private.
@@ -115,9 +115,8 @@ public class ThrowableProxy implements Serializable {
 
     /**
      * Constructs the wrapper for the Throwable that includes packaging data.
-     * 
-     * @param throwable
-     *        The Throwable to wrap, must not be null.
+     *
+     * @param throwable The Throwable to wrap, must not be null.
      */
     public ThrowableProxy(final Throwable throwable) {
         this(throwable, null);
@@ -125,11 +124,9 @@ public class ThrowableProxy implements Serializable {
 
     /**
      * Constructs the wrapper for the Throwable that includes packaging data.
-     * 
-     * @param throwable
-     *        The Throwable to wrap, must not be null.
-     * @param visited
-     *        The set of visited suppressed exceptions.
+     *
+     * @param throwable The Throwable to wrap, must not be null.
+     * @param visited   The set of visited suppressed exceptions.
      */
     private ThrowableProxy(final Throwable throwable, final Set<Throwable> visited) {
         this.throwable = throwable;
@@ -141,26 +138,24 @@ public class ThrowableProxy implements Serializable {
         this.extendedStackTrace = this.toExtendedStackTrace(stack, map, null, throwable.getStackTrace());
         final Throwable throwableCause = throwable.getCause();
         final Set<Throwable> causeVisited = new HashSet<>(1);
-        this.causeProxy = throwableCause == null ? null : new ThrowableProxy(throwable, stack, map, throwableCause, visited, causeVisited);
+        this.causeProxy = throwableCause == null ? null : new ThrowableProxy(throwable, stack, map, throwableCause,
+            visited, causeVisited);
         this.suppressedProxies = this.toSuppressedProxies(throwable, visited);
     }
 
     /**
      * Constructs the wrapper for a Throwable that is referenced as the cause by another Throwable.
-     * 
-     * @param parent
-     *        The Throwable referencing this Throwable.
-     * @param stack
-     *        The Class stack.
-     * @param map
-     *        The cache containing the packaging data.
-     * @param cause
-     *        The Throwable to wrap.
+     *
+     * @param parent            The Throwable referencing this Throwable.
+     * @param stack             The Class stack.
+     * @param map               The cache containing the packaging data.
+     * @param cause             The Throwable to wrap.
      * @param suppressedVisited TODO
-     * @param causeVisited TODO
+     * @param causeVisited      TODO
      */
     private ThrowableProxy(final Throwable parent, final Stack<Class<?>> stack, final Map<String, CacheEntry> map,
-            final Throwable cause, final Set<Throwable> suppressedVisited, final Set<Throwable> causeVisited) {
+                           final Throwable cause, final Set<Throwable> suppressedVisited,
+                           final Set<Throwable> causeVisited) {
         causeVisited.add(cause);
         this.throwable = cause;
         this.name = cause.getClass().getName();
@@ -169,7 +164,7 @@ public class ThrowableProxy implements Serializable {
         this.extendedStackTrace = this.toExtendedStackTrace(stack, map, parent.getStackTrace(), cause.getStackTrace());
         final Throwable causeCause = cause.getCause();
         this.causeProxy = causeCause == null || causeVisited.contains(causeCause) ? null : new ThrowableProxy(parent,
-                stack, map, causeCause, suppressedVisited, causeVisited);
+            stack, map, causeCause, suppressedVisited, causeVisited);
         this.suppressedProxies = this.toSuppressedProxies(cause, suppressedVisited);
     }
 
@@ -212,26 +207,27 @@ public class ThrowableProxy implements Serializable {
     }
 
     private void formatCause(final StringBuilder sb, final String prefix, final ThrowableProxy cause,
-            final List<String> ignorePackages, final TextRenderer textRenderer) {
+                             final List<String> ignorePackages, final TextRenderer textRenderer) {
         formatThrowableProxy(sb, prefix, CAUSED_BY_LABEL, cause, ignorePackages, textRenderer);
     }
 
-	private void formatThrowableProxy(final StringBuilder sb, final String prefix, final String causeLabel,
-			final ThrowableProxy throwableProxy, final List<String> ignorePackages, final TextRenderer textRenderer) {
-		if (throwableProxy == null) {
-			return;
-		}
+    private void formatThrowableProxy(final StringBuilder sb, final String prefix, final String causeLabel,
+                                      final ThrowableProxy throwableProxy, final List<String> ignorePackages,
+                                      final TextRenderer textRenderer) {
+        if (throwableProxy == null) {
+            return;
+        }
         textRenderer.render(prefix, sb, "Prefix");
         textRenderer.render(causeLabel, sb, "CauseLabel");
         throwableProxy.renderOn(sb, textRenderer);
         textRenderer.render(EOL_STR, sb, "Text");
-		this.formatElements(sb, prefix, throwableProxy.commonElementCount,
-				throwableProxy.getStackTrace(), throwableProxy.extendedStackTrace, ignorePackages, textRenderer);
-		this.formatSuppressed(sb, prefix + TAB, throwableProxy.suppressedProxies, ignorePackages, textRenderer);
-		this.formatCause(sb, prefix, throwableProxy.causeProxy, ignorePackages, textRenderer);
-	}
+        this.formatElements(sb, prefix, throwableProxy.commonElementCount,
+            throwableProxy.getStackTrace(), throwableProxy.extendedStackTrace, ignorePackages, textRenderer);
+        this.formatSuppressed(sb, prefix + TAB, throwableProxy.suppressedProxies, ignorePackages, textRenderer);
+        this.formatCause(sb, prefix, throwableProxy.causeProxy, ignorePackages, textRenderer);
+    }
 
-	void renderOn(final StringBuilder output, final TextRenderer textRenderer) {
+    void renderOn(final StringBuilder output, final TextRenderer textRenderer) {
         final String msg = this.message;
         textRenderer.render(this.name, output, "Name");
         if (msg != null) {
@@ -241,49 +237,50 @@ public class ThrowableProxy implements Serializable {
     }
 
     private void formatSuppressed(final StringBuilder sb, final String prefix, final ThrowableProxy[] suppressedProxies,
-			final List<String> ignorePackages, final TextRenderer textRenderer) {
-		if (suppressedProxies == null) {
-			return;
-		}
-		for (final ThrowableProxy suppressedProxy : suppressedProxies) {
-			formatThrowableProxy(sb, prefix, SUPPRESSED_LABEL, suppressedProxy, ignorePackages, textRenderer);
-		}
-	}
-
-	private void formatElements(final StringBuilder sb, final String prefix, final int commonCount,
-			final StackTraceElement[] causedTrace, final ExtendedStackTraceElement[] extStackTrace,
-			final List<String> ignorePackages, final TextRenderer textRenderer) {
-		if (ignorePackages == null || ignorePackages.isEmpty()) {
-			for (final ExtendedStackTraceElement element : extStackTrace) {
-				this.formatEntry(element, sb, prefix, textRenderer);
-			}
-		} else {
-			int count = 0;
-			for (int i = 0; i < extStackTrace.length; ++i) {
-				if (!this.ignoreElement(causedTrace[i], ignorePackages)) {
-					if (count > 0) {
-						appendSuppressedCount(sb, prefix, count, textRenderer);
-						count = 0;
-					}
-					this.formatEntry(extStackTrace[i], sb, prefix, textRenderer);
-				} else {
-					++count;
-				}
-			}
-			if (count > 0) {
-				appendSuppressedCount(sb, prefix, count, textRenderer);
-			}
-		}
-		if (commonCount != 0) {
+                                  final List<String> ignorePackages, final TextRenderer textRenderer) {
+        if (suppressedProxies == null) {
+            return;
+        }
+        for (final ThrowableProxy suppressedProxy : suppressedProxies) {
+            formatThrowableProxy(sb, prefix, SUPPRESSED_LABEL, suppressedProxy, ignorePackages, textRenderer);
+        }
+    }
+
+    private void formatElements(final StringBuilder sb, final String prefix, final int commonCount,
+                                final StackTraceElement[] causedTrace, final ExtendedStackTraceElement[] extStackTrace,
+                                final List<String> ignorePackages, final TextRenderer textRenderer) {
+        if (ignorePackages == null || ignorePackages.isEmpty()) {
+            for (final ExtendedStackTraceElement element : extStackTrace) {
+                this.formatEntry(element, sb, prefix, textRenderer);
+            }
+        } else {
+            int count = 0;
+            for (int i = 0; i < extStackTrace.length; ++i) {
+                if (!this.ignoreElement(causedTrace[i], ignorePackages)) {
+                    if (count > 0) {
+                        appendSuppressedCount(sb, prefix, count, textRenderer);
+                        count = 0;
+                    }
+                    this.formatEntry(extStackTrace[i], sb, prefix, textRenderer);
+                } else {
+                    ++count;
+                }
+            }
+            if (count > 0) {
+                appendSuppressedCount(sb, prefix, count, textRenderer);
+            }
+        }
+        if (commonCount != 0) {
             textRenderer.render(prefix, sb, "Prefix");
             textRenderer.render("\t... ", sb, "More");
             textRenderer.render(Integer.toString(commonCount), sb, "More");
             textRenderer.render(" more", sb, "More");
             textRenderer.render(EOL_STR, sb, "Text");
-		}
-	}
+        }
+    }
 
-    private void appendSuppressedCount(final StringBuilder sb, final String prefix, final int count, final TextRenderer textRenderer) {
+    private void appendSuppressedCount(final StringBuilder sb, final String prefix, final int count,
+                                       final TextRenderer textRenderer) {
         textRenderer.render(prefix, sb, "Prefix");
         if (count == 1) {
             textRenderer.render("\t... ", sb, "Suppressed");
@@ -295,7 +292,8 @@ public class ThrowableProxy implements Serializable {
         textRenderer.render(EOL_STR, sb, "Text");
     }
 
-    private void formatEntry(final ExtendedStackTraceElement extStackTraceElement, final StringBuilder sb, final String prefix, final TextRenderer textRenderer) {
+    private void formatEntry(final ExtendedStackTraceElement extStackTraceElement, final StringBuilder sb,
+                             final String prefix, final TextRenderer textRenderer) {
         textRenderer.render(prefix, sb, "Prefix");
         textRenderer.render("\tat ", sb, "At");
         extStackTraceElement.renderOn(sb, textRenderer);
@@ -304,11 +302,9 @@ public class ThrowableProxy implements Serializable {
 
     /**
      * Formats the specified Throwable.
-     * 
-     * @param sb
-     *        StringBuilder to contain the formatted Throwable.
-     * @param cause
-     *        The Throwable to format.
+     *
+     * @param sb    StringBuilder to contain the formatted Throwable.
+     * @param cause The Throwable to format.
      */
     public void formatWrapper(final StringBuilder sb, final ThrowableProxy cause) {
         this.formatWrapper(sb, cause, null, PlainTextRenderer.getInstance());
@@ -316,13 +312,10 @@ public class ThrowableProxy implements Serializable {
 
     /**
      * Formats the specified Throwable.
-     * 
-     * @param sb
-     *        StringBuilder to contain the formatted Throwable.
-     * @param cause
-     *        The Throwable to format.
-     * @param ignorePackages
-     *        The List of packages to be suppressed from the trace.
+     *
+     * @param sb             StringBuilder to contain the formatted Throwable.
+     * @param cause          The Throwable to format.
+     * @param ignorePackages The List of packages to be suppressed from the trace.
      */
     @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
     public void formatWrapper(final StringBuilder sb, final ThrowableProxy cause, final List<String> ignorePackages) {
@@ -331,18 +324,15 @@ public class ThrowableProxy implements Serializable {
 
     /**
      * Formats the specified Throwable.
-     * 
-     * @param sb
-     *            StringBuilder to contain the formatted Throwable.
-     * @param cause
-     *            The Throwable to format.
-     * @param ignorePackages
-     *            The List of packages to be suppressed from the trace.
-     * @param textRenderer
-     *            The text render
+     *
+     * @param sb             StringBuilder to contain the formatted Throwable.
+     * @param cause          The Throwable to format.
+     * @param ignorePackages The List of packages to be suppressed from the trace.
+     * @param textRenderer   The text render
      */
     @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
-    public void formatWrapper(final StringBuilder sb, final ThrowableProxy cause, final List<String> ignorePackages, final TextRenderer textRenderer) {
+    public void formatWrapper(final StringBuilder sb, final ThrowableProxy cause, final List<String> ignorePackages,
+                              final TextRenderer textRenderer) {
         final Throwable caused = cause.getCauseProxy() != null ? cause.getCauseProxy().getThrowable() : null;
         if (caused != null) {
             this.formatWrapper(sb, cause.causeProxy, ignorePackages, textRenderer);
@@ -351,7 +341,7 @@ public class ThrowableProxy implements Serializable {
         cause.renderOn(sb, textRenderer);
         textRenderer.render(EOL_STR, sb, "Text");
         this.formatElements(sb, Strings.EMPTY, cause.commonElementCount,
-                cause.getThrowable().getStackTrace(), cause.extendedStackTrace, ignorePackages, textRenderer);
+            cause.getThrowable().getStackTrace(), cause.extendedStackTrace, ignorePackages, textRenderer);
     }
 
     public ThrowableProxy getCauseProxy() {
@@ -360,7 +350,7 @@ public class ThrowableProxy implements Serializable {
 
     /**
      * Formats the Throwable that is the cause of this Throwable.
-     * 
+     *
      * @return The formatted Throwable that caused this Throwable.
      */
     public String getCauseStackTraceAsString() {
@@ -369,9 +359,8 @@ public class ThrowableProxy implements Serializable {
 
     /**
      * Formats the Throwable that is the cause of this Throwable.
-     * 
-     * @param packages
-     *        The List of packages to be suppressed from the trace.
+     *
+     * @param packages The List of packages to be suppressed from the trace.
      * @return The formatted Throwable that caused this Throwable.
      */
     public String getCauseStackTraceAsString(final List<String> packages) {
@@ -380,11 +369,9 @@ public class ThrowableProxy implements Serializable {
 
     /**
      * Formats the Throwable that is the cause of this Throwable.
-     * 
-     * @param ignorePackages
-     *            The List of packages to be suppressed from the trace.
-     * @param textRenderer
-     *            the text renderer
+     *
+     * @param ignorePackages The List of packages to be suppressed from the trace.
+     * @param textRenderer   the text renderer
      * @return The formatted Throwable that caused this Throwable.
      */
     public String getCauseStackTraceAsString(final List<String> ignorePackages, final TextRenderer textRenderer) {
@@ -396,14 +383,14 @@ public class ThrowableProxy implements Serializable {
         this.renderOn(sb, textRenderer);
         textRenderer.render(EOL_STR, sb, "Text");
         this.formatElements(sb, Strings.EMPTY, 0, this.throwable.getStackTrace(), this.extendedStackTrace,
-                ignorePackages, textRenderer);
+            ignorePackages, textRenderer);
         return sb.toString();
     }
 
     /**
      * Returns the number of elements that are being omitted because they are common with the parent Throwable's stack
      * trace.
-     * 
+     *
      * @return The number of elements omitted from the stack trace.
      */
     public int getCommonElementCount() {
@@ -412,7 +399,7 @@ public class ThrowableProxy implements Serializable {
 
     /**
      * Gets the stack trace including packaging information.
-     * 
+     *
      * @return The stack trace including packaging information.
      */
     public ExtendedStackTraceElement[] getExtendedStackTrace() {
@@ -421,7 +408,7 @@ public class ThrowableProxy implements Serializable {
 
     /**
      * Format the stack trace including packaging information.
-     * 
+     *
      * @return The formatted stack trace including packaging information.
      */
     public String getExtendedStackTraceAsString() {
@@ -430,9 +417,8 @@ public class ThrowableProxy implements Serializable {
 
     /**
      * Format the stack trace including packaging information.
-     * 
-     * @param ignorePackages
-     *        List of packages to be ignored in the trace.
+     *
+     * @param ignorePackages List of packages to be ignored in the trace.
      * @return The formatted stack trace including packaging information.
      */
     public String getExtendedStackTraceAsString(final List<String> ignorePackages) {
@@ -441,11 +427,9 @@ public class ThrowableProxy implements Serializable {
 
     /**
      * Format the stack trace including packaging information.
-     * 
-     * @param ignorePackages
-     *            List of packages to be ignored in the trace.
-     * @param textRenderer
-     *            The message renderer
+     *
+     * @param ignorePackages List of packages to be ignored in the trace.
+     * @param textRenderer   The message renderer
      * @return The formatted stack trace including packaging information.
      */
     public String getExtendedStackTraceAsString(final List<String> ignorePackages, final TextRenderer textRenderer) {
@@ -471,7 +455,7 @@ public class ThrowableProxy implements Serializable {
 
     /**
      * Return the FQCN of the Throwable.
-     * 
+     *
      * @return The FQCN of the Throwable.
      */
     public String getName() {
@@ -484,7 +468,7 @@ public class ThrowableProxy implements Serializable {
 
     /**
      * Gets proxies for suppressed exceptions.
-     * 
+     *
      * @return proxies for suppressed exceptions.
      */
     public ThrowableProxy[] getSuppressedProxies() {
@@ -493,7 +477,7 @@ public class ThrowableProxy implements Serializable {
 
     /**
      * Format the suppressed Throwables.
-     * 
+     *
      * @return The formatted suppressed Throwables.
      */
     public String getSuppressedStackTrace() {
@@ -510,7 +494,7 @@ public class ThrowableProxy implements Serializable {
 
     /**
      * The throwable or null if this object is deserialized from XML or JSON.
-     * 
+     *
      * @return The throwable or null if this object is deserialized from XML or JSON.
      */
     public Throwable getThrowable() {
@@ -543,11 +527,9 @@ public class ThrowableProxy implements Serializable {
 
     /**
      * Loads classes not located via Reflection.getCallerClass.
-     * 
-     * @param lastLoader
-     *        The ClassLoader that loaded the Class that called this Class.
-     * @param className
-     *        The name of the Class.
+     *
+     * @param lastLoader The ClassLoader that loaded the Class that called this Class.
+     * @param className  The name of the Class.
      * @return The Class object for the Class or null if it could not be located.
      */
     private Class<?> loadClass(final ClassLoader lastLoader, final String className) {
@@ -583,18 +565,14 @@ public class ThrowableProxy implements Serializable {
 
     /**
      * Construct the CacheEntry from the Class's information.
-     * 
-     * @param stackTraceElement
-     *        The stack trace element
-     * @param callerClass
-     *        The Class.
-     * @param exact
-     *        True if the class was obtained via Reflection.getCallerClass.
-     * 
+     *
+     * @param stackTraceElement The stack trace element
+     * @param callerClass       The Class.
+     * @param exact             True if the class was obtained via Reflection.getCallerClass.
      * @return The CacheEntry.
      */
     private CacheEntry toCacheEntry(final StackTraceElement stackTraceElement, final Class<?> callerClass,
-            final boolean exact) {
+                                    final boolean exact) {
         String location = "?";
         String version = "?";
         ClassLoader lastLoader = null;
@@ -631,19 +609,16 @@ public class ThrowableProxy implements Serializable {
 
     /**
      * Resolve all the stack entries in this stack trace that are not common with the parent.
-     * 
-     * @param stack
-     *        The callers Class stack.
-     * @param map
-     *        The cache of CacheEntry objects.
-     * @param rootTrace
-     *        The first stack trace resolve or null.
-     * @param stackTrace
-     *        The stack trace being resolved.
+     *
+     * @param stack      The callers Class stack.
+     * @param map        The cache of CacheEntry objects.
+     * @param rootTrace  The first stack trace resolve or null.
+     * @param stackTrace The stack trace being resolved.
      * @return The StackTracePackageElement array.
      */
     ExtendedStackTraceElement[] toExtendedStackTrace(final Stack<Class<?>> stack, final Map<String, CacheEntry> map,
-            final StackTraceElement[] rootTrace, final StackTraceElement[] stackTrace) {
+                                                     final StackTraceElement[] rootTrace,
+                                                     final StackTraceElement[] stackTrace) {
         int stackLength;
         if (rootTrace != null) {
             int rootIndex = rootTrace.length - 1;
@@ -684,7 +659,7 @@ public class ThrowableProxy implements Serializable {
                     }
                 } else {
                     final CacheEntry entry = this.toCacheEntry(stackTraceElement,
-                            this.loadClass(lastLoader, className), false);
+                        this.loadClass(lastLoader, className), false);
                     extClassInfo = entry.element;
                     map.put(stackTraceElement.toString(), entry);
                     if (entry.loader != null) {


[16/21] logging-log4j2 git commit: Wait until at least n messages show up the test or a timeout expires.

Posted by rp...@apache.org.
Wait until at least n messages show up the test or a timeout expires.

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/6e793601
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/6e793601
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/6e793601

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: 6e79360108b622c105889f9a1e2077558c61c156
Parents: 1b3c6af
Author: Gary Gregory <gg...@apache.org>
Authored: Thu Sep 8 15:11:26 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Thu Sep 8 15:11:26 2016 -0700

----------------------------------------------------------------------
 .../apache/logging/log4j/core/appender/AsyncAppenderTest.java | 4 ++--
 .../org/apache/logging/log4j/test/appender/ListAppender.java  | 7 ++++---
 2 files changed, 6 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6e793601/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
index 01beb48..cf5752b 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
@@ -80,7 +80,7 @@ public class AsyncAppenderTest {
         logger.warn("Hello world!");
         final long timeoutMillis = TIMEOUT_MILLIS;
         final TimeUnit timeUnit = TimeUnit.MILLISECONDS;
-        final List<String> list = listAppender.getMessages(timeoutMillis, timeUnit);
+        final List<String> list = listAppender.getMessages(2, timeoutMillis, timeUnit);
         assertNotNull("No events generated", list);
         assertTrue("Incorrect number of events after " + timeoutMillis + " " + timeUnit + ". Expected 2, got "
                 + list.size(), list.size() == 2);
@@ -100,7 +100,7 @@ public class AsyncAppenderTest {
         logger.error("This is a test", child);
         final long timeoutMillis = TIMEOUT_MILLIS;
         final TimeUnit timeUnit = TimeUnit.MILLISECONDS;
-        final List<String> list = listAppender.getMessages(timeoutMillis, timeUnit);
+        final List<String> list = listAppender.getMessages(1, timeoutMillis, timeUnit);
         assertNotNull("No events generated", list);
         assertTrue("Incorrect number of events after " + timeoutMillis + " " + timeUnit + ". Expected 1, got "
                 + list.size(), list.size() == 1);

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6e793601/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/ListAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/ListAppender.java b/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/ListAppender.java
index 68ee55d..2efaaca 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/ListAppender.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/ListAppender.java
@@ -175,11 +175,12 @@ public class ListAppender extends AbstractAppender {
     }
 
     /**
-     * Polls the messages for at most timeout timeUnits and return a copy of what we have so far. 
+     * Polls the messages list for it to grow to a given minimum size at most timeout timeUnits and return a copy of
+     * what we have so far.
      */
-    public List<String> getMessages(long timeout, TimeUnit timeUnit) throws InterruptedException {
+    public List<String> getMessages(int minSize, long timeout, TimeUnit timeUnit) throws InterruptedException {
         final long endMillis = System.currentTimeMillis() + timeUnit.toMillis(timeout);
-        while (messages.isEmpty() && System.currentTimeMillis() < endMillis) {
+        while (messages.size() < minSize && System.currentTimeMillis() < endMillis) {
             Thread.sleep(100);
         }
         return Collections.unmodifiableList(messages);


[04/21] logging-log4j2 git commit: Fix class loader deadlock when using async logging and extended stack trace pattern

Posted by rp...@apache.org.
Fix class loader deadlock when using async logging and extended stack trace pattern

This fixes LOG4J2-1457.


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/284067cb
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/284067cb
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/284067cb

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: 284067cbdb5f13c41225e22c2a60d79cd43f1383
Parents: 99c0d01
Author: Matt Sicker <bo...@gmail.com>
Authored: Thu Sep 8 10:30:12 2016 -0500
Committer: Matt Sicker <bo...@gmail.com>
Committed: Thu Sep 8 10:30:12 2016 -0500

----------------------------------------------------------------------
 .../logging/log4j/core/impl/ThrowableProxy.java |  9 ++--
 .../async/AsyncLoggerClassLoadDeadlock.java     | 32 ++++++++++++++
 .../async/AsyncLoggerClassLoadDeadlockTest.java | 45 ++++++++++++++++++++
 .../test/resources/AsyncLoggerConsoleTest.xml   | 16 +++++++
 src/changes/changes.xml                         |  3 ++
 5 files changed, 100 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/284067cb/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableProxy.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableProxy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableProxy.java
index a052e4d..e12e14a 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableProxy.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableProxy.java
@@ -30,7 +30,6 @@ import java.util.Stack;
 
 import org.apache.logging.log4j.core.pattern.PlainTextRenderer;
 import org.apache.logging.log4j.core.pattern.TextRenderer;
-import org.apache.logging.log4j.core.util.Loader;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.util.LoaderUtil;
 import org.apache.logging.log4j.util.ReflectionUtil;
@@ -537,7 +536,7 @@ public class ThrowableProxy implements Serializable {
         Class<?> clazz;
         if (lastLoader != null) {
             try {
-                clazz = Loader.initializeClass(className, lastLoader);
+                clazz = lastLoader.loadClass(className);
                 if (clazz != null) {
                     return clazz;
                 }
@@ -548,16 +547,16 @@ public class ThrowableProxy implements Serializable {
         try {
             clazz = LoaderUtil.loadClass(className);
         } catch (final ClassNotFoundException | NoClassDefFoundError e) {
-            return initializeClass(className);
+            return loadClass(className);
         } catch (final SecurityException e) {
             return null;
         }
         return clazz;
     }
 
-    private Class<?> initializeClass(final String className) {
+    private Class<?> loadClass(final String className) {
         try {
-            return Loader.initializeClass(className, this.getClass().getClassLoader());
+            return this.getClass().getClassLoader().loadClass(className);
         } catch (final ClassNotFoundException | NoClassDefFoundError | SecurityException e) {
             return null;
         }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/284067cb/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerClassLoadDeadlock.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerClassLoadDeadlock.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerClassLoadDeadlock.java
new file mode 100644
index 0000000..f8341f9
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerClassLoadDeadlock.java
@@ -0,0 +1,32 @@
+/*
+ * 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.logging.log4j.core.async;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+class AsyncLoggerClassLoadDeadlock {
+    static {
+        final Logger log = LogManager.getLogger("com.foo.bar.deadlock");
+        final Exception e = new Exception();
+        // the key to reproducing the problem is to fill up the ring buffer so that
+        // log.info call will block on ring buffer as well
+        for (int i = 0; i < AsyncLoggerClassLoadDeadlockTest.RING_BUFFER_SIZE * 2; ++i) {
+            log.info("clinit", e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/284067cb/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerClassLoadDeadlockTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerClassLoadDeadlockTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerClassLoadDeadlockTest.java
new file mode 100644
index 0000000..990312d
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerClassLoadDeadlockTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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.logging.log4j.core.async;
+
+import org.apache.logging.log4j.core.config.ConfigurationFactory;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Test class loading deadlock condition from the LOG4J2-1457
+ */
+public class AsyncLoggerClassLoadDeadlockTest {
+
+    static final int RING_BUFFER_SIZE = 128;
+
+    @BeforeClass
+    public static void beforeClass() {
+        System.setProperty("Log4jContextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector");
+        System.setProperty("AsyncLogger.RingBufferSize", String.valueOf(RING_BUFFER_SIZE));
+        System.setProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY, "AsyncLoggerConsoleTest.xml");
+    }
+
+    @Test(timeout = 30000)
+    public void testClassLoaderDeadlock() throws Exception {
+        //touch the class so static init will be called
+        final AsyncLoggerClassLoadDeadlock temp = new AsyncLoggerClassLoadDeadlock();
+        assertNotNull(temp);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/284067cb/log4j-core/src/test/resources/AsyncLoggerConsoleTest.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/AsyncLoggerConsoleTest.xml b/log4j-core/src/test/resources/AsyncLoggerConsoleTest.xml
new file mode 100644
index 0000000..90f4e9e
--- /dev/null
+++ b/log4j-core/src/test/resources/AsyncLoggerConsoleTest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="warn">
+  <Appenders>
+    <Console name="Console" target="SYSTEM_OUT">
+      <PatternLayout>
+        <pattern>%xEx{0}</pattern>
+      </PatternLayout>
+    </Console>
+  </Appenders>
+
+  <Loggers>
+    <Root level="info">
+      <AppenderRef ref="Console"/>
+    </Root>
+  </Loggers>
+</Configuration>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/284067cb/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 2bfc311..fa53129 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -24,6 +24,9 @@
   </properties>
   <body>
     <release version="2.7" date="2016-MM-DD" description="GA Release 2.7">
+      <action issue="LOG4J2-1457" dev="mattsicker" type="fix" due-to="Leon Finker">
+        Class loader deadlock when using async logging and extended stack trace pattern.
+      </action>
       <action issue="LOG4J2-1563" dev="ggregory" type="fix" due-to="Jason Tedor">
         Log4j 2.6.2 can lose exceptions when a security manager is present.
       </action>