This is an automated email from the ASF dual-hosted git repository.

pkarwasz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git


The following commit(s) were added to refs/heads/main by this push:
     new 108361a559 Renormalize Java file line endings
108361a559 is described below

commit 108361a5593d8240b06df6ecd8571c7ce389b278
Author: Piotr P. Karwasz <[email protected]>
AuthorDate: Wed Mar 29 17:56:55 2023 +0200

    Renormalize Java file line endings
    
    This also runs `spotless:apply` on the modified files.
---
 .gitattributes                                     |   4 +
 .../org/apache/log4j/CallerInformationTest.java    | 130 ++--
 .../test/java/org/apache/log4j/LoggingTest.java    |  82 +--
 .../org/apache/log4j/config/StartsWithFilter.java  |  76 +--
 .../apache/logging/log4j/message/EntryMessage.java |  52 +-
 .../apache/logging/log4j/message/ExitMessage.java  |  52 +-
 .../apache/logging/log4j/message/FlowMessage.java  |  78 +--
 .../log4j/flume/appender/FlumeAvroManager.java     | 698 ++++++++++-----------
 .../logging/log4j/io/AbstractStreamTest.java       | 117 ++--
 .../log4j/io/IoBuilderCallerInfoTesting.java       | 110 ++--
 .../org/apache/logging/log4j/io/IoBuilderTest.java | 102 +--
 .../log4j/io/LoggerPrintWriterJdbcH2Test.java      | 192 +++---
 .../logging/log4j/jcl/CallerInformationTest.java   | 134 ++--
 .../apache/logging/log4j/jul/ApiLoggerAdapter.java |  79 ++-
 .../logging/log4j/jul/CoreLoggerAdapter.java       |  85 ++-
 .../logging/log4j/jul/Log4jBridgeHandler.java      | 638 +++++++++----------
 .../liquibase/ext/logging/log4j2/Log4j2Logger.java | 186 +++---
 .../apache/logging/log4j/taglib/DumpTagTest.java   | 243 ++++---
 .../logging/slf4j/CallerInformationTest.java       | 131 ++--
 .../apache/logging/slf4j/LoggerContextRule.java    | 145 ++---
 20 files changed, 1668 insertions(+), 1666 deletions(-)

diff --git a/.gitattributes b/.gitattributes
index d48d4da3e0..bc0e569cbc 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -12,6 +12,10 @@
 # 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.
+
+# All text files with LF line endings
+* text=auto eol=lf
+# Maven Wrapper cmd script
 /mvnw.cmd eol=crlf
 # Maven Wrapper need LF line endings
 /.mvn/wrapper/maven-wrapper.properties eol=lf
diff --git 
a/log4j-1.2-api/src/test/java/org/apache/log4j/CallerInformationTest.java 
b/log4j-1.2-api/src/test/java/org/apache/log4j/CallerInformationTest.java
index fd35e4a9c7..b9d0b84a45 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/CallerInformationTest.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/CallerInformationTest.java
@@ -1,65 +1,65 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.log4j;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.List;
-
-import org.apache.logging.log4j.core.test.junit.LoggerContextRule;
-import org.apache.logging.log4j.core.test.appender.ListAppender;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-public class CallerInformationTest {
-
-    // config from log4j-core test-jar
-    private static final String CONFIG = "log4j2-calling-class.xml";
-
-    @ClassRule
-    public static final LoggerContextRule ctx = new LoggerContextRule(CONFIG);
-
-    @Test
-    public void testClassLogger() {
-        final ListAppender app = ctx.getListAppender("Class").clear();
-        final Logger logger = Logger.getLogger("ClassLogger");
-        logger.info("Ignored message contents.");
-        logger.warn("Verifying the caller class is still correct.");
-        logger.error("Hopefully nobody breaks me!");
-        final List<String> messages = app.getMessages();
-        assertEquals("Incorrect number of messages.", 3, messages.size());
-        for (final String message : messages) {
-            assertEquals("Incorrect caller class name.", 
this.getClass().getName(), message);
-        }
-    }
-
-    @Test
-    public void testMethodLogger() {
-        final ListAppender app = ctx.getListAppender("Method").clear();
-        final Logger logger = Logger.getLogger("MethodLogger");
-        logger.info("More messages.");
-        logger.warn("CATASTROPHE INCOMING!");
-        logger.error("ZOMBIES!!!");
-        logger.warn("brains~~~");
-        logger.info("Itchy. Tasty.");
-        final List<String> messages = app.getMessages();
-        assertEquals("Incorrect number of messages.", 5, messages.size());
-        for (final String message : messages) {
-            assertEquals("Incorrect caller method name.", "testMethodLogger", 
message);
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.log4j;
+
+import java.util.List;
+
+import org.apache.logging.log4j.core.test.appender.ListAppender;
+import org.apache.logging.log4j.core.test.junit.LoggerContextRule;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class CallerInformationTest {
+
+    // config from log4j-core test-jar
+    private static final String CONFIG = "log4j2-calling-class.xml";
+
+    @ClassRule
+    public static final LoggerContextRule ctx = new LoggerContextRule(CONFIG);
+
+    @Test
+    public void testClassLogger() {
+        final ListAppender app = ctx.getListAppender("Class").clear();
+        final Logger logger = Logger.getLogger("ClassLogger");
+        logger.info("Ignored message contents.");
+        logger.warn("Verifying the caller class is still correct.");
+        logger.error("Hopefully nobody breaks me!");
+        final List<String> messages = app.getMessages();
+        assertEquals("Incorrect number of messages.", 3, messages.size());
+        for (final String message : messages) {
+            assertEquals("Incorrect caller class name.", 
this.getClass().getName(), message);
+        }
+    }
+
+    @Test
+    public void testMethodLogger() {
+        final ListAppender app = ctx.getListAppender("Method").clear();
+        final Logger logger = Logger.getLogger("MethodLogger");
+        logger.info("More messages.");
+        logger.warn("CATASTROPHE INCOMING!");
+        logger.error("ZOMBIES!!!");
+        logger.warn("brains~~~");
+        logger.info("Itchy. Tasty.");
+        final List<String> messages = app.getMessages();
+        assertEquals("Incorrect number of messages.", 5, messages.size());
+        for (final String message : messages) {
+            assertEquals("Incorrect caller method name.", "testMethodLogger", 
message);
+        }
+    }
+}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/LoggingTest.java 
b/log4j-1.2-api/src/test/java/org/apache/log4j/LoggingTest.java
index e72f3bec7c..edfbe43f61 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/LoggingTest.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/LoggingTest.java
@@ -1,41 +1,41 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.log4j;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
-import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
-import org.junit.jupiter.api.Test;
-
-/**
- *
- */
-public class LoggingTest {
-
-    private static final String CONFIG = "log4j2-config.xml";
-
-    @Test
-    @LoggerContextSource(CONFIG)
-    public void testParent() {
-        final Logger logger = Logger.getLogger("org.apache.test.logging.Test");
-        final Category parent = logger.getParent();
-        assertNotNull(parent, "No parent Logger");
-        assertEquals("org.apache.test.logging", parent.getName(), "Incorrect 
parent logger");
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.log4j;
+
+import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ *
+ */
+public class LoggingTest {
+
+    private static final String CONFIG = "log4j2-config.xml";
+
+    @Test
+    @LoggerContextSource(CONFIG)
+    public void testParent() {
+        final Logger logger = Logger.getLogger("org.apache.test.logging.Test");
+        final Category parent = logger.getParent();
+        assertNotNull(parent, "No parent Logger");
+        assertEquals("org.apache.test.logging", parent.getName(), "Incorrect 
parent logger");
+    }
+
+}
diff --git 
a/log4j-1.2-api/src/test/java/org/apache/log4j/config/StartsWithFilter.java 
b/log4j-1.2-api/src/test/java/org/apache/log4j/config/StartsWithFilter.java
index db16d84f65..7fcc632962 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/config/StartsWithFilter.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/config/StartsWithFilter.java
@@ -1,38 +1,38 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.log4j.config;
-
-import org.apache.log4j.spi.Filter;
-import org.apache.log4j.spi.LoggingEvent;
-
-/**
- * A Filter used in tests.
- */
-public class StartsWithFilter extends Filter {
-
-    @Override
-    public int decide(LoggingEvent event) {
-        String message = String.valueOf(event.getMessage());
-        if (message.startsWith("DENY")) {
-            return DENY;
-        } else if (message.startsWith("ACCEPT")) {
-            return ACCEPT;
-        }
-        return NEUTRAL;
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.log4j.config;
+
+import org.apache.log4j.spi.Filter;
+import org.apache.log4j.spi.LoggingEvent;
+
+/**
+ * A Filter used in tests.
+ */
+public class StartsWithFilter extends Filter {
+
+    @Override
+    public int decide(LoggingEvent event) {
+        String message = String.valueOf(event.getMessage());
+        if (message.startsWith("DENY")) {
+            return DENY;
+        } else if (message.startsWith("ACCEPT")) {
+            return ACCEPT;
+        }
+        return NEUTRAL;
+    }
+
+}
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/message/EntryMessage.java 
b/log4j-api/src/main/java/org/apache/logging/log4j/message/EntryMessage.java
index c00bd4c2e1..fe8bcc1457 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/EntryMessage.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/EntryMessage.java
@@ -1,26 +1,26 @@
-/*
- * 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.message;
-
-/**
- * Entry flow messages
- * 
- * @since 2.6
- */
-public interface EntryMessage extends FlowMessage {
-    // empty
-}
+/*
+ * 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.message;
+
+/**
+ * Entry flow messages
+ *
+ * @since 2.6
+ */
+public interface EntryMessage extends FlowMessage {
+    // empty
+}
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/message/ExitMessage.java 
b/log4j-api/src/main/java/org/apache/logging/log4j/message/ExitMessage.java
index 48722f6485..9e1f23c0a2 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/ExitMessage.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/ExitMessage.java
@@ -1,26 +1,26 @@
-/*
- * 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.message;
-
-/**
- * Exit flow messages
- * 
- * @since 2.6
- */
-public interface ExitMessage extends FlowMessage {
-    // empty
-}
+/*
+ * 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.message;
+
+/**
+ * Exit flow messages
+ *
+ * @since 2.6
+ */
+public interface ExitMessage extends FlowMessage {
+    // empty
+}
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/message/FlowMessage.java 
b/log4j-api/src/main/java/org/apache/logging/log4j/message/FlowMessage.java
index c6d180d622..d708c305f5 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/FlowMessage.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/FlowMessage.java
@@ -1,39 +1,39 @@
-/*
- * 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.message;
-
-/**
- * Flow messages
- * 
- * @since 2.6
- */
-public interface FlowMessage extends Message {
-
-    /**
-     * The message text like "Enter" or "Exit" used to prefix the actual 
Message.
-     * 
-     * @return message text used to prefix the actual Message.
-     */
-    String getText();
-
-    /**
-     * The wrapped message
-     * 
-     * @return the wrapped message
-     */
-    Message getMessage();
-}
+/*
+ * 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.message;
+
+/**
+ * Flow messages
+ *
+ * @since 2.6
+ */
+public interface FlowMessage extends Message {
+
+    /**
+     * The message text like "Enter" or "Exit" used to prefix the actual 
Message.
+     *
+     * @return message text used to prefix the actual Message.
+     */
+    String getText();
+
+    /**
+     * The wrapped message
+     *
+     * @return the wrapped message
+     */
+    Message getMessage();
+}
diff --git 
a/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeAvroManager.java
 
b/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeAvroManager.java
index 1dac69836e..9f6222ce97 100644
--- 
a/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeAvroManager.java
+++ 
b/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeAvroManager.java
@@ -1,349 +1,349 @@
-/*
- * 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.flume.appender;
-
-import java.util.Properties;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.flume.Event;
-import org.apache.flume.api.RpcClient;
-import org.apache.flume.api.RpcClientFactory;
-import org.apache.logging.log4j.core.appender.AppenderLoggingException;
-import org.apache.logging.log4j.core.appender.ManagerFactory;
-
-/**
- * Manager for FlumeAvroAppenders.
- */
-public class FlumeAvroManager extends AbstractFlumeManager {
-
-    private static final int MAX_RECONNECTS = 3;
-    private static final int MINIMUM_TIMEOUT = 1000;
-
-    private static final AvroManagerFactory factory = new AvroManagerFactory();
-
-    private final Agent[] agents;
-
-    private final int batchSize;
-
-    private final long delayNanos;
-    private final int delayMillis;
-
-    private final int retries;
-
-    private final int connectTimeoutMillis;
-
-    private final int requestTimeoutMillis;
-
-    private final int current = 0;
-
-    private volatile RpcClient rpcClient;
-
-    private BatchEvent batchEvent = new BatchEvent();
-    private long nextSend = 0;
-
-    /**
-     * Constructor
-     * @param name The unique name of this manager.
-     * @param agents An array of Agents.
-     * @param batchSize The number of events to include in a batch.
-     * @param retries The number of times to retry connecting before giving up.
-     * @param connectTimeout The connection timeout in ms.
-     * @param requestTimeout The request timeout in ms.
-     *
-     */
-    protected FlumeAvroManager(final String name, final String shortName, 
final Agent[] agents, final int batchSize,
-                               final int delayMillis, final int retries, final 
int connectTimeout, final int requestTimeout) {
-        super(name);
-        this.agents = agents;
-        this.batchSize = batchSize;
-        this.delayMillis = delayMillis;
-        this.delayNanos = TimeUnit.MILLISECONDS.toNanos(delayMillis);
-        this.retries = retries;
-        this.connectTimeoutMillis = connectTimeout;
-        this.requestTimeoutMillis = requestTimeout;
-        this.rpcClient = connect(agents, retries, connectTimeout, 
requestTimeout);
-    }
-
-    /**
-     * Returns a FlumeAvroManager.
-     * @param name The name of the manager.
-     * @param agents The agents to use.
-     * @param batchSize The number of events to include in a batch.
-     * @param delayMillis The number of milliseconds to wait before sending an 
incomplete batch.
-     * @param retries The number of times to retry connecting before giving up.
-     * @param connectTimeoutMillis The connection timeout in ms.
-     * @param requestTimeoutMillis The request timeout in ms.
-     * @return A FlumeAvroManager.
-     */
-    public static FlumeAvroManager getManager(final String name, final Agent[] 
agents, int batchSize, final int delayMillis,
-                                              final int retries, final int 
connectTimeoutMillis, final int requestTimeoutMillis) {
-        if (agents == null || agents.length == 0) {
-            throw new IllegalArgumentException("At least one agent is 
required");
-        }
-
-        if (batchSize <= 0) {
-            batchSize = 1;
-        };
-        final StringBuilder sb = new StringBuilder(name);
-        sb.append(" FlumeAvro[");
-        boolean first = true;
-        for (final Agent agent : agents) {
-            if (!first) {
-                sb.append(',');
-            }
-            sb.append(agent.getHost()).append(':').append(agent.getPort());
-            first = false;
-        }
-        sb.append(']');
-        return getManager(sb.toString(), factory,
-                new FactoryData(name, agents, batchSize, delayMillis, retries, 
connectTimeoutMillis, requestTimeoutMillis));
-    }
-
-    /**
-     * Returns the agents.
-     * @return The agent array.
-     */
-    public Agent[] getAgents() {
-        return agents;
-    }
-
-    /**
-     * Returns the index of the current agent.
-     * @return The index for the current agent.
-     */
-    public int getCurrent() {
-        return current;
-    }
-
-    public int getRetries() {
-        return retries;
-    }
-
-    public int getConnectTimeoutMillis() {
-        return connectTimeoutMillis;
-    }
-
-    public int getRequestTimeoutMillis() {
-        return requestTimeoutMillis;
-    }
-
-    public int getBatchSize() {
-        return batchSize;
-    }
-
-    public int getDelayMillis() {
-        return delayMillis;
-    }
-
-    public void send(final BatchEvent events) {
-        if (rpcClient == null) {
-            synchronized (this) {
-                if (rpcClient == null) {
-                    rpcClient = connect(agents, retries, connectTimeoutMillis, 
requestTimeoutMillis);
-                }
-            }
-        }
-
-        if (rpcClient != null) {
-            try {
-                LOGGER.trace("Sending batch of {} events", 
events.getEvents().size());
-                rpcClient.appendBatch(events.getEvents());
-            } catch (final Exception ex) {
-                rpcClient.close();
-                rpcClient = null;
-                final String msg = "Unable to write to " + getName() + " at " 
+ agents[current].getHost() + ':' +
-                    agents[current].getPort();
-                LOGGER.warn(msg, ex);
-                throw new AppenderLoggingException("No Flume agents are 
available");
-            }
-        }  else {
-            final String msg = "Unable to write to " + getName() + " at " + 
agents[current].getHost() + ':' +
-                agents[current].getPort();
-            LOGGER.warn(msg);
-            throw new AppenderLoggingException("No Flume agents are 
available");
-        }
-    }
-
-    @Override
-    public void send(final Event event)  {
-        if (batchSize == 1) {
-            if (rpcClient == null) {
-                rpcClient = connect(agents, retries, connectTimeoutMillis, 
requestTimeoutMillis);
-            }
-
-            if (rpcClient != null) {
-                try {
-                    rpcClient.append(event);
-                } catch (final Exception ex) {
-                    rpcClient.close();
-                    rpcClient = null;
-                    final String msg = "Unable to write to " + getName() + " 
at " + agents[current].getHost() + ':' +
-                            agents[current].getPort();
-                    LOGGER.warn(msg, ex);
-                    throw new AppenderLoggingException("No Flume agents are 
available");
-                }
-            } else {
-                final String msg = "Unable to write to " + getName() + " at " 
+ agents[current].getHost() + ':' +
-                        agents[current].getPort();
-                LOGGER.warn(msg);
-                throw new AppenderLoggingException("No Flume agents are 
available");
-            }
-        } else {
-            int eventCount;
-            BatchEvent batch = null;
-            synchronized(batchEvent) {
-                batchEvent.addEvent(event);
-                eventCount = batchEvent.size();
-                long now = System.nanoTime();
-                if (eventCount == 1) {
-                    nextSend = now + delayNanos;
-                }
-                if (eventCount >= batchSize || now >= nextSend) {
-                    batch = batchEvent;
-                    batchEvent = new BatchEvent();
-                }
-            }
-            if (batch != null) {
-                send(batch);
-            }
-        }
-    }
-
-    /**
-     * There is a very good chance that this will always return the first 
agent even if it isn't available.
-     * @param agents The list of agents to choose from
-     * @return The FlumeEventAvroServer.
-     */
-    private RpcClient connect(final Agent[] agents, int retries, final int 
connectTimeoutMillis, final int requestTimeoutMillis) {
-        try {
-            final Properties props = new Properties();
-
-            props.put("client.type", "default_failover");
-
-            int agentCount = 1;
-            final StringBuilder sb = new StringBuilder();
-            for (final Agent agent : agents) {
-                if (sb.length() > 0) {
-                    sb.append(' ');
-                }
-                final String hostName = "host" + agentCount++;
-                props.put("hosts." + hostName, agent.getHost() + ':' + 
agent.getPort());
-                sb.append(hostName);
-            }
-            props.put("hosts", sb.toString());
-            if (batchSize > 0) {
-                props.put("batch-size", Integer.toString(batchSize));
-            }
-            if (retries > 1) {
-                if (retries > MAX_RECONNECTS) {
-                    retries = MAX_RECONNECTS;
-                }
-                props.put("max-attempts", Integer.toString(retries * 
agents.length));
-            }
-            if (requestTimeoutMillis >= MINIMUM_TIMEOUT) {
-                props.put("request-timeout", 
Integer.toString(requestTimeoutMillis));
-            }
-            if (connectTimeoutMillis >= MINIMUM_TIMEOUT) {
-                props.put("connect-timeout", 
Integer.toString(connectTimeoutMillis));
-            }
-            return RpcClientFactory.getInstance(props);
-        } catch (final Exception ex) {
-            LOGGER.error("Unable to create Flume RPCClient: {}", 
ex.getMessage());
-            return null;
-        }
-    }
-
-    @Override
-    protected boolean releaseSub(final long timeout, final TimeUnit timeUnit) {
-       boolean closed = true;
-        if (rpcClient != null) {
-            try {
-                synchronized(this) {
-                    try {
-                        if (batchSize > 1 && batchEvent.getEvents().size() > 
0) {
-                            send(batchEvent);
-                        }
-                    } catch (final Exception ex) {
-                        LOGGER.error("Error sending final batch: {}", 
ex.getMessage());
-                        closed = false;
-                    }
-                }
-                rpcClient.close();
-            } catch (final Exception ex) {
-                LOGGER.error("Attempt to close RPC client failed", ex);
-                closed = false;
-            }
-        }
-        rpcClient = null;
-        return closed;
-    }
-
-    /**
-     * Factory data.
-     */
-    private static class FactoryData {
-        private final String name;
-        private final Agent[] agents;
-        private final int batchSize;
-        private final int delayMillis;
-        private final int retries;
-        private final int conntectTimeoutMillis;
-        private final int requestTimeoutMillis;
-
-        /**
-         * Constructor.
-         * @param name The name of the Appender.
-         * @param agents The agents.
-         * @param batchSize The number of events to include in a batch.
-         */
-        public FactoryData(final String name, final Agent[] agents, final int 
batchSize, final int delayMillis,
-                final int retries, final int connectTimeoutMillis, final int 
requestTimeoutMillis) {
-            this.name = name;
-            this.agents = agents;
-            this.batchSize = batchSize;
-            this.delayMillis = delayMillis;
-            this.retries = retries;
-            this.conntectTimeoutMillis = connectTimeoutMillis;
-            this.requestTimeoutMillis = requestTimeoutMillis;
-        }
-    }
-
-    /**
-     * Avro Manager Factory.
-     */
-    private static class AvroManagerFactory implements 
ManagerFactory<FlumeAvroManager, FactoryData> {
-
-        /**
-         * Create the FlumeAvroManager.
-         * @param name The name of the entity to manage.
-         * @param data The data required to create the entity.
-         * @return The FlumeAvroManager.
-         */
-        @Override
-        public FlumeAvroManager createManager(final String name, final 
FactoryData data) {
-            try {
-
-                return new FlumeAvroManager(name, data.name, data.agents, 
data.batchSize, data.delayMillis,
-                        data.retries, data.conntectTimeoutMillis, 
data.requestTimeoutMillis);
-            } catch (final Exception ex) {
-                LOGGER.error("Could not create FlumeAvroManager", 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.flume.appender;
+
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.flume.Event;
+import org.apache.flume.api.RpcClient;
+import org.apache.flume.api.RpcClientFactory;
+import org.apache.logging.log4j.core.appender.AppenderLoggingException;
+import org.apache.logging.log4j.core.appender.ManagerFactory;
+
+/**
+ * Manager for FlumeAvroAppenders.
+ */
+public class FlumeAvroManager extends AbstractFlumeManager {
+
+    private static final int MAX_RECONNECTS = 3;
+    private static final int MINIMUM_TIMEOUT = 1000;
+
+    private static final AvroManagerFactory factory = new AvroManagerFactory();
+
+    private final Agent[] agents;
+
+    private final int batchSize;
+
+    private final long delayNanos;
+    private final int delayMillis;
+
+    private final int retries;
+
+    private final int connectTimeoutMillis;
+
+    private final int requestTimeoutMillis;
+
+    private final int current = 0;
+
+    private volatile RpcClient rpcClient;
+
+    private BatchEvent batchEvent = new BatchEvent();
+    private long nextSend = 0;
+
+    /**
+     * Constructor
+     * @param name The unique name of this manager.
+     * @param agents An array of Agents.
+     * @param batchSize The number of events to include in a batch.
+     * @param retries The number of times to retry connecting before giving up.
+     * @param connectTimeout The connection timeout in ms.
+     * @param requestTimeout The request timeout in ms.
+     *
+     */
+    protected FlumeAvroManager(final String name, final String shortName, 
final Agent[] agents, final int batchSize,
+                               final int delayMillis, final int retries, final 
int connectTimeout, final int requestTimeout) {
+        super(name);
+        this.agents = agents;
+        this.batchSize = batchSize;
+        this.delayMillis = delayMillis;
+        this.delayNanos = TimeUnit.MILLISECONDS.toNanos(delayMillis);
+        this.retries = retries;
+        this.connectTimeoutMillis = connectTimeout;
+        this.requestTimeoutMillis = requestTimeout;
+        this.rpcClient = connect(agents, retries, connectTimeout, 
requestTimeout);
+    }
+
+    /**
+     * Returns a FlumeAvroManager.
+     * @param name The name of the manager.
+     * @param agents The agents to use.
+     * @param batchSize The number of events to include in a batch.
+     * @param delayMillis The number of milliseconds to wait before sending an 
incomplete batch.
+     * @param retries The number of times to retry connecting before giving up.
+     * @param connectTimeoutMillis The connection timeout in ms.
+     * @param requestTimeoutMillis The request timeout in ms.
+     * @return A FlumeAvroManager.
+     */
+    public static FlumeAvroManager getManager(final String name, final Agent[] 
agents, int batchSize, final int delayMillis,
+                                              final int retries, final int 
connectTimeoutMillis, final int requestTimeoutMillis) {
+        if (agents == null || agents.length == 0) {
+            throw new IllegalArgumentException("At least one agent is 
required");
+        }
+
+        if (batchSize <= 0) {
+            batchSize = 1;
+        };
+        final StringBuilder sb = new StringBuilder(name);
+        sb.append(" FlumeAvro[");
+        boolean first = true;
+        for (final Agent agent : agents) {
+            if (!first) {
+                sb.append(',');
+            }
+            sb.append(agent.getHost()).append(':').append(agent.getPort());
+            first = false;
+        }
+        sb.append(']');
+        return getManager(sb.toString(), factory,
+                new FactoryData(name, agents, batchSize, delayMillis, retries, 
connectTimeoutMillis, requestTimeoutMillis));
+    }
+
+    /**
+     * Returns the agents.
+     * @return The agent array.
+     */
+    public Agent[] getAgents() {
+        return agents;
+    }
+
+    /**
+     * Returns the index of the current agent.
+     * @return The index for the current agent.
+     */
+    public int getCurrent() {
+        return current;
+    }
+
+    public int getRetries() {
+        return retries;
+    }
+
+    public int getConnectTimeoutMillis() {
+        return connectTimeoutMillis;
+    }
+
+    public int getRequestTimeoutMillis() {
+        return requestTimeoutMillis;
+    }
+
+    public int getBatchSize() {
+        return batchSize;
+    }
+
+    public int getDelayMillis() {
+        return delayMillis;
+    }
+
+    public void send(final BatchEvent events) {
+        if (rpcClient == null) {
+            synchronized (this) {
+                if (rpcClient == null) {
+                    rpcClient = connect(agents, retries, connectTimeoutMillis, 
requestTimeoutMillis);
+                }
+            }
+        }
+
+        if (rpcClient != null) {
+            try {
+                LOGGER.trace("Sending batch of {} events", 
events.getEvents().size());
+                rpcClient.appendBatch(events.getEvents());
+            } catch (final Exception ex) {
+                rpcClient.close();
+                rpcClient = null;
+                final String msg = "Unable to write to " + getName() + " at " 
+ agents[current].getHost() + ':' +
+                    agents[current].getPort();
+                LOGGER.warn(msg, ex);
+                throw new AppenderLoggingException("No Flume agents are 
available");
+            }
+        }  else {
+            final String msg = "Unable to write to " + getName() + " at " + 
agents[current].getHost() + ':' +
+                agents[current].getPort();
+            LOGGER.warn(msg);
+            throw new AppenderLoggingException("No Flume agents are 
available");
+        }
+    }
+
+    @Override
+    public void send(final Event event)  {
+        if (batchSize == 1) {
+            if (rpcClient == null) {
+                rpcClient = connect(agents, retries, connectTimeoutMillis, 
requestTimeoutMillis);
+            }
+
+            if (rpcClient != null) {
+                try {
+                    rpcClient.append(event);
+                } catch (final Exception ex) {
+                    rpcClient.close();
+                    rpcClient = null;
+                    final String msg = "Unable to write to " + getName() + " 
at " + agents[current].getHost() + ':' +
+                            agents[current].getPort();
+                    LOGGER.warn(msg, ex);
+                    throw new AppenderLoggingException("No Flume agents are 
available");
+                }
+            } else {
+                final String msg = "Unable to write to " + getName() + " at " 
+ agents[current].getHost() + ':' +
+                        agents[current].getPort();
+                LOGGER.warn(msg);
+                throw new AppenderLoggingException("No Flume agents are 
available");
+            }
+        } else {
+            int eventCount;
+            BatchEvent batch = null;
+            synchronized(batchEvent) {
+                batchEvent.addEvent(event);
+                eventCount = batchEvent.size();
+                long now = System.nanoTime();
+                if (eventCount == 1) {
+                    nextSend = now + delayNanos;
+                }
+                if (eventCount >= batchSize || now >= nextSend) {
+                    batch = batchEvent;
+                    batchEvent = new BatchEvent();
+                }
+            }
+            if (batch != null) {
+                send(batch);
+            }
+        }
+    }
+
+    /**
+     * There is a very good chance that this will always return the first 
agent even if it isn't available.
+     * @param agents The list of agents to choose from
+     * @return The FlumeEventAvroServer.
+     */
+    private RpcClient connect(final Agent[] agents, int retries, final int 
connectTimeoutMillis, final int requestTimeoutMillis) {
+        try {
+            final Properties props = new Properties();
+
+            props.put("client.type", "default_failover");
+
+            int agentCount = 1;
+            final StringBuilder sb = new StringBuilder();
+            for (final Agent agent : agents) {
+                if (sb.length() > 0) {
+                    sb.append(' ');
+                }
+                final String hostName = "host" + agentCount++;
+                props.put("hosts." + hostName, agent.getHost() + ':' + 
agent.getPort());
+                sb.append(hostName);
+            }
+            props.put("hosts", sb.toString());
+            if (batchSize > 0) {
+                props.put("batch-size", Integer.toString(batchSize));
+            }
+            if (retries > 1) {
+                if (retries > MAX_RECONNECTS) {
+                    retries = MAX_RECONNECTS;
+                }
+                props.put("max-attempts", Integer.toString(retries * 
agents.length));
+            }
+            if (requestTimeoutMillis >= MINIMUM_TIMEOUT) {
+                props.put("request-timeout", 
Integer.toString(requestTimeoutMillis));
+            }
+            if (connectTimeoutMillis >= MINIMUM_TIMEOUT) {
+                props.put("connect-timeout", 
Integer.toString(connectTimeoutMillis));
+            }
+            return RpcClientFactory.getInstance(props);
+        } catch (final Exception ex) {
+            LOGGER.error("Unable to create Flume RPCClient: {}", 
ex.getMessage());
+            return null;
+        }
+    }
+
+    @Override
+    protected boolean releaseSub(final long timeout, final TimeUnit timeUnit) {
+        boolean closed = true;
+        if (rpcClient != null) {
+            try {
+                synchronized(this) {
+                    try {
+                        if (batchSize > 1 && batchEvent.getEvents().size() > 
0) {
+                            send(batchEvent);
+                        }
+                    } catch (final Exception ex) {
+                        LOGGER.error("Error sending final batch: {}", 
ex.getMessage());
+                        closed = false;
+                    }
+                }
+                rpcClient.close();
+            } catch (final Exception ex) {
+                LOGGER.error("Attempt to close RPC client failed", ex);
+                closed = false;
+            }
+        }
+        rpcClient = null;
+        return closed;
+    }
+
+    /**
+     * Factory data.
+     */
+    private static class FactoryData {
+        private final String name;
+        private final Agent[] agents;
+        private final int batchSize;
+        private final int delayMillis;
+        private final int retries;
+        private final int conntectTimeoutMillis;
+        private final int requestTimeoutMillis;
+
+        /**
+         * Constructor.
+         * @param name The name of the Appender.
+         * @param agents The agents.
+         * @param batchSize The number of events to include in a batch.
+         */
+        public FactoryData(final String name, final Agent[] agents, final int 
batchSize, final int delayMillis,
+                final int retries, final int connectTimeoutMillis, final int 
requestTimeoutMillis) {
+            this.name = name;
+            this.agents = agents;
+            this.batchSize = batchSize;
+            this.delayMillis = delayMillis;
+            this.retries = retries;
+            this.conntectTimeoutMillis = connectTimeoutMillis;
+            this.requestTimeoutMillis = requestTimeoutMillis;
+        }
+    }
+
+    /**
+     * Avro Manager Factory.
+     */
+    private static class AvroManagerFactory implements 
ManagerFactory<FlumeAvroManager, FactoryData> {
+
+        /**
+         * Create the FlumeAvroManager.
+         * @param name The name of the entity to manage.
+         * @param data The data required to create the entity.
+         * @return The FlumeAvroManager.
+         */
+        @Override
+        public FlumeAvroManager createManager(final String name, final 
FactoryData data) {
+            try {
+
+                return new FlumeAvroManager(name, data.name, data.agents, 
data.batchSize, data.delayMillis,
+                        data.retries, data.conntectTimeoutMillis, 
data.requestTimeoutMillis);
+            } catch (final Exception ex) {
+                LOGGER.error("Could not create FlumeAvroManager", ex);
+            }
+            return null;
+        }
+    }
+
+}
diff --git 
a/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/AbstractStreamTest.java
 
b/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/AbstractStreamTest.java
index 64ecaa8edb..290f9b3fb5 100644
--- 
a/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/AbstractStreamTest.java
+++ 
b/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/AbstractStreamTest.java
@@ -1,59 +1,58 @@
-/*
- * 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.io;
-
-import java.util.List;
-
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.core.test.junit.LoggerContextRule;
-import org.apache.logging.log4j.spi.ExtendedLogger;
-import org.junit.Before;
-import org.junit.ClassRule;
-
-import static org.hamcrest.core.StringStartsWith.startsWith;
-import static org.junit.Assert.*;
-
-public abstract class AbstractStreamTest {
-
-    protected static ExtendedLogger getExtendedLogger() {
-        return ctx.getLogger("UnitTestLogger");
-    }
-
-    protected final static String NEWLINE = System.lineSeparator();
-    protected final static Level LEVEL = Level.ERROR;
-    protected final static String FIRST = "first";
-
-    protected final static String LAST = "last";
-
-    @ClassRule
-    public static LoggerContextRule ctx = new 
LoggerContextRule("log4j2-streams-unit-test.xml");
-
-    protected void assertMessages(final String... messages) {
-        final List<String> actualMsgs = 
ctx.getListAppender("UnitTest").getMessages();
-        assertEquals("Unexpected number of results.", messages.length, 
actualMsgs.size());
-        for (int i = 0; i < messages.length; i++) {
-            final String start = LEVEL.name() + ' ' + messages[i];
-            assertThat(actualMsgs.get(i), startsWith(start));
-        }
-    }
-
-    @Before
-    public void clearAppender() {
-        ctx.getListAppender("UnitTest").clear();
-    }
-}
+/*
+ * 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.io;
+
+import java.util.List;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.test.junit.LoggerContextRule;
+import org.apache.logging.log4j.spi.ExtendedLogger;
+import org.junit.Before;
+import org.junit.ClassRule;
+
+import static org.hamcrest.core.StringStartsWith.startsWith;
+import static org.junit.Assert.*;
+
+public abstract class AbstractStreamTest {
+
+    protected static ExtendedLogger getExtendedLogger() {
+        return ctx.getLogger("UnitTestLogger");
+    }
+
+    protected final static String NEWLINE = System.lineSeparator();
+    protected final static Level LEVEL = Level.ERROR;
+    protected final static String FIRST = "first";
+
+    protected final static String LAST = "last";
+
+    @ClassRule
+    public static LoggerContextRule ctx = new 
LoggerContextRule("log4j2-streams-unit-test.xml");
+
+    protected void assertMessages(final String... messages) {
+        final List<String> actualMsgs = 
ctx.getListAppender("UnitTest").getMessages();
+        assertEquals("Unexpected number of results.", messages.length, 
actualMsgs.size());
+        for (int i = 0; i < messages.length; i++) {
+            final String start = LEVEL.name() + ' ' + messages[i];
+            assertThat(actualMsgs.get(i), startsWith(start));
+        }
+    }
+
+    @Before
+    public void clearAppender() {
+        ctx.getListAppender("UnitTest").clear();
+    }
+}
diff --git 
a/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/IoBuilderCallerInfoTesting.java
 
b/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/IoBuilderCallerInfoTesting.java
index 7a0cf29731..172dae42df 100644
--- 
a/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/IoBuilderCallerInfoTesting.java
+++ 
b/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/IoBuilderCallerInfoTesting.java
@@ -1,55 +1,55 @@
-/*
- * 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.io;
-
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.core.Logger;
-import org.apache.logging.log4j.core.test.junit.LoggerContextRule;
-import org.apache.logging.log4j.core.test.appender.ListAppender;
-import org.junit.Before;
-import org.junit.ClassRule;
-
-import static org.junit.Assert.*;
-
-public class IoBuilderCallerInfoTesting {
-
-    protected static Logger getExtendedLogger() {
-        return ctx.getLogger("ClassAndMethodLogger");
-    }
-
-    protected static Logger getLogger() {
-        return getExtendedLogger();
-    }
-
-    protected final static Level LEVEL = Level.WARN;
-
-    @ClassRule
-    public static LoggerContextRule ctx = new 
LoggerContextRule("log4j2-streams-calling-info.xml");
-
-    public void assertMessages(final String msg, final int size, final String 
methodName) {
-        final ListAppender appender = ctx.getListAppender("ClassAndMethod");
-        assertEquals(msg + ".size", size, appender.getMessages().size());
-        for (final String message : appender.getMessages()) {
-            assertEquals(msg + " has incorrect caller info", 
this.getClass().getName() + '.' + methodName, message);
-        }
-    }
-
-    @Before
-    public void clearAppender() {
-        ctx.getListAppender("ClassAndMethod").clear();
-    }
-}
+/*
+ * 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.io;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.Logger;
+import org.apache.logging.log4j.core.test.appender.ListAppender;
+import org.apache.logging.log4j.core.test.junit.LoggerContextRule;
+import org.junit.Before;
+import org.junit.ClassRule;
+
+import static org.junit.Assert.*;
+
+public class IoBuilderCallerInfoTesting {
+
+    protected static Logger getExtendedLogger() {
+        return ctx.getLogger("ClassAndMethodLogger");
+    }
+
+    protected static Logger getLogger() {
+        return getExtendedLogger();
+    }
+
+    protected final static Level LEVEL = Level.WARN;
+
+    @ClassRule
+    public static LoggerContextRule ctx = new 
LoggerContextRule("log4j2-streams-calling-info.xml");
+
+    public void assertMessages(final String msg, final int size, final String 
methodName) {
+        final ListAppender appender = ctx.getListAppender("ClassAndMethod");
+        assertEquals(msg + ".size", size, appender.getMessages().size());
+        for (final String message : appender.getMessages()) {
+            assertEquals(msg + " has incorrect caller info", 
this.getClass().getName() + '.' + methodName, message);
+        }
+    }
+
+    @Before
+    public void clearAppender() {
+        ctx.getListAppender("ClassAndMethod").clear();
+    }
+}
diff --git 
a/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/IoBuilderTest.java 
b/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/IoBuilderTest.java
index 8142b61e7d..a4d5941bcf 100644
--- 
a/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/IoBuilderTest.java
+++ 
b/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/IoBuilderTest.java
@@ -1,51 +1,51 @@
-/*
- * 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.io;
-
-import static org.hamcrest.Matchers.empty;
-import static org.hamcrest.Matchers.hasSize;
-import static org.hamcrest.Matchers.not;
-import static org.hamcrest.Matchers.startsWith;
-import static org.junit.Assert.assertThat;
-
-import java.io.PrintStream;
-import java.util.List;
-
-import org.apache.logging.log4j.core.test.junit.LoggerContextRule;
-import org.apache.logging.log4j.core.test.appender.ListAppender;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-public class IoBuilderTest {
-
-    @ClassRule
-    public static LoggerContextRule context = new 
LoggerContextRule("log4j2-streams-calling-info.xml");
-
-    @Test
-    public void testNoArgBuilderCallerClassInfo() throws Exception {
-        try (final PrintStream ps = IoBuilder.forLogger().buildPrintStream()) {
-            ps.println("discarded");
-            final ListAppender app = context.getListAppender("IoBuilderTest");
-            final List<String> messages = app.getMessages();
-            assertThat(messages, not(empty()));
-            assertThat(messages, hasSize(1));
-            final String message = messages.get(0);
-            assertThat(message, startsWith(getClass().getName() + 
".testNoArgBuilderCallerClassInfo"));
-            app.clear();
-        }
-    }
-}
+/*
+ * 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.io;
+
+import java.io.PrintStream;
+import java.util.List;
+
+import org.apache.logging.log4j.core.test.appender.ListAppender;
+import org.apache.logging.log4j.core.test.junit.LoggerContextRule;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.startsWith;
+import static org.junit.Assert.assertThat;
+
+public class IoBuilderTest {
+
+    @ClassRule
+    public static LoggerContextRule context = new 
LoggerContextRule("log4j2-streams-calling-info.xml");
+
+    @Test
+    public void testNoArgBuilderCallerClassInfo() throws Exception {
+        try (final PrintStream ps = IoBuilder.forLogger().buildPrintStream()) {
+            ps.println("discarded");
+            final ListAppender app = context.getListAppender("IoBuilderTest");
+            final List<String> messages = app.getMessages();
+            assertThat(messages, not(empty()));
+            assertThat(messages, hasSize(1));
+            final String message = messages.get(0);
+            assertThat(message, startsWith(getClass().getName() + 
".testNoArgBuilderCallerClassInfo"));
+            app.clear();
+        }
+    }
+}
diff --git 
a/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/LoggerPrintWriterJdbcH2Test.java
 
b/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/LoggerPrintWriterJdbcH2Test.java
index 47a790d703..739b95215a 100644
--- 
a/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/LoggerPrintWriterJdbcH2Test.java
+++ 
b/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/LoggerPrintWriterJdbcH2Test.java
@@ -1,96 +1,96 @@
-/*
- * 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.io;
-
-import java.io.PrintWriter;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.core.test.junit.LoggerContextRule;
-import org.apache.logging.log4j.core.test.appender.ListAppender;
-import org.apache.logging.log4j.util.Strings;
-import org.h2.jdbcx.JdbcDataSource;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Ignore;
-import org.junit.Test;
-
-public class LoggerPrintWriterJdbcH2Test {
-
-    @ClassRule
-    public static LoggerContextRule context = new 
LoggerContextRule("log4j2-jdbc-driver-manager.xml");
-
-    private static final String H2_URL = "jdbc:h2:mem:Log4j";
-
-    private static final String PASSWORD = Strings.EMPTY;
-
-    private static final String USER_ID = "sa";
-
-    private ListAppender listAppender;
-
-    private PrintWriter createLoggerPrintWriter() {
-        return 
IoBuilder.forLogger(context.getLogger()).setLevel(Level.ALL).buildPrintWriter();
-    }
-
-    private ListAppender getListAppender() {
-        return listAppender;
-    }
-
-    protected Connection newConnection() throws SQLException {
-        return DriverManager.getConnection(H2_URL, USER_ID, PASSWORD);
-    }
-
-    private void setListAppender(final ListAppender listAppender) {
-        this.listAppender = listAppender;
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        this.setListAppender(context.getListAppender("List").clear());
-        Assert.assertEquals(0, this.getListAppender().getMessages().size());
-    }
-
-    @Test
-    @Ignore("DataSource#setLogWriter() has no effect in H2, it uses its own 
internal logging and an SLF4J bridge.")
-    public void testDataSource_setLogWriter() throws SQLException {
-        final JdbcDataSource dataSource = new JdbcDataSource();
-        dataSource.setUrl(H2_URL);
-        dataSource.setUser(USER_ID);
-        dataSource.setPassword(PASSWORD);
-        dataSource.setLogWriter(createLoggerPrintWriter());
-        // dataSource.setLogWriter(new PrintWriter(new 
OutputStreamWriter(System.out)));
-        try (final Connection conn = dataSource.getConnection()) {
-            conn.prepareCall("select 1");
-        }
-        Assert.assertTrue(this.getListAppender().getMessages().size() > 0);
-    }
-
-    @Test
-    public void testDriverManager_setLogWriter() throws SQLException {
-        DriverManager.setLogWriter(createLoggerPrintWriter());
-        // DriverManager.setLogWriter(new PrintWriter(new 
OutputStreamWriter(System.out)));
-        try (final Connection conn = this.newConnection()) {
-            conn.rollback();
-        } finally {
-            DriverManager.setLogWriter(null);
-        }
-        Assert.assertTrue(this.getListAppender().getMessages().size() > 0);
-    }
-}
+/*
+ * 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.io;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.test.appender.ListAppender;
+import org.apache.logging.log4j.core.test.junit.LoggerContextRule;
+import org.apache.logging.log4j.util.Strings;
+import org.h2.jdbcx.JdbcDataSource;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class LoggerPrintWriterJdbcH2Test {
+
+    @ClassRule
+    public static LoggerContextRule context = new 
LoggerContextRule("log4j2-jdbc-driver-manager.xml");
+
+    private static final String H2_URL = "jdbc:h2:mem:Log4j";
+
+    private static final String PASSWORD = Strings.EMPTY;
+
+    private static final String USER_ID = "sa";
+
+    private ListAppender listAppender;
+
+    private PrintWriter createLoggerPrintWriter() {
+        return 
IoBuilder.forLogger(context.getLogger()).setLevel(Level.ALL).buildPrintWriter();
+    }
+
+    private ListAppender getListAppender() {
+        return listAppender;
+    }
+
+    protected Connection newConnection() throws SQLException {
+        return DriverManager.getConnection(H2_URL, USER_ID, PASSWORD);
+    }
+
+    private void setListAppender(final ListAppender listAppender) {
+        this.listAppender = listAppender;
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        this.setListAppender(context.getListAppender("List").clear());
+        Assert.assertEquals(0, this.getListAppender().getMessages().size());
+    }
+
+    @Test
+    @Ignore("DataSource#setLogWriter() has no effect in H2, it uses its own 
internal logging and an SLF4J bridge.")
+    public void testDataSource_setLogWriter() throws SQLException {
+        final JdbcDataSource dataSource = new JdbcDataSource();
+        dataSource.setUrl(H2_URL);
+        dataSource.setUser(USER_ID);
+        dataSource.setPassword(PASSWORD);
+        dataSource.setLogWriter(createLoggerPrintWriter());
+        // dataSource.setLogWriter(new PrintWriter(new 
OutputStreamWriter(System.out)));
+        try (final Connection conn = dataSource.getConnection()) {
+            conn.prepareCall("select 1");
+        }
+        Assert.assertTrue(this.getListAppender().getMessages().size() > 0);
+    }
+
+    @Test
+    public void testDriverManager_setLogWriter() throws SQLException {
+        DriverManager.setLogWriter(createLoggerPrintWriter());
+        // DriverManager.setLogWriter(new PrintWriter(new 
OutputStreamWriter(System.out)));
+        try (final Connection conn = this.newConnection()) {
+            conn.rollback();
+        } finally {
+            DriverManager.setLogWriter(null);
+        }
+        Assert.assertTrue(this.getListAppender().getMessages().size() > 0);
+    }
+}
diff --git 
a/log4j-jcl/src/test/java/org/apache/logging/log4j/jcl/CallerInformationTest.java
 
b/log4j-jcl/src/test/java/org/apache/logging/log4j/jcl/CallerInformationTest.java
index 6a87ed9d74..97c31253fe 100644
--- 
a/log4j-jcl/src/test/java/org/apache/logging/log4j/jcl/CallerInformationTest.java
+++ 
b/log4j-jcl/src/test/java/org/apache/logging/log4j/jcl/CallerInformationTest.java
@@ -1,67 +1,67 @@
-/*
- * 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.jcl;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.logging.log4j.core.test.junit.LoggerContextRule;
-import org.apache.logging.log4j.core.test.appender.ListAppender;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-public class CallerInformationTest {
-
-    // config from log4j-core test-jar
-    private static final String CONFIG = "log4j2-calling-class.xml";
-
-    @ClassRule
-    public static final LoggerContextRule ctx = new LoggerContextRule(CONFIG);
-
-    @Test
-    public void testClassLogger() throws Exception {
-        final ListAppender app = ctx.getListAppender("Class").clear();
-        final Log logger = LogFactory.getLog("ClassLogger");
-        logger.info("Ignored message contents.");
-        logger.warn("Verifying the caller class is still correct.");
-        logger.error("Hopefully nobody breaks me!");
-        final List<String> messages = app.getMessages();
-        assertEquals("Incorrect number of messages.", 3, messages.size());
-        for (final String message : messages) {
-            assertEquals("Incorrect caller class name.", 
this.getClass().getName(), message);
-        }
-    }
-
-    @Test
-    public void testMethodLogger() throws Exception {
-        final ListAppender app = ctx.getListAppender("Method").clear();
-        final Log logger = LogFactory.getLog("MethodLogger");
-        logger.info("More messages.");
-        logger.warn("CATASTROPHE INCOMING!");
-        logger.error("ZOMBIES!!!");
-        logger.warn("brains~~~");
-        logger.info("Itchy. Tasty.");
-        final List<String> messages = app.getMessages();
-        assertEquals("Incorrect number of messages.", 5, messages.size());
-        for (final String message : messages) {
-            assertEquals("Incorrect caller method name.", "testMethodLogger", 
message);
-        }
-    }
-}
+/*
+ * 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.jcl;
+
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.logging.log4j.core.test.appender.ListAppender;
+import org.apache.logging.log4j.core.test.junit.LoggerContextRule;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class CallerInformationTest {
+
+    // config from log4j-core test-jar
+    private static final String CONFIG = "log4j2-calling-class.xml";
+
+    @ClassRule
+    public static final LoggerContextRule ctx = new LoggerContextRule(CONFIG);
+
+    @Test
+    public void testClassLogger() throws Exception {
+        final ListAppender app = ctx.getListAppender("Class").clear();
+        final Log logger = LogFactory.getLog("ClassLogger");
+        logger.info("Ignored message contents.");
+        logger.warn("Verifying the caller class is still correct.");
+        logger.error("Hopefully nobody breaks me!");
+        final List<String> messages = app.getMessages();
+        assertEquals("Incorrect number of messages.", 3, messages.size());
+        for (final String message : messages) {
+            assertEquals("Incorrect caller class name.", 
this.getClass().getName(), message);
+        }
+    }
+
+    @Test
+    public void testMethodLogger() throws Exception {
+        final ListAppender app = ctx.getListAppender("Method").clear();
+        final Log logger = LogFactory.getLog("MethodLogger");
+        logger.info("More messages.");
+        logger.warn("CATASTROPHE INCOMING!");
+        logger.error("ZOMBIES!!!");
+        logger.warn("brains~~~");
+        logger.info("Itchy. Tasty.");
+        final List<String> messages = app.getMessages();
+        assertEquals("Incorrect number of messages.", 5, messages.size());
+        for (final String message : messages) {
+            assertEquals("Incorrect caller method name.", "testMethodLogger", 
message);
+        }
+    }
+}
diff --git 
a/log4j-jul/src/main/java/org/apache/logging/log4j/jul/ApiLoggerAdapter.java 
b/log4j-jul/src/main/java/org/apache/logging/log4j/jul/ApiLoggerAdapter.java
index 61bb9d0fdb..eb57294b25 100644
--- a/log4j-jul/src/main/java/org/apache/logging/log4j/jul/ApiLoggerAdapter.java
+++ b/log4j-jul/src/main/java/org/apache/logging/log4j/jul/ApiLoggerAdapter.java
@@ -1,40 +1,39 @@
-/*
- * 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.jul;
-
-import java.util.logging.Logger;
-
-import org.apache.logging.log4j.message.MessageFactory;
-import org.apache.logging.log4j.message.MessageFormatMessageFactory;
-import org.apache.logging.log4j.spi.LoggerContext;
-
-/**
- * {@link Logger} registry implementation using just log4j-api. This is the 
fallback registry used when log4j-core is
- * not available.
- *
- * @since 2.1
- */
-public class ApiLoggerAdapter extends AbstractLoggerAdapter {
-
-    private static final MessageFactory MESSAGE_FACTORY = new 
MessageFormatMessageFactory();
-
-    @Override
-    protected Logger newLogger(final String name, final LoggerContext context) 
{
-        return new ApiLogger(context.getLogger(name, MESSAGE_FACTORY));
-    }
-}
+/*
+ * 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.jul;
+
+import java.util.logging.Logger;
+
+import org.apache.logging.log4j.message.MessageFactory;
+import org.apache.logging.log4j.message.MessageFormatMessageFactory;
+import org.apache.logging.log4j.spi.LoggerContext;
+
+/**
+ * {@link Logger} registry implementation using just log4j-api. This is the 
fallback registry used when log4j-core is
+ * not available.
+ *
+ * @since 2.1
+ */
+public class ApiLoggerAdapter extends AbstractLoggerAdapter {
+
+    private static final MessageFactory MESSAGE_FACTORY = new 
MessageFormatMessageFactory();
+
+    @Override
+    protected Logger newLogger(final String name, final LoggerContext context) 
{
+        return new ApiLogger(context.getLogger(name, MESSAGE_FACTORY));
+    }
+}
diff --git 
a/log4j-jul/src/main/java/org/apache/logging/log4j/jul/CoreLoggerAdapter.java 
b/log4j-jul/src/main/java/org/apache/logging/log4j/jul/CoreLoggerAdapter.java
index 0840f7f527..6db34c3564 100644
--- 
a/log4j-jul/src/main/java/org/apache/logging/log4j/jul/CoreLoggerAdapter.java
+++ 
b/log4j-jul/src/main/java/org/apache/logging/log4j/jul/CoreLoggerAdapter.java
@@ -1,43 +1,42 @@
-/*
- * 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.jul;
-
-import java.util.logging.Logger;
-
-import org.apache.logging.log4j.message.MessageFactory;
-import org.apache.logging.log4j.message.MessageFormatMessageFactory;
-import org.apache.logging.log4j.spi.LoggerContext;
-
-/**
- * {@link Logger} registry implementation that uses log4j-core.
- *
- * @since 2.1
- */
-public class CoreLoggerAdapter extends AbstractLoggerAdapter {
-
-    private static final MessageFactory MESSAGE_FACTORY = new 
MessageFormatMessageFactory();
-
-    @Override
-    protected Logger newLogger(final String name, final LoggerContext context) 
{
-        final org.apache.logging.log4j.spi.ExtendedLogger original = 
context.getLogger(name, MESSAGE_FACTORY);
-        if (original instanceof org.apache.logging.log4j.core.Logger) {
-            return new CoreLogger((org.apache.logging.log4j.core.Logger) 
original);
-        }
-        return new ApiLogger(original); // LOG4J2-1618 during shutdown, a 
SimpleLogger may be returned
-    }
-}
+/*
+ * 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.jul;
+
+import java.util.logging.Logger;
+
+import org.apache.logging.log4j.message.MessageFactory;
+import org.apache.logging.log4j.message.MessageFormatMessageFactory;
+import org.apache.logging.log4j.spi.LoggerContext;
+
+/**
+ * {@link Logger} registry implementation that uses log4j-core.
+ *
+ * @since 2.1
+ */
+public class CoreLoggerAdapter extends AbstractLoggerAdapter {
+
+    private static final MessageFactory MESSAGE_FACTORY = new 
MessageFormatMessageFactory();
+
+    @Override
+    protected Logger newLogger(final String name, final LoggerContext context) 
{
+        final org.apache.logging.log4j.spi.ExtendedLogger original = 
context.getLogger(name, MESSAGE_FACTORY);
+        if (original instanceof org.apache.logging.log4j.core.Logger) {
+            return new CoreLogger((org.apache.logging.log4j.core.Logger) 
original);
+        }
+        return new ApiLogger(original); // LOG4J2-1618 during shutdown, a 
SimpleLogger may be returned
+    }
+}
diff --git 
a/log4j-jul/src/main/java/org/apache/logging/log4j/jul/Log4jBridgeHandler.java 
b/log4j-jul/src/main/java/org/apache/logging/log4j/jul/Log4jBridgeHandler.java
index aea7ad0980..f0fd08142e 100644
--- 
a/log4j-jul/src/main/java/org/apache/logging/log4j/jul/Log4jBridgeHandler.java
+++ 
b/log4j-jul/src/main/java/org/apache/logging/log4j/jul/Log4jBridgeHandler.java
@@ -1,319 +1,319 @@
-/*
- * 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.jul;
-
-//note: NO import of Logger, Level, LogManager to prevent conflicts JUL/log4j
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.LogRecord;
-
-import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.core.config.Configuration;
-import org.apache.logging.log4j.core.config.LoggerConfig;
-import org.apache.logging.log4j.spi.ExtendedLogger;
-import org.apache.logging.log4j.status.StatusLogger;
-
-
-/**
- * Bridge from JUL to log4j2.<br>
- * This is an alternative to log4j.jul.LogManager (running as complete JUL 
replacement),
- * especially useful for webapps running on a container for which the 
LogManager cannot or
- * should not be used.<br><br>
- *
- * Installation/usage:<ul>
- * <li> Declaratively inside JUL's <code>logging.properties</code>:<br>
- *    <code>handlers = 
org.apache.logging.log4j.jul.Log4jBridgeHandler</code><br>
- *    (and typically also:   
<code>org.apache.logging.log4j.jul.Log4jBridgeHandler.propagateLevels = 
true</code> )<br>
- *    Note: in a webapp running on Tomcat, you may create a 
<code>WEB-INF/classes/logging.properties</code>
- *    file to configure JUL for this webapp only: configured handlers and log 
levels affect your webapp only!
- *    This file is then the <i>complete</i> JUL configuration, so JUL's 
defaults (e.g. log level INFO) apply
- *    for stuff not explicitly defined therein.
- * <li> Programmatically by calling <code>install()</code> method,
- *    e.g. inside ServletContextListener static-class-init. or 
contextInitialized()
- * </ul>
- * Configuration (in JUL's <code>logging.properties</code>):<ul>
- * <li> Log4jBridgeHandler.<code>suffixToAppend</code><br>
- *        String, suffix to append to JUL logger names, to easily recognize 
bridged log messages.
- *        A dot "." is automatically prepended, so configuration for the basis 
logger is used<br>
- *        Example:  <code>Log4jBridgeHandler.suffixToAppend = _JUL</code><br>
- *        Useful, for example, if you use JSF because it logs exceptions and 
throws them afterwards;
- *        you can easily recognize the duplicates with this (or concentrate on 
the non-JUL-logs).
- * <li> Log4jBridgeHandler.<code>propagateLevels</code>   boolean, "true" to 
automatically propagate log4j log levels to JUL.
- * <li> Log4jBridgeHandler.<code>sysoutDebug</code>   boolean, perform some 
(developer) debug output to sysout
- * </ul>
- *
- * Log levels are translated with {@link LevelTranslator}, see also
- * <a 
href="https://logging.apache.org/log4j/2.x/log4j-jul/index.html#Default_Level_Conversions";>log4j
 doc</a>.<br><br>
- *
- * Restrictions:<ul>
- * <li> Manually given source/location info in JUL (e.g. entering(), 
exiting(), throwing(), logp(), logrb() )
- *    will NOT be considered, i.e. gets lost in log4j logging.
- * <li> Log levels of JUL have to be adjusted according to log4j log levels:
- *      Either by using "propagateLevels" (preferred), or manually by 
specifying them explicitly,
- *      i.e. logging.properties and log4j2.xml have some redundancies.
- * <li> Only JUL log events that are allowed according to the JUL log level 
get to this handler and thus to log4j.
- *      This is only relevant and important if you NOT use "propagateLevels".
- *      If you set <code>.level = SEVERE</code> only error logs will be seen 
by this handler and thus log4j
- *      - even if the corresponding log4j log level is ALL.<br>
- *      On the other side, you should NOT set <code>.level = FINER  or  
FINEST</code> if the log4j level is higher.
- *      In this case a lot of JUL log events would be generated, sent via this 
bridge to log4j and thrown away by the latter.<br>
- *      Note: JUL's default log level (i.e. none specified in 
logger.properties) is INFO.
- * </ul>
- *
- * (Credits: idea and concept originate from 
org.slf4j.bridge.SLF4JBridgeHandler;
- *   level propagation idea originates from logback/LevelChangePropagator;
- *   but no source code has been copied)
- */
-public class Log4jBridgeHandler extends java.util.logging.Handler implements 
PropertyChangeListener {
-    private static final org.apache.logging.log4j.Logger SLOGGER = 
StatusLogger.getLogger();
-
-    // the caller of the logging is java.util.logging.Logger (for location 
info)
-    private static final String FQCN = 
java.util.logging.Logger.class.getName();
-    private static final String UNKNOWN_LOGGER_NAME = "unknown.jul.logger";
-    private static final java.util.logging.Formatter julFormatter = new 
java.util.logging.SimpleFormatter();
-
-    private boolean doDebugOutput = false;
-    private String julSuffixToAppend = null;
-    //not needed:  private boolean installAsLevelPropagator = false;
-
-
-    /**
-     * Adds a new Log4jBridgeHandler instance to JUL's root logger.
-     * This is a programmatic alternative to specify
-     * <code>handlers = org.apache.logging.log4j.jul.Log4jBridgeHandler</code>
-     * and its configuration in logging.properties.<br>
-     * @param removeHandlersForRootLogger  true to remove all other installed 
handlers on JUL root level
-     */
-    public static void install(boolean removeHandlersForRootLogger, String 
suffixToAppend, boolean propagateLevels) {
-        java.util.logging.Logger rootLogger = getJulRootLogger();
-        if (removeHandlersForRootLogger) {
-            for (java.util.logging.Handler hdl : rootLogger.getHandlers()) {
-                rootLogger.removeHandler(hdl);
-            }
-        }
-        rootLogger.addHandler(new Log4jBridgeHandler(false, suffixToAppend, 
propagateLevels));
-        // note: filter-level of Handler defaults to ALL, so nothing to do here
-    }
-
-    private static java.util.logging.Logger getJulRootLogger() {
-        return java.util.logging.LogManager.getLogManager().getLogger("");
-    }
-
-
-    /** Initialize this handler by reading out JUL configuration. */
-    public Log4jBridgeHandler() {
-        final java.util.logging.LogManager julLogMgr = 
java.util.logging.LogManager.getLogManager();
-        final String className = this.getClass().getName();
-        init(Boolean.parseBoolean(julLogMgr.getProperty(className + 
".sysoutDebug")),
-                julLogMgr.getProperty(className + ".appendSuffix"),
-                Boolean.parseBoolean(julLogMgr.getProperty(className + 
".propagateLevels")) );
-
-    }
-
-    /** Initialize this handler with given configuration. */
-    public Log4jBridgeHandler(boolean debugOutput, String suffixToAppend, 
boolean propagateLevels) {
-           init(debugOutput, suffixToAppend, propagateLevels);
-       }
-
-
-    /** Perform init. of this handler with given configuration (typical use is 
for constructor). */
-       protected void init(boolean debugOutput, String suffixToAppend, boolean 
propagateLevels) {
-           this.doDebugOutput = debugOutput;
-        if (debugOutput) {
-            new Exception("DIAGNOSTIC ONLY (sysout):  Log4jBridgeHandler 
instance created (" + this + ")")
-                    .printStackTrace(System.out);    // is no error thus no 
syserr
-        }
-
-        if (suffixToAppend != null) {
-            suffixToAppend = suffixToAppend.trim();    // remove spaces
-            if (suffixToAppend.isEmpty()) {
-                suffixToAppend = null;
-            } else if (suffixToAppend.charAt(0) != '.') {    // always make it 
a sub-logger
-                suffixToAppend = '.' + suffixToAppend;
-            }
-        }
-        this.julSuffixToAppend = suffixToAppend;
-
-        //not needed:  this.installAsLevelPropagator = propagateLevels;
-        if (propagateLevels) {
-            @SuppressWarnings("resource")    // no need to close the 
AutoCloseable ctx here
-            LoggerContext context = LoggerContext.getContext(false);
-            context.addPropertyChangeListener(this);
-            propagateLogLevels(context.getConfiguration());
-            // note: java.util.logging.LogManager.addPropertyChangeListener() 
could also
-            // be set here, but a call of JUL.readConfiguration() will be done 
on purpose
-        }
-
-        SLOGGER.debug("Log4jBridgeHandler init. with: suffix='{}', lvlProp={}, 
instance={}",
-                suffixToAppend, propagateLevels, this);
-    }
-
-
-    @Override
-    public void close() {
-        // cleanup and remove listener and JUL logger references
-        julLoggerRefs = null;
-        LoggerContext.getContext(false).removePropertyChangeListener(this);
-        if (doDebugOutput) {
-            System.out.println("sysout:  Log4jBridgeHandler close(): " + this);
-        }
-    }
-
-
-    @Override
-    public void publish(LogRecord record) {
-        if (record == null) {    // silently ignore null records
-            return;
-        }
-
-        org.apache.logging.log4j.Logger log4jLogger = getLog4jLogger(record);
-        String msg = julFormatter.formatMessage(record);    // use JUL's 
implementation to get real msg
-        /* log4j allows nulls:
-        if (msg == null) {
-            // JUL allows nulls, but other log system may not
-            msg = "<null log msg>";
-        } */
-        org.apache.logging.log4j.Level log4jLevel = 
LevelTranslator.toLevel(record.getLevel());
-        Throwable thrown = record.getThrown();
-        if (log4jLogger instanceof ExtendedLogger) {
-            // relevant for location information
-            try {
-                ((ExtendedLogger) log4jLogger).logIfEnabled(FQCN, log4jLevel, 
null, msg, thrown);
-            } catch (NoClassDefFoundError e) {
-                // sometimes there are problems with 
log4j.ExtendedStackTraceElement, so try a workaround
-                log4jLogger.warn("Log4jBridgeHandler: ignored exception when 
calling 'ExtendedLogger': {}", e.toString());
-                log4jLogger.log(log4jLevel, msg, thrown);
-            }
-        } else {
-            log4jLogger.log(log4jLevel, msg, thrown);
-        }
-    }
-
-
-    @Override
-    public void flush() {
-        // nothing to do
-    }
-
-
-    /**
-     * Return the log4j-Logger instance that will be used for logging.
-     * Handles null name case and appends configured suffix.
-     */
-    private org.apache.logging.log4j.Logger getLog4jLogger(LogRecord record) {
-        String name = record.getLoggerName();
-        if (name == null) {
-            name = UNKNOWN_LOGGER_NAME;
-        } else if (julSuffixToAppend != null) {
-            name += julSuffixToAppend;
-        }
-        return org.apache.logging.log4j.LogManager.getLogger(name);
-    }
-
-
-/////  log level propagation code
-
-
-    @Override
-    // impl. for PropertyChangeListener
-    public void propertyChange(PropertyChangeEvent evt) {
-        SLOGGER.debug("Log4jBridgeHandler.propertyChange(): {}", evt);
-        if (LoggerContext.PROPERTY_CONFIG.equals(evt.getPropertyName())  &&  
evt.getNewValue() instanceof Configuration) {
-            propagateLogLevels((Configuration) evt.getNewValue());
-        }
-    }
-
-
-    /** Save "hard" references to configured JUL loggers. (is lazy init.) */
-    private Set<java.util.logging.Logger> julLoggerRefs;
-    /** Perform developer tests? (Should be unused/outcommented for real code) 
*/
-    //private static final boolean DEVTEST = false;
-
-
-    private void propagateLogLevels(Configuration config) {
-        SLOGGER.debug("Log4jBridgeHandler.propagateLogLevels(): {}", config);
-        // clear or init. saved JUL logger references
-        // JUL loggers have to be explicitly referenced because JUL internally 
uses
-        // weak references so not instantiated loggers may be garbage collected
-        // and their level config gets lost then.
-        if (julLoggerRefs == null) {
-            julLoggerRefs = new HashSet<>();
-        } else {
-            julLoggerRefs.clear();
-        }
-
-        //if (DEVTEST)  debugPrintJulLoggers("Start of propagation");
-        // walk through all log4j configured loggers and set JUL level 
accordingly
-        final Map<String, LoggerConfig> log4jLoggers = config.getLoggers();
-        //java.util.List<String> outTxt = new java.util.ArrayList<>();    // 
DEVTEST / DEV-DEBUG ONLY
-        for (LoggerConfig lcfg : log4jLoggers.values()) {
-            java.util.logging.Logger julLog = 
java.util.logging.Logger.getLogger(lcfg.getName());    // this also fits for 
root = ""
-            java.util.logging.Level julLevel = 
LevelTranslator.toJavaLevel(lcfg.getLevel());    // lcfg.getLevel() never 
returns null
-            julLog.setLevel(julLevel);
-            julLoggerRefs.add(julLog);    // save an explicit reference to 
prevent GC
-            //if (DEVTEST)  outTxt.add("propagating '" + lcfg.getName() + "' / 
" + lcfg.getLevel() + "  ->  " + julLevel);
-        } // for
-        //if (DEVTEST)  java.util.Collections.sort(outTxt, 
String.CASE_INSENSITIVE_ORDER);
-        //if (DEVTEST)  for (String s : outTxt)  System.out.println("+ " + s);
-        //if (DEVTEST)  debugPrintJulLoggers("After propagation");
-
-        // cleanup JUL: reset all log levels not explicitly given by log4j
-        // This has to happen after propagation because JUL creates and inits. 
the loggers lazily
-        // so a nested logger might be created during the propagation-for-loop 
above and gets
-        // its JUL-configured level not until then.
-        final java.util.logging.LogManager julMgr = 
java.util.logging.LogManager.getLogManager();
-        for (Enumeration<String> en = julMgr.getLoggerNames();  
en.hasMoreElements(); ) {
-            java.util.logging.Logger julLog = 
julMgr.getLogger(en.nextElement());
-            if (julLog != null  &&  julLog.getLevel() != null  &&  
!"".equals(julLog.getName())
-                    &&  !log4jLoggers.containsKey(julLog.getName()) ) {
-                julLog.setLevel(null);
-            }
-        } // for
-        //if (DEVTEST)  debugPrintJulLoggers("After JUL cleanup");
-    }
-
-
-    /* DEV-DEBUG ONLY  (comment out for release) *xx/
-    private void debugPrintJulLoggers(String infoStr) {
-        if (!DEVTEST)  return;
-        java.util.logging.LogManager julMgr = 
java.util.logging.LogManager.getLogManager();
-        System.out.println("sysout:  " + infoStr + " - for " + julMgr);
-        java.util.List<String> txt = new java.util.ArrayList<>();
-        int n = 1;
-        for (Enumeration<String> en = julMgr.getLoggerNames();  
en.hasMoreElements(); ) {
-            String ln = en.nextElement();
-            java.util.logging.Logger lg = julMgr.getLogger(ln);
-            if (lg == null) {
-                txt.add("(!null-Logger '" + ln + "')  #" + n);
-            } else if (lg.getLevel() == null) {
-                txt.add("(null-Level Logger '" + ln + "')  #" + n);
-            } else {
-                txt.add("Logger '" + ln + "',  lvl = " + lg.getLevel() + "  #" 
+ n);
-            }
-            n++;
-        } // for
-        java.util.Collections.sort(txt, String.CASE_INSENSITIVE_ORDER);
-        for (String s : txt) {
-            System.out.println("  - " + s);
-        }
-    } /**/
-
-}
+/*
+ * 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.jul;
+
+//note: NO import of Logger, Level, LogManager to prevent conflicts JUL/log4j
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.LogRecord;
+
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.LoggerConfig;
+import org.apache.logging.log4j.spi.ExtendedLogger;
+import org.apache.logging.log4j.status.StatusLogger;
+
+
+/**
+ * Bridge from JUL to log4j2.<br>
+ * This is an alternative to log4j.jul.LogManager (running as complete JUL 
replacement),
+ * especially useful for webapps running on a container for which the 
LogManager cannot or
+ * should not be used.<br><br>
+ *
+ * Installation/usage:<ul>
+ * <li> Declaratively inside JUL's <code>logging.properties</code>:<br>
+ *    <code>handlers = 
org.apache.logging.log4j.jul.Log4jBridgeHandler</code><br>
+ *    (and typically also:   
<code>org.apache.logging.log4j.jul.Log4jBridgeHandler.propagateLevels = 
true</code> )<br>
+ *    Note: in a webapp running on Tomcat, you may create a 
<code>WEB-INF/classes/logging.properties</code>
+ *    file to configure JUL for this webapp only: configured handlers and log 
levels affect your webapp only!
+ *    This file is then the <i>complete</i> JUL configuration, so JUL's 
defaults (e.g. log level INFO) apply
+ *    for stuff not explicitly defined therein.
+ * <li> Programmatically by calling <code>install()</code> method,
+ *    e.g. inside ServletContextListener static-class-init. or 
contextInitialized()
+ * </ul>
+ * Configuration (in JUL's <code>logging.properties</code>):<ul>
+ * <li> Log4jBridgeHandler.<code>suffixToAppend</code><br>
+ *        String, suffix to append to JUL logger names, to easily recognize 
bridged log messages.
+ *        A dot "." is automatically prepended, so configuration for the basis 
logger is used<br>
+ *        Example:  <code>Log4jBridgeHandler.suffixToAppend = _JUL</code><br>
+ *        Useful, for example, if you use JSF because it logs exceptions and 
throws them afterwards;
+ *        you can easily recognize the duplicates with this (or concentrate on 
the non-JUL-logs).
+ * <li> Log4jBridgeHandler.<code>propagateLevels</code>   boolean, "true" to 
automatically propagate log4j log levels to JUL.
+ * <li> Log4jBridgeHandler.<code>sysoutDebug</code>   boolean, perform some 
(developer) debug output to sysout
+ * </ul>
+ *
+ * Log levels are translated with {@link LevelTranslator}, see also
+ * <a 
href="https://logging.apache.org/log4j/2.x/log4j-jul/index.html#Default_Level_Conversions";>log4j
 doc</a>.<br><br>
+ *
+ * Restrictions:<ul>
+ * <li> Manually given source/location info in JUL (e.g. entering(), 
exiting(), throwing(), logp(), logrb() )
+ *    will NOT be considered, i.e. gets lost in log4j logging.
+ * <li> Log levels of JUL have to be adjusted according to log4j log levels:
+ *      Either by using "propagateLevels" (preferred), or manually by 
specifying them explicitly,
+ *      i.e. logging.properties and log4j2.xml have some redundancies.
+ * <li> Only JUL log events that are allowed according to the JUL log level 
get to this handler and thus to log4j.
+ *      This is only relevant and important if you NOT use "propagateLevels".
+ *      If you set <code>.level = SEVERE</code> only error logs will be seen 
by this handler and thus log4j
+ *      - even if the corresponding log4j log level is ALL.<br>
+ *      On the other side, you should NOT set <code>.level = FINER  or  
FINEST</code> if the log4j level is higher.
+ *      In this case a lot of JUL log events would be generated, sent via this 
bridge to log4j and thrown away by the latter.<br>
+ *      Note: JUL's default log level (i.e. none specified in 
logger.properties) is INFO.
+ * </ul>
+ *
+ * (Credits: idea and concept originate from 
org.slf4j.bridge.SLF4JBridgeHandler;
+ *   level propagation idea originates from logback/LevelChangePropagator;
+ *   but no source code has been copied)
+ */
+public class Log4jBridgeHandler extends java.util.logging.Handler implements 
PropertyChangeListener {
+    private static final org.apache.logging.log4j.Logger SLOGGER = 
StatusLogger.getLogger();
+
+    // the caller of the logging is java.util.logging.Logger (for location 
info)
+    private static final String FQCN = 
java.util.logging.Logger.class.getName();
+    private static final String UNKNOWN_LOGGER_NAME = "unknown.jul.logger";
+    private static final java.util.logging.Formatter julFormatter = new 
java.util.logging.SimpleFormatter();
+
+    private boolean doDebugOutput = false;
+    private String julSuffixToAppend = null;
+    //not needed:  private boolean installAsLevelPropagator = false;
+
+
+    /**
+     * Adds a new Log4jBridgeHandler instance to JUL's root logger.
+     * This is a programmatic alternative to specify
+     * <code>handlers = org.apache.logging.log4j.jul.Log4jBridgeHandler</code>
+     * and its configuration in logging.properties.<br>
+     * @param removeHandlersForRootLogger  true to remove all other installed 
handlers on JUL root level
+     */
+    public static void install(boolean removeHandlersForRootLogger, String 
suffixToAppend, boolean propagateLevels) {
+        java.util.logging.Logger rootLogger = getJulRootLogger();
+        if (removeHandlersForRootLogger) {
+            for (java.util.logging.Handler hdl : rootLogger.getHandlers()) {
+                rootLogger.removeHandler(hdl);
+            }
+        }
+        rootLogger.addHandler(new Log4jBridgeHandler(false, suffixToAppend, 
propagateLevels));
+        // note: filter-level of Handler defaults to ALL, so nothing to do here
+    }
+
+    private static java.util.logging.Logger getJulRootLogger() {
+        return java.util.logging.LogManager.getLogManager().getLogger("");
+    }
+
+
+    /** Initialize this handler by reading out JUL configuration. */
+    public Log4jBridgeHandler() {
+        final java.util.logging.LogManager julLogMgr = 
java.util.logging.LogManager.getLogManager();
+        final String className = this.getClass().getName();
+        init(Boolean.parseBoolean(julLogMgr.getProperty(className + 
".sysoutDebug")),
+                julLogMgr.getProperty(className + ".appendSuffix"),
+                Boolean.parseBoolean(julLogMgr.getProperty(className + 
".propagateLevels")) );
+
+    }
+
+    /** Initialize this handler with given configuration. */
+    public Log4jBridgeHandler(boolean debugOutput, String suffixToAppend, 
boolean propagateLevels) {
+           init(debugOutput, suffixToAppend, propagateLevels);
+       }
+
+
+    /** Perform init. of this handler with given configuration (typical use is 
for constructor). */
+       protected void init(boolean debugOutput, String suffixToAppend, boolean 
propagateLevels) {
+           this.doDebugOutput = debugOutput;
+        if (debugOutput) {
+            new Exception("DIAGNOSTIC ONLY (sysout):  Log4jBridgeHandler 
instance created (" + this + ")")
+                    .printStackTrace(System.out);    // is no error thus no 
syserr
+        }
+
+        if (suffixToAppend != null) {
+            suffixToAppend = suffixToAppend.trim();    // remove spaces
+            if (suffixToAppend.isEmpty()) {
+                suffixToAppend = null;
+            } else if (suffixToAppend.charAt(0) != '.') {    // always make it 
a sub-logger
+                suffixToAppend = '.' + suffixToAppend;
+            }
+        }
+        this.julSuffixToAppend = suffixToAppend;
+
+        //not needed:  this.installAsLevelPropagator = propagateLevels;
+        if (propagateLevels) {
+            @SuppressWarnings("resource")    // no need to close the 
AutoCloseable ctx here
+            LoggerContext context = LoggerContext.getContext(false);
+            context.addPropertyChangeListener(this);
+            propagateLogLevels(context.getConfiguration());
+            // note: java.util.logging.LogManager.addPropertyChangeListener() 
could also
+            // be set here, but a call of JUL.readConfiguration() will be done 
on purpose
+        }
+
+        SLOGGER.debug("Log4jBridgeHandler init. with: suffix='{}', lvlProp={}, 
instance={}",
+                suffixToAppend, propagateLevels, this);
+    }
+
+
+    @Override
+    public void close() {
+        // cleanup and remove listener and JUL logger references
+        julLoggerRefs = null;
+        LoggerContext.getContext(false).removePropertyChangeListener(this);
+        if (doDebugOutput) {
+            System.out.println("sysout:  Log4jBridgeHandler close(): " + this);
+        }
+    }
+
+
+    @Override
+    public void publish(LogRecord record) {
+        if (record == null) {    // silently ignore null records
+            return;
+        }
+
+        org.apache.logging.log4j.Logger log4jLogger = getLog4jLogger(record);
+        String msg = julFormatter.formatMessage(record);    // use JUL's 
implementation to get real msg
+        /* log4j allows nulls:
+        if (msg == null) {
+            // JUL allows nulls, but other log system may not
+            msg = "<null log msg>";
+        } */
+        org.apache.logging.log4j.Level log4jLevel = 
LevelTranslator.toLevel(record.getLevel());
+        Throwable thrown = record.getThrown();
+        if (log4jLogger instanceof ExtendedLogger) {
+            // relevant for location information
+            try {
+                ((ExtendedLogger) log4jLogger).logIfEnabled(FQCN, log4jLevel, 
null, msg, thrown);
+            } catch (NoClassDefFoundError e) {
+                // sometimes there are problems with 
log4j.ExtendedStackTraceElement, so try a workaround
+                log4jLogger.warn("Log4jBridgeHandler: ignored exception when 
calling 'ExtendedLogger': {}", e.toString());
+                log4jLogger.log(log4jLevel, msg, thrown);
+            }
+        } else {
+            log4jLogger.log(log4jLevel, msg, thrown);
+        }
+    }
+
+
+    @Override
+    public void flush() {
+        // nothing to do
+    }
+
+
+    /**
+     * Return the log4j-Logger instance that will be used for logging.
+     * Handles null name case and appends configured suffix.
+     */
+    private org.apache.logging.log4j.Logger getLog4jLogger(LogRecord record) {
+        String name = record.getLoggerName();
+        if (name == null) {
+            name = UNKNOWN_LOGGER_NAME;
+        } else if (julSuffixToAppend != null) {
+            name += julSuffixToAppend;
+        }
+        return org.apache.logging.log4j.LogManager.getLogger(name);
+    }
+
+
+/////  log level propagation code
+
+
+    @Override
+    // impl. for PropertyChangeListener
+    public void propertyChange(PropertyChangeEvent evt) {
+        SLOGGER.debug("Log4jBridgeHandler.propertyChange(): {}", evt);
+        if (LoggerContext.PROPERTY_CONFIG.equals(evt.getPropertyName())  &&  
evt.getNewValue() instanceof Configuration) {
+            propagateLogLevels((Configuration) evt.getNewValue());
+        }
+    }
+
+
+    /** Save "hard" references to configured JUL loggers. (is lazy init.) */
+    private Set<java.util.logging.Logger> julLoggerRefs;
+    /** Perform developer tests? (Should be unused/outcommented for real code) 
*/
+    //private static final boolean DEVTEST = false;
+
+
+    private void propagateLogLevels(Configuration config) {
+        SLOGGER.debug("Log4jBridgeHandler.propagateLogLevels(): {}", config);
+        // clear or init. saved JUL logger references
+        // JUL loggers have to be explicitly referenced because JUL internally 
uses
+        // weak references so not instantiated loggers may be garbage collected
+        // and their level config gets lost then.
+        if (julLoggerRefs == null) {
+            julLoggerRefs = new HashSet<>();
+        } else {
+            julLoggerRefs.clear();
+        }
+
+        //if (DEVTEST)  debugPrintJulLoggers("Start of propagation");
+        // walk through all log4j configured loggers and set JUL level 
accordingly
+        final Map<String, LoggerConfig> log4jLoggers = config.getLoggers();
+        //java.util.List<String> outTxt = new java.util.ArrayList<>();    // 
DEVTEST / DEV-DEBUG ONLY
+        for (LoggerConfig lcfg : log4jLoggers.values()) {
+            java.util.logging.Logger julLog = 
java.util.logging.Logger.getLogger(lcfg.getName());    // this also fits for 
root = ""
+            java.util.logging.Level julLevel = 
LevelTranslator.toJavaLevel(lcfg.getLevel());    // lcfg.getLevel() never 
returns null
+            julLog.setLevel(julLevel);
+            julLoggerRefs.add(julLog);    // save an explicit reference to 
prevent GC
+            //if (DEVTEST)  outTxt.add("propagating '" + lcfg.getName() + "' / 
" + lcfg.getLevel() + "  ->  " + julLevel);
+        } // for
+        //if (DEVTEST)  java.util.Collections.sort(outTxt, 
String.CASE_INSENSITIVE_ORDER);
+        //if (DEVTEST)  for (String s : outTxt)  System.out.println("+ " + s);
+        //if (DEVTEST)  debugPrintJulLoggers("After propagation");
+
+        // cleanup JUL: reset all log levels not explicitly given by log4j
+        // This has to happen after propagation because JUL creates and inits. 
the loggers lazily
+        // so a nested logger might be created during the propagation-for-loop 
above and gets
+        // its JUL-configured level not until then.
+        final java.util.logging.LogManager julMgr = 
java.util.logging.LogManager.getLogManager();
+        for (Enumeration<String> en = julMgr.getLoggerNames();  
en.hasMoreElements(); ) {
+            java.util.logging.Logger julLog = 
julMgr.getLogger(en.nextElement());
+            if (julLog != null  &&  julLog.getLevel() != null  &&  
!"".equals(julLog.getName())
+                    &&  !log4jLoggers.containsKey(julLog.getName()) ) {
+                julLog.setLevel(null);
+            }
+        } // for
+        //if (DEVTEST)  debugPrintJulLoggers("After JUL cleanup");
+    }
+
+
+    /* DEV-DEBUG ONLY  (comment out for release) *xx/
+    private void debugPrintJulLoggers(String infoStr) {
+        if (!DEVTEST)  return;
+        java.util.logging.LogManager julMgr = 
java.util.logging.LogManager.getLogManager();
+        System.out.println("sysout:  " + infoStr + " - for " + julMgr);
+        java.util.List<String> txt = new java.util.ArrayList<>();
+        int n = 1;
+        for (Enumeration<String> en = julMgr.getLoggerNames();  
en.hasMoreElements(); ) {
+            String ln = en.nextElement();
+            java.util.logging.Logger lg = julMgr.getLogger(ln);
+            if (lg == null) {
+                txt.add("(!null-Logger '" + ln + "')  #" + n);
+            } else if (lg.getLevel() == null) {
+                txt.add("(null-Level Logger '" + ln + "')  #" + n);
+            } else {
+                txt.add("Logger '" + ln + "',  lvl = " + lg.getLevel() + "  #" 
+ n);
+            }
+            n++;
+        } // for
+        java.util.Collections.sort(txt, String.CASE_INSENSITIVE_ORDER);
+        for (String s : txt) {
+            System.out.println("  - " + s);
+        }
+    } /**/
+
+}
diff --git 
a/log4j-liquibase/src/main/java/liquibase/ext/logging/log4j2/Log4j2Logger.java 
b/log4j-liquibase/src/main/java/liquibase/ext/logging/log4j2/Log4j2Logger.java
index b007cf8e65..724d3c5652 100644
--- 
a/log4j-liquibase/src/main/java/liquibase/ext/logging/log4j2/Log4j2Logger.java
+++ 
b/log4j-liquibase/src/main/java/liquibase/ext/logging/log4j2/Log4j2Logger.java
@@ -1,93 +1,93 @@
-/*
- * 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 liquibase.ext.logging.log4j2;
-
-import liquibase.logging.core.AbstractLogger;
-
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.spi.ExtendedLogger;
-
-/**
- * Logs Liquibase messages to Log4j 2.x.
- * <p>
- * This class must be in the {@code liquibase} package in order for the 
Liquibase plugin discovery mechanism to work.
- * </p>
- */
-public class Log4j2Logger extends AbstractLogger {
-
-    private static final String FQCN = Log4j2Logger.class.getName();
-
-    private ExtendedLogger logger;
-
-    @Override
-    public void debug(final String message) {
-        logger.logIfEnabled(FQCN, Level.DEBUG, null, buildMessage(message));
-    }
-
-    @Override
-    public void debug(final String message, final Throwable e) {
-        logger.logIfEnabled(FQCN, Level.DEBUG, null, buildMessage(message), e);
-    }
-
-    @Override
-    public int getPriority() {
-        return PRIORITY_DATABASE;
-    }
-
-    @Override
-    public void info(final String message) {
-        logger.logIfEnabled(FQCN, Level.INFO, null, buildMessage(message));
-    }
-
-    @Override
-    public void info(final String message, final Throwable e) {
-        logger.logIfEnabled(FQCN, Level.INFO, null, buildMessage(message), e);
-    }
-
-    @Override
-    public void setLogLevel(final String logLevel, final String logFile) {
-        setLogLevel(logLevel);
-        // ignore logFile
-    }
-
-    @Override
-    public void setName(final String name) {
-        logger = LogManager.getContext(false).getLogger(name);
-    }
-
-    @Override
-    public void severe(final String message) {
-        logger.logIfEnabled(FQCN, Level.ERROR, null, buildMessage(message));
-    }
-
-    @Override
-    public void severe(final String message, final Throwable e) {
-        logger.logIfEnabled(FQCN, Level.ERROR, null, buildMessage(message), e);
-    }
-
-    @Override
-    public void warning(final String message) {
-        logger.logIfEnabled(FQCN, Level.WARN, null, buildMessage(message));
-    }
-
-    @Override
-    public void warning(final String message, final Throwable e) {
-        logger.logIfEnabled(FQCN, Level.WARN, null, buildMessage(message), e);
-    }
-
-}
+/*
+ * 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 liquibase.ext.logging.log4j2;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.spi.ExtendedLogger;
+
+import liquibase.logging.core.AbstractLogger;
+
+/**
+ * Logs Liquibase messages to Log4j 2.x.
+ * <p>
+ * This class must be in the {@code liquibase} package in order for the 
Liquibase plugin discovery mechanism to work.
+ * </p>
+ */
+public class Log4j2Logger extends AbstractLogger {
+
+    private static final String FQCN = Log4j2Logger.class.getName();
+
+    private ExtendedLogger logger;
+
+    @Override
+    public void debug(final String message) {
+        logger.logIfEnabled(FQCN, Level.DEBUG, null, buildMessage(message));
+    }
+
+    @Override
+    public void debug(final String message, final Throwable e) {
+        logger.logIfEnabled(FQCN, Level.DEBUG, null, buildMessage(message), e);
+    }
+
+    @Override
+    public int getPriority() {
+        return PRIORITY_DATABASE;
+    }
+
+    @Override
+    public void info(final String message) {
+        logger.logIfEnabled(FQCN, Level.INFO, null, buildMessage(message));
+    }
+
+    @Override
+    public void info(final String message, final Throwable e) {
+        logger.logIfEnabled(FQCN, Level.INFO, null, buildMessage(message), e);
+    }
+
+    @Override
+    public void setLogLevel(final String logLevel, final String logFile) {
+        setLogLevel(logLevel);
+        // ignore logFile
+    }
+
+    @Override
+    public void setName(final String name) {
+        logger = LogManager.getContext(false).getLogger(name);
+    }
+
+    @Override
+    public void severe(final String message) {
+        logger.logIfEnabled(FQCN, Level.ERROR, null, buildMessage(message));
+    }
+
+    @Override
+    public void severe(final String message, final Throwable e) {
+        logger.logIfEnabled(FQCN, Level.ERROR, null, buildMessage(message), e);
+    }
+
+    @Override
+    public void warning(final String message) {
+        logger.logIfEnabled(FQCN, Level.WARN, null, buildMessage(message));
+    }
+
+    @Override
+    public void warning(final String message, final Throwable e) {
+        logger.logIfEnabled(FQCN, Level.WARN, null, buildMessage(message), e);
+    }
+
+}
diff --git 
a/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/DumpTagTest.java 
b/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/DumpTagTest.java
index 7d28954c1f..a770f8fd89 100644
--- 
a/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/DumpTagTest.java
+++ 
b/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/DumpTagTest.java
@@ -1,122 +1,121 @@
-/*
- * 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.taglib;
-
-import java.io.ByteArrayOutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-
-import javax.servlet.jsp.JspWriter;
-import javax.servlet.jsp.PageContext;
-import javax.servlet.jsp.tagext.Tag;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.springframework.mock.web.MockJspWriter;
-import org.springframework.mock.web.MockPageContext;
-
-import static org.junit.Assert.*;
-
-/**
- *
- */
-public class DumpTagTest {
-    private static final Charset UTF8 = StandardCharsets.UTF_8;
-    private Writer writer;
-    private ByteArrayOutputStream output;
-    private MockPageContext context;
-    private DumpTag tag;
-
-    @Before
-    public void setUp() {
-        this.output = new ByteArrayOutputStream();
-        this.writer = new OutputStreamWriter(this.output, UTF8);
-
-        this.context = new MockPageContext() {
-            private final MockJspWriter jspWriter = new MockJspWriter(writer);
-            @Override
-            public JspWriter getOut() {
-                return this.jspWriter;
-            }
-        };
-
-        this.tag = new DumpTag();
-        this.tag.setPageContext(this.context);
-    }
-
-    @Test
-    public void testDoEndTagDefaultPageScopeNoAttributes() throws Exception {
-        final int returnValue = this.tag.doEndTag();
-        assertEquals("The return value is not correct.", Tag.EVAL_PAGE, 
returnValue);
-
-        this.writer.flush();
-        final String output = new String(this.output.toByteArray(), UTF8);
-        assertEquals("The output is not correct.", "<dl></dl>", output);
-    }
-
-    @Test
-    public void testDoEndTagDefaultPageScope() throws Exception {
-        this.context.setAttribute("testAttribute01", "testValue01", 
PageContext.PAGE_SCOPE);
-        this.context.setAttribute("anotherAttribute02", "finalValue02", 
PageContext.PAGE_SCOPE);
-        this.context.setAttribute("badAttribute03", "skippedValue03", 
PageContext.SESSION_SCOPE);
-
-        final int returnValue = this.tag.doEndTag();
-        assertEquals("The return value is not correct.", Tag.EVAL_PAGE, 
returnValue);
-
-        this.writer.flush();
-        final String output = new String(this.output.toByteArray(), UTF8);
-        assertEquals("The output is not correct.",
-                "<dl>" +
-                        
"<dt><code>testAttribute01</code></dt><dd><code>testValue01</code></dd>" +
-                        
"<dt><code>anotherAttribute02</code></dt><dd><code>finalValue02</code></dd>" +
-                        "</dl>", output);
-    }
-
-    @Test
-    public void testDoEndTagSessionScopeNoAttributes() throws Exception {
-        this.context.setAttribute("badAttribute01", "skippedValue01", 
PageContext.PAGE_SCOPE);
-
-        this.tag.setScope("session");
-        final int returnValue = this.tag.doEndTag();
-        assertEquals("The return value is not correct.", Tag.EVAL_PAGE, 
returnValue);
-
-        this.writer.flush();
-        final String output = new String(this.output.toByteArray(), UTF8);
-        assertEquals("The output is not correct.", "<dl></dl>", output);
-    }
-
-    @Test
-    public void testDoEndTagSessionScope() throws Exception {
-        this.context.setAttribute("otherAttribute03", "lostValue03", 
PageContext.PAGE_SCOPE);
-        this.context.setAttribute("coolAttribute01", "weirdValue01", 
PageContext.SESSION_SCOPE);
-        this.context.setAttribute("testAttribute02", "testValue02", 
PageContext.SESSION_SCOPE);
-
-        this.tag.setScope("session");
-        final int returnValue = this.tag.doEndTag();
-        assertEquals("The return value is not correct.", Tag.EVAL_PAGE, 
returnValue);
-
-        this.writer.flush();
-        final String output = new String(this.output.toByteArray(), UTF8);
-        assertEquals("The output is not correct.",
-                "<dl>" +
-                        
"<dt><code>coolAttribute01</code></dt><dd><code>weirdValue01</code></dd>" +
-                        
"<dt><code>testAttribute02</code></dt><dd><code>testValue02</code></dd>" +
-                        "</dl>", output);
-    }
-}
+/*
+ * 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.taglib;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import javax.servlet.jsp.JspWriter;
+import javax.servlet.jsp.PageContext;
+import javax.servlet.jsp.tagext.Tag;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.mock.web.MockJspWriter;
+import org.springframework.mock.web.MockPageContext;
+
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class DumpTagTest {
+    private static final Charset UTF8 = StandardCharsets.UTF_8;
+    private Writer writer;
+    private ByteArrayOutputStream output;
+    private MockPageContext context;
+    private DumpTag tag;
+
+    @Before
+    public void setUp() {
+        this.output = new ByteArrayOutputStream();
+        this.writer = new OutputStreamWriter(this.output, UTF8);
+
+        this.context = new MockPageContext() {
+            private final MockJspWriter jspWriter = new MockJspWriter(writer);
+            @Override
+            public JspWriter getOut() {
+                return this.jspWriter;
+            }
+        };
+
+        this.tag = new DumpTag();
+        this.tag.setPageContext(this.context);
+    }
+
+    @Test
+    public void testDoEndTagDefaultPageScopeNoAttributes() throws Exception {
+        final int returnValue = this.tag.doEndTag();
+        assertEquals("The return value is not correct.", Tag.EVAL_PAGE, 
returnValue);
+
+        this.writer.flush();
+        final String output = new String(this.output.toByteArray(), UTF8);
+        assertEquals("The output is not correct.", "<dl></dl>", output);
+    }
+
+    @Test
+    public void testDoEndTagDefaultPageScope() throws Exception {
+        this.context.setAttribute("testAttribute01", "testValue01", 
PageContext.PAGE_SCOPE);
+        this.context.setAttribute("anotherAttribute02", "finalValue02", 
PageContext.PAGE_SCOPE);
+        this.context.setAttribute("badAttribute03", "skippedValue03", 
PageContext.SESSION_SCOPE);
+
+        final int returnValue = this.tag.doEndTag();
+        assertEquals("The return value is not correct.", Tag.EVAL_PAGE, 
returnValue);
+
+        this.writer.flush();
+        final String output = new String(this.output.toByteArray(), UTF8);
+        assertEquals("The output is not correct.",
+                "<dl>" +
+                        
"<dt><code>testAttribute01</code></dt><dd><code>testValue01</code></dd>" +
+                        
"<dt><code>anotherAttribute02</code></dt><dd><code>finalValue02</code></dd>" +
+                        "</dl>", output);
+    }
+
+    @Test
+    public void testDoEndTagSessionScopeNoAttributes() throws Exception {
+        this.context.setAttribute("badAttribute01", "skippedValue01", 
PageContext.PAGE_SCOPE);
+
+        this.tag.setScope("session");
+        final int returnValue = this.tag.doEndTag();
+        assertEquals("The return value is not correct.", Tag.EVAL_PAGE, 
returnValue);
+
+        this.writer.flush();
+        final String output = new String(this.output.toByteArray(), UTF8);
+        assertEquals("The output is not correct.", "<dl></dl>", output);
+    }
+
+    @Test
+    public void testDoEndTagSessionScope() throws Exception {
+        this.context.setAttribute("otherAttribute03", "lostValue03", 
PageContext.PAGE_SCOPE);
+        this.context.setAttribute("coolAttribute01", "weirdValue01", 
PageContext.SESSION_SCOPE);
+        this.context.setAttribute("testAttribute02", "testValue02", 
PageContext.SESSION_SCOPE);
+
+        this.tag.setScope("session");
+        final int returnValue = this.tag.doEndTag();
+        assertEquals("The return value is not correct.", Tag.EVAL_PAGE, 
returnValue);
+
+        this.writer.flush();
+        final String output = new String(this.output.toByteArray(), UTF8);
+        assertEquals("The output is not correct.",
+                "<dl>" +
+                        
"<dt><code>coolAttribute01</code></dt><dd><code>weirdValue01</code></dd>" +
+                        
"<dt><code>testAttribute02</code></dt><dd><code>testValue02</code></dd>" +
+                        "</dl>", output);
+    }
+}
diff --git 
a/log4j-to-slf4j/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java
 
b/log4j-to-slf4j/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java
index 7ebab7a100..d8ed79b518 100644
--- 
a/log4j-to-slf4j/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java
+++ 
b/log4j-to-slf4j/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java
@@ -1,65 +1,66 @@
-/*
- * 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.slf4j;
-
-import java.util.List;
-
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.testUtil.StringListAppender;
-import org.apache.logging.log4j.LogManager;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-public class CallerInformationTest {
-
-    private static final String CONFIG = 
"target/test-classes/logback-calling-class.xml";
-
-    @ClassRule
-    public static final LoggerContextRule CTX = new LoggerContextRule(CONFIG);
-
-    @Test
-    public void testClassLogger() throws Exception {
-        final SLF4JLogger logger = (SLF4JLogger) 
LogManager.getLogger("ClassLogger");
-        final StringListAppender<ILoggingEvent> app = 
TestUtil.getListAppender(logger, "Class");
-        logger.info("Ignored message contents.");
-        logger.warn("Verifying the caller class is still correct.");
-        logger.error("Hopefully nobody breaks me!");
-        final List<String> messages = app.strList;
-        assertEquals("Incorrect number of messages.", 3, messages.size());
-        for (final String message : messages) {
-            assertEquals("Incorrect caller class name.", 
this.getClass().getName(), message);
-        }
-    }
-
-    @Test
-    public void testMethodLogger() throws Exception {
-        final SLF4JLogger logger = (SLF4JLogger) 
LogManager.getLogger("MethodLogger");
-        final StringListAppender<ILoggingEvent> app = 
TestUtil.getListAppender(logger, "Method");
-        logger.info("More messages.");
-        logger.warn("CATASTROPHE INCOMING!");
-        logger.error("ZOMBIES!!!");
-        logger.warn("brains~~~");
-        logger.info("Itchy. Tasty.");
-        final List<String> messages = app.strList;
-        assertEquals("Incorrect number of messages.", 5, messages.size());
-        for (final String message : messages) {
-            assertEquals("Incorrect caller method name.", "testMethodLogger", 
message);
-        }
-    }
-}
+/*
+ * 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.slf4j;
+
+import java.util.List;
+
+import org.apache.logging.log4j.LogManager;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.testUtil.StringListAppender;
+
+import static org.junit.Assert.*;
+
+public class CallerInformationTest {
+
+    private static final String CONFIG = 
"target/test-classes/logback-calling-class.xml";
+
+    @ClassRule
+    public static final LoggerContextRule CTX = new LoggerContextRule(CONFIG);
+
+    @Test
+    public void testClassLogger() throws Exception {
+        final SLF4JLogger logger = (SLF4JLogger) 
LogManager.getLogger("ClassLogger");
+        final StringListAppender<ILoggingEvent> app = 
TestUtil.getListAppender(logger, "Class");
+        logger.info("Ignored message contents.");
+        logger.warn("Verifying the caller class is still correct.");
+        logger.error("Hopefully nobody breaks me!");
+        final List<String> messages = app.strList;
+        assertEquals("Incorrect number of messages.", 3, messages.size());
+        for (final String message : messages) {
+            assertEquals("Incorrect caller class name.", 
this.getClass().getName(), message);
+        }
+    }
+
+    @Test
+    public void testMethodLogger() throws Exception {
+        final SLF4JLogger logger = (SLF4JLogger) 
LogManager.getLogger("MethodLogger");
+        final StringListAppender<ILoggingEvent> app = 
TestUtil.getListAppender(logger, "Method");
+        logger.info("More messages.");
+        logger.warn("CATASTROPHE INCOMING!");
+        logger.error("ZOMBIES!!!");
+        logger.warn("brains~~~");
+        logger.info("Itchy. Tasty.");
+        final List<String> messages = app.strList;
+        assertEquals("Incorrect number of messages.", 5, messages.size());
+        for (final String message : messages) {
+            assertEquals("Incorrect caller method name.", "testMethodLogger", 
message);
+        }
+    }
+}
diff --git 
a/log4j-to-slf4j/src/test/java/org/apache/logging/slf4j/LoggerContextRule.java 
b/log4j-to-slf4j/src/test/java/org/apache/logging/slf4j/LoggerContextRule.java
index 0f245e226d..706ddc5467 100644
--- 
a/log4j-to-slf4j/src/test/java/org/apache/logging/slf4j/LoggerContextRule.java
+++ 
b/log4j-to-slf4j/src/test/java/org/apache/logging/slf4j/LoggerContextRule.java
@@ -1,72 +1,73 @@
-/*
- * 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.slf4j;
-
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.joran.JoranConfigurator;
-import ch.qos.logback.core.joran.GenericConfigurator;
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-import org.slf4j.LoggerFactory;
-
-/**
- * JUnit {@link TestRule} similar to the TestRule in {@code log4j-core} of the 
same name.
- *
- * @since 2.1
- * @since 2.4.1 Renamed InitialLoggerContext to LoggerContextRule
- */
-public class LoggerContextRule implements TestRule {
-
-    private final String configLocation;
-
-    private LoggerContext context;
-
-    private String testClassName;
-
-    public LoggerContextRule(final String configLocation) {
-        this.configLocation = configLocation;
-    }
-
-    @Override
-    public Statement apply(final Statement base, final Description 
description) {
-        testClassName = description.getClassName();
-        return new Statement() {
-            @Override
-            public void evaluate() throws Throwable {
-                context = (LoggerContext) LoggerFactory.getILoggerFactory();
-                final GenericConfigurator configurator = new 
JoranConfigurator();
-                configurator.setContext(context);
-                configurator.doConfigure(configLocation);
-                base.evaluate();
-            }
-        };
-    }
-
-    public LoggerContext getContext() {
-        return context;
-    }
-
-    public Logger getLogger() {
-        return context.getLogger(testClassName);
-    }
-
-    public Logger getLogger(final String name) {
-        return context.getLogger(name);
-    }
-}
+/*
+ * 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.slf4j;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import org.slf4j.LoggerFactory;
+
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.core.joran.GenericConfigurator;
+
+/**
+ * JUnit {@link TestRule} similar to the TestRule in {@code log4j-core} of the 
same name.
+ *
+ * @since 2.1
+ * @since 2.4.1 Renamed InitialLoggerContext to LoggerContextRule
+ */
+public class LoggerContextRule implements TestRule {
+
+    private final String configLocation;
+
+    private LoggerContext context;
+
+    private String testClassName;
+
+    public LoggerContextRule(final String configLocation) {
+        this.configLocation = configLocation;
+    }
+
+    @Override
+    public Statement apply(final Statement base, final Description 
description) {
+        testClassName = description.getClassName();
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                context = (LoggerContext) LoggerFactory.getILoggerFactory();
+                final GenericConfigurator configurator = new 
JoranConfigurator();
+                configurator.setContext(context);
+                configurator.doConfigure(configLocation);
+                base.evaluate();
+            }
+        };
+    }
+
+    public LoggerContext getContext() {
+        return context;
+    }
+
+    public Logger getLogger() {
+        return context.getLogger(testClassName);
+    }
+
+    public Logger getLogger(final String name) {
+        return context.getLogger(name);
+    }
+}


Reply via email to