This is an automated email from the ASF dual-hosted git repository.
rgoers pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
The following commit(s) were added to refs/heads/master by this push:
new 2f0d50f2c0 log4j-jul is now a JPMS module
2f0d50f2c0 is described below
commit 2f0d50f2c018c02372707cb11d1831d08f9ec4dd
Author: Ralph Goers <[email protected]>
AuthorDate: Thu Sep 1 01:47:43 2022 -0700
log4j-jul is now a JPMS module
---
.../appender/rolling/RollingNewDirectoryTest.java | 19 +-
log4j-jul/pom.xml | 65 +-
.../java/module-info.java} | 57 +-
...ultLevelConverterTest.java => module-info.java} | 62 +-
.../log4j/jul/{ => test}/AbstractLoggerTest.java | 5 +-
.../log4j/jul/{ => test}/ApiLoggerTest.java | 6 +-
.../jul/{ => test}/AsyncLoggerThreadsTest.java | 7 +-
.../BracketInNotInterpolatedMessageTest.java | 4 +-
.../jul/{ => test}/CallerInformationTest.java | 179 ++--
.../log4j/jul/{ => test}/CoreLoggerTest.java | 4 +-
.../DefaultLevelConverterCustomJulLevelsTest.java | 4 +-
.../jul/{ => test}/DefaultLevelConverterTest.java | 63 +-
.../jul/{ => test}/JavaLevelTranslatorTest.java | 3 +-
.../logging/log4j/jul/test/ListAppender.java | 289 +++++++
.../jul/{ => test}/Log4jBridgeHandlerTest.java | 918 ++++++++++-----------
.../jul/{ => test}/Log4jLevelTranslatorTest.java | 3 +-
.../src/test/resources/log4j2-calling-class.xml | 37 +
.../src/test/resources/log4j2-julBridge-test.xml | 2 +-
pom.xml | 2 +-
19 files changed, 1078 insertions(+), 651 deletions(-)
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingNewDirectoryTest.java
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingNewDirectoryTest.java
index 4909ac110b..1dd931b4a0 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingNewDirectoryTest.java
+++
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingNewDirectoryTest.java
@@ -20,17 +20,20 @@ import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
import org.apache.logging.log4j.plugins.Named;
import org.apache.logging.log4j.test.junit.CleanUpDirectories;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.fail;
/**
* Tests
*/
-public class RollingNewDirectoryTest extends AbstractRollingListenerTest {
+public class RollingNewDirectoryTest implements RolloverListener {
private static final String CONFIG = "log4j-rolling-new-directory.xml";
private static final String DIR = "target/rolling-new-directory";
@@ -43,14 +46,24 @@ public class RollingNewDirectoryTest extends
AbstractRollingListenerTest {
manager.addRolloverListener(this);
for (int i = 0; i < 10; ++i) {
logger.info("AAA");
- currentTimeMillis.addAndGet(300);
+ Thread.sleep(300);
+ }
+ try {
+ if (!rollover.await(5, TimeUnit.SECONDS)) {
+ fail("Timer expired before rollover");
+ }
+ } catch (InterruptedException ie) {
+ fail("Thread was interrupted");
}
- rollover.await();
final File dir = new File(DIR);
assertThat(dir).isNotEmptyDirectory();
assertThat(dir.listFiles()).hasSizeGreaterThan(2);
}
+ @Override
+ public void rolloverTriggered(final String fileName) {
+ }
+
@Override
public void rolloverComplete(final String fileName) {
rollover.countDown();
diff --git a/log4j-jul/pom.xml b/log4j-jul/pom.xml
index 04d76b3140..d77dbd7bc9 100644
--- a/log4j-jul/pom.xml
+++ b/log4j-jul/pom.xml
@@ -26,7 +26,6 @@
<properties>
<log4jParentDir>${basedir}/..</log4jParentDir>
- <module.name>org.apache.logging.log4j.jul</module.name>
<maven.doap.skip>true</maven.doap.skip>
</properties>
@@ -44,6 +43,42 @@
<artifactId>log4j-core</artifactId>
<optional>true</optional>
</dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-api-test</artifactId>
+ <scope>test</scope>
+ <exclusions>
+ <!-- Exclude Junit 5 - it is hardwired to use java.util.logging and
breaks all these tests -->
+ <exclusion>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.junit.platform</groupId>
+ <artifactId>junit-platform-commons</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.junit.platform</groupId>
+ <artifactId>junit-platform-launcher</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-migrationsupport</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-params</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.junit-pioneer</groupId>
+ <artifactId>junit-pioneer</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core-test</artifactId>
@@ -112,6 +147,34 @@
</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>default-jar</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ <configuration combine.self="override">
+ <archive>
+ <manifestFile>${manifestfile}</manifestFile>
+ <manifestEntries>
+ <Specification-Title>${project.name}</Specification-Title>
+
<Specification-Version>${project.version}</Specification-Version>
+
<Specification-Vendor>${project.organization.name}</Specification-Vendor>
+ <Implementation-Title>${project.name}</Implementation-Title>
+
<Implementation-Version>${project.version}</Implementation-Version>
+
<Implementation-Vendor>${project.organization.name}</Implementation-Vendor>
+
<Implementation-Vendor-Id>org.apache</Implementation-Vendor-Id>
+
<X-Compile-Source-JDK>${maven.compiler.source}</X-Compile-Source-JDK>
+
<X-Compile-Target-JDK>${maven.compiler.target}</X-Compile-Target-JDK>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
diff --git
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/DefaultLevelConverterTest.java
b/log4j-jul/src/main/java/module-info.java
similarity index 66%
copy from
log4j-jul/src/test/java/org/apache/logging/log4j/jul/DefaultLevelConverterTest.java
copy to log4j-jul/src/main/java/module-info.java
index 801749ec27..31c51021c4 100644
---
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/DefaultLevelConverterTest.java
+++ b/log4j-jul/src/main/java/module-info.java
@@ -1,31 +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.jul;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-public class DefaultLevelConverterTest {
-
- /**
- * (LOG4J2-1108) NullPointerException when passing null to
java.util.logging.Logger.setLevel().
- */
- @Test
- public void testJulSetNull() {
- Assert.assertEquals(null, new DefaultLevelConverter().toLevel(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.
+ */
+
+module org.apache.logging.log4j.jul {
+ exports org.apache.logging.log4j.jul;
+ opens org.apache.logging.log4j.jul to org.apache.logging.log4j;
+
+ requires org.apache.logging.log4j;
+ requires org.apache.logging.log4j.core;
+ requires java.desktop;
+ requires java.logging;
+}
diff --git
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/DefaultLevelConverterTest.java
b/log4j-jul/src/test/java/module-info.java
similarity index 62%
copy from
log4j-jul/src/test/java/org/apache/logging/log4j/jul/DefaultLevelConverterTest.java
copy to log4j-jul/src/test/java/module-info.java
index 801749ec27..764f4036d3 100644
---
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/DefaultLevelConverterTest.java
+++ b/log4j-jul/src/test/java/module-info.java
@@ -1,31 +1,31 @@
-/*
- * 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 org.junit.Assert;
-import org.junit.Test;
-
-public class DefaultLevelConverterTest {
-
- /**
- * (LOG4J2-1108) NullPointerException when passing null to
java.util.logging.Logger.setLevel().
- */
- @Test
- public void testJulSetNull() {
- Assert.assertEquals(null, new DefaultLevelConverter().toLevel(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.
+ */
+module org.apache.logging.log4j.jul.test {
+ exports org.apache.logging.log4j.jul.test;
+
+ requires org.apache.logging.log4j;
+ requires org.apache.logging.log4j.core;
+ requires org.apache.logging.log4j.jul;
+ requires org.assertj.core;
+ requires org.hamcrest;
+ requires java.desktop;
+ requires java.logging;
+
+ requires junit;
+
+ provides org.apache.logging.log4j.plugins.processor.PluginService with
org.apache.logging.log4j.jul.test.plugins.Log4jPlugins;
+}
\ No newline at end of file
diff --git
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/AbstractLoggerTest.java
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/AbstractLoggerTest.java
similarity index 98%
rename from
log4j-jul/src/test/java/org/apache/logging/log4j/jul/AbstractLoggerTest.java
rename to
log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/AbstractLoggerTest.java
index 263765235b..1e446e4397 100644
---
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/AbstractLoggerTest.java
+++
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/AbstractLoggerTest.java
@@ -15,7 +15,7 @@
* limitations under the license.
*/
-package org.apache.logging.log4j.jul;
+package org.apache.logging.log4j.jul.test;
import java.util.List;
import java.util.logging.Logger;
@@ -23,7 +23,8 @@ import java.util.logging.Logger;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
-import org.apache.logging.log4j.core.test.appender.ListAppender;
+import org.apache.logging.log4j.jul.ApiLogger;
+import org.apache.logging.log4j.jul.LevelTranslator;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
diff --git
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/ApiLoggerTest.java
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/ApiLoggerTest.java
similarity index 93%
rename from
log4j-jul/src/test/java/org/apache/logging/log4j/jul/ApiLoggerTest.java
rename to
log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/ApiLoggerTest.java
index aafd287871..bb69781f9f 100644
--- a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/ApiLoggerTest.java
+++
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/ApiLoggerTest.java
@@ -15,7 +15,7 @@
* limitations under the license.
*/
-package org.apache.logging.log4j.jul;
+package org.apache.logging.log4j.jul.test;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertNotNull;
@@ -24,7 +24,9 @@ import static org.junit.Assert.assertThat;
import java.util.logging.Logger;
-import org.apache.logging.log4j.core.test.appender.ListAppender;
+import org.apache.logging.log4j.jul.ApiLoggerAdapter;
+import org.apache.logging.log4j.jul.Constants;
+import org.apache.logging.log4j.jul.LogManager;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
diff --git
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/AsyncLoggerThreadsTest.java
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/AsyncLoggerThreadsTest.java
similarity index 89%
rename from
log4j-jul/src/test/java/org/apache/logging/log4j/jul/AsyncLoggerThreadsTest.java
rename to
log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/AsyncLoggerThreadsTest.java
index 509c36ce44..3d8c02bf9b 100644
---
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/AsyncLoggerThreadsTest.java
+++
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/AsyncLoggerThreadsTest.java
@@ -14,11 +14,10 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.jul;
+package org.apache.logging.log4j.jul.test;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector;
-import org.apache.logging.log4j.core.test.categories.AsyncLoggers;
import org.apache.logging.log4j.core.util.Constants;
import org.junit.AfterClass;
import org.junit.BeforeClass;
@@ -31,7 +30,7 @@ import java.util.stream.Collectors;
import static org.junit.Assert.assertEquals;
-@Category(AsyncLoggers.class)
+//@Category(AsyncLoggers.class)
@Ignore("https://issues.apache.org/jira/browse/LOG4J2-3523")
public class AsyncLoggerThreadsTest {
@@ -39,7 +38,7 @@ public class AsyncLoggerThreadsTest {
public static void beforeClass() {
System.setProperty(Constants.LOG4J_CONTEXT_SELECTOR,
AsyncLoggerContextSelector.class.getName());
- System.setProperty("java.util.logging.manager",
org.apache.logging.log4j.jul.LogManager.class.getName());
+ System.setProperty("java.util.logging.manager",
LogManager.class.getName());
}
@AfterClass
diff --git
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/BracketInNotInterpolatedMessageTest.java
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/BracketInNotInterpolatedMessageTest.java
similarity index 95%
rename from
log4j-jul/src/test/java/org/apache/logging/log4j/jul/BracketInNotInterpolatedMessageTest.java
rename to
log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/BracketInNotInterpolatedMessageTest.java
index 598cb84332..d2385b0785 100644
---
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/BracketInNotInterpolatedMessageTest.java
+++
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/BracketInNotInterpolatedMessageTest.java
@@ -14,14 +14,14 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.jul;
+package org.apache.logging.log4j.jul.test;
import java.util.List;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.test.appender.ListAppender;
+import org.apache.logging.log4j.jul.LogManager;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
diff --git
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/CallerInformationTest.java
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/CallerInformationTest.java
similarity index 72%
rename from
log4j-jul/src/test/java/org/apache/logging/log4j/jul/CallerInformationTest.java
rename to
log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/CallerInformationTest.java
index 2df2827145..74bdedae5f 100644
---
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/CallerInformationTest.java
+++
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/CallerInformationTest.java
@@ -1,78 +1,101 @@
-/*
- * 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.List;
-import java.util.logging.Logger;
-
-import org.apache.logging.log4j.core.test.junit.LoggerContextRule;
-import org.apache.logging.log4j.core.test.appender.ListAppender;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-public class CallerInformationTest {
-
- // config from log4j-core test-jar
- private static final String CONFIG = "log4j2-calling-class.xml";
-
- @Rule
- public final LoggerContextRule ctx = new LoggerContextRule(CONFIG);
-
- @BeforeClass
- public static void setUpClass() {
- System.setProperty("java.util.logging.manager",
LogManager.class.getName());
- }
-
- @AfterClass
- public static void tearDownClass() {
- System.clearProperty("java.util.logging.manager");
- }
-
- @Test
- public void testClassLogger() throws Exception {
- final ListAppender app = ctx.getListAppender("Class").clear();
- final Logger logger = Logger.getLogger("ClassLogger");
- logger.info("Ignored message contents.");
- logger.warning("Verifying the caller class is still correct.");
- logger.severe("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 Logger logger = Logger.getLogger("MethodLogger");
- logger.info("More messages.");
- logger.warning("CATASTROPHE INCOMING!");
- logger.severe("ZOMBIES!!!");
- logger.warning("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.jul.test;
+
+import java.net.URI;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.jul.LogManager;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class CallerInformationTest {
+
+ // config from log4j-core test-jar
+ private static final String CONFIG = "log4j2-calling-class.xml";
+
+ private LoggerContext ctx;
+ private ListAppender app;
+
+
+ @BeforeClass
+ public static void setUpClass() {
+ System.setProperty("java.util.logging.manager",
LogManager.class.getName());
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ System.clearProperty("java.util.logging.manager");
+ }
+
+ @Before
+ public void beforeEach() throws Exception {
+ URI uri = this.getClass().getClassLoader().getResource(CONFIG).toURI();
+ ctx =
(LoggerContext)org.apache.logging.log4j.LogManager.getContext(null, false, uri);
+ assertNotNull("No LoggerContext", ctx);
+ }
+
+ @After
+ public void afterEach() throws Exception {
+ if (ctx != null) {
+ ctx.stop();
+ ctx = null;
+ app = null;
+ }
+ }
+
+ @Test
+ public void testClassLogger() throws Exception {
+ app = ctx.getConfiguration().getAppender("Class");
+ assertNotNull("No ListAppender", app);
+ app.clear();
+ final Logger logger = Logger.getLogger("ClassLogger");
+ logger.info("Ignored message contents.");
+ logger.warning("Verifying the caller class is still correct.");
+ logger.severe("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 {
+ app = ctx.getConfiguration().getAppender("Method");
+ assertNotNull("No ListAppender", app);
+ app.clear();
+ final Logger logger = Logger.getLogger("MethodLogger");
+ logger.info("More messages.");
+ logger.warning("CATASTROPHE INCOMING!");
+ logger.severe("ZOMBIES!!!");
+ logger.warning("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/test/java/org/apache/logging/log4j/jul/CoreLoggerTest.java
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/CoreLoggerTest.java
similarity index 97%
rename from
log4j-jul/src/test/java/org/apache/logging/log4j/jul/CoreLoggerTest.java
rename to
log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/CoreLoggerTest.java
index 39aefee74c..6cf6b547e2 100644
--- a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/CoreLoggerTest.java
+++
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/CoreLoggerTest.java
@@ -15,7 +15,7 @@
* limitations under the license.
*/
-package org.apache.logging.log4j.jul;
+package org.apache.logging.log4j.jul.test;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
@@ -25,7 +25,7 @@ import static org.junit.Assert.assertThat;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.apache.logging.log4j.core.test.appender.ListAppender;
+import org.apache.logging.log4j.jul.LogManager;
import org.apache.logging.log4j.util.Strings;
import org.junit.After;
import org.junit.AfterClass;
diff --git
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/DefaultLevelConverterCustomJulLevelsTest.java
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/DefaultLevelConverterCustomJulLevelsTest.java
similarity index 97%
rename from
log4j-jul/src/test/java/org/apache/logging/log4j/jul/DefaultLevelConverterCustomJulLevelsTest.java
rename to
log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/DefaultLevelConverterCustomJulLevelsTest.java
index 03f3cffda1..6183951ae7 100644
---
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/DefaultLevelConverterCustomJulLevelsTest.java
+++
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/DefaultLevelConverterCustomJulLevelsTest.java
@@ -14,9 +14,11 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.jul;
+package org.apache.logging.log4j.jul.test;
import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.jul.DefaultLevelConverter;
+import org.apache.logging.log4j.jul.LevelTranslator;
import org.junit.Assert;
import org.junit.Test;
diff --git
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/DefaultLevelConverterTest.java
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/DefaultLevelConverterTest.java
similarity index 91%
rename from
log4j-jul/src/test/java/org/apache/logging/log4j/jul/DefaultLevelConverterTest.java
rename to
log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/DefaultLevelConverterTest.java
index 801749ec27..7ae1803808 100644
---
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/DefaultLevelConverterTest.java
+++
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/DefaultLevelConverterTest.java
@@ -1,31 +1,32 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.jul;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-public class DefaultLevelConverterTest {
-
- /**
- * (LOG4J2-1108) NullPointerException when passing null to
java.util.logging.Logger.setLevel().
- */
- @Test
- public void testJulSetNull() {
- Assert.assertEquals(null, new DefaultLevelConverter().toLevel(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.jul.test;
+
+import org.apache.logging.log4j.jul.DefaultLevelConverter;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class DefaultLevelConverterTest {
+
+ /**
+ * (LOG4J2-1108) NullPointerException when passing null to
java.util.logging.Logger.setLevel().
+ */
+ @Test
+ public void testJulSetNull() {
+ Assert.assertEquals(null, new DefaultLevelConverter().toLevel(null));
+ }
+}
diff --git
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/JavaLevelTranslatorTest.java
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/JavaLevelTranslatorTest.java
similarity index 96%
rename from
log4j-jul/src/test/java/org/apache/logging/log4j/jul/JavaLevelTranslatorTest.java
rename to
log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/JavaLevelTranslatorTest.java
index 5ccc9c2345..46c010cf6b 100644
---
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/JavaLevelTranslatorTest.java
+++
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/JavaLevelTranslatorTest.java
@@ -15,12 +15,13 @@
* limitations under the license.
*/
-package org.apache.logging.log4j.jul;
+package org.apache.logging.log4j.jul.test;
import java.util.Arrays;
import java.util.Collection;
import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.jul.LevelTranslator;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
diff --git
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/ListAppender.java
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/ListAppender.java
new file mode 100644
index 0000000000..1f7fe83a4a
--- /dev/null
+++
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/ListAppender.java
@@ -0,0 +1,289 @@
+/*
+ * 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.test;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.AbstractAppender;
+import org.apache.logging.log4j.core.config.Property;
+import org.apache.logging.log4j.core.impl.MutableLogEvent;
+import org.apache.logging.log4j.plugins.Configurable;
+import org.apache.logging.log4j.plugins.Plugin;
+import org.apache.logging.log4j.plugins.PluginAttribute;
+import org.apache.logging.log4j.plugins.PluginElement;
+import org.apache.logging.log4j.plugins.PluginFactory;
+import org.apache.logging.log4j.plugins.validation.constraints.Required;
+
+/**
+ * This appender is primarily used for testing. Use in a real environment is
discouraged as the List could eventually
+ * grow to cause an OutOfMemoryError.
+ *
+ * This appender is not thread-safe.
+ *
+ * This appender will use {@link Layout#toByteArray(LogEvent)}.
+ *
+ */
+@Configurable(elementType = Appender.ELEMENT_TYPE, printObject = true)
+@Plugin("List")
+public class ListAppender extends AbstractAppender {
+
+ // Use Collections.synchronizedList rather than CopyOnWriteArrayList
because we expect
+ // more frequent writes than reads.
+ final List<LogEvent> events = Collections.synchronizedList(new
ArrayList<>());
+
+ private final List<String> messages = Collections.synchronizedList(new
ArrayList<>());
+
+ final List<byte[]> data = Collections.synchronizedList(new ArrayList<>());
+
+ private final boolean newLine;
+
+ private final boolean raw;
+
+ private static final String WINDOWS_LINE_SEP = "\r\n";
+
+ /**
+ * CountDownLatch for asynchronous logging tests. Example usage:
+ *
+ * <pre>
+ * @Rule
+ * public LoggerContextRule context = new
LoggerContextRule("log4j-list.xml");
+ * private ListAppender listAppender;
+ *
+ * @Before
+ * public void before() throws Exception {
+ * listAppender = context.getListAppender("List");
+ * }
+ *
+ * @Test
+ * public void testSomething() throws Exception {
+ * listAppender.countDownLatch = new CountDownLatch(1);
+ *
+ * Logger logger = LogManager.getLogger();
+ * logger.info("log one event asynchronously");
+ *
+ * // wait for the appender to finish processing this event (wait max
1 second)
+ * listAppender.countDownLatch.await(1, TimeUnit.SECONDS);
+ *
+ * // now assert something or do follow-up tests...
+ * }
+ * </pre>
+ */
+ public volatile CountDownLatch countDownLatch = null;
+
+ public ListAppender(final String name) {
+ super(name, null, null, true, Property.EMPTY_ARRAY);
+ newLine = false;
+ raw = false;
+ }
+
+ public ListAppender(final String name, final Filter filter, final Layout<?
extends Serializable> layout,
+ final boolean newline, final boolean raw) {
+ super(name, filter, layout, true, Property.EMPTY_ARRAY);
+ this.newLine = newline;
+ this.raw = raw;
+ if (layout != null) {
+ final byte[] bytes = layout.getHeader();
+ if (bytes != null) {
+ write(bytes);
+ }
+ }
+ }
+
+ @Override
+ public void append(final LogEvent event) {
+ final Layout<? extends Serializable> layout = getLayout();
+ if (layout == null) {
+ if (event instanceof MutableLogEvent) {
+ // must take snapshot or subsequent calls to logger.log() will
modify this event
+ events.add(((MutableLogEvent) event).createMemento());
+ } else {
+ events.add(event);
+ }
+ } else {
+ write(layout.toByteArray(event));
+ }
+ if (countDownLatch != null) {
+ countDownLatch.countDown();
+ }
+ }
+
+ void write(final byte[] bytes) {
+ if (raw) {
+ data.add(bytes);
+ return;
+ }
+ final String str = new String(bytes);
+ if (newLine) {
+ int index = 0;
+ while (index < str.length()) {
+ int end;
+ final int wend = str.indexOf(WINDOWS_LINE_SEP, index);
+ final int lend = str.indexOf('\n', index);
+ int length;
+ if (wend >= 0 && wend < lend) {
+ end = wend;
+ length = 2;
+ } else {
+ end = lend;
+ length = 1;
+ }
+ if (index == end) {
+ if (!messages.get(messages.size() - length).isEmpty()) {
+ messages.add("");
+ }
+ } else if (end >= 0) {
+ messages.add(str.substring(index, end));
+ } else {
+ messages.add(str.substring(index));
+ break;
+ }
+ index = end + length;
+ }
+ } else {
+ messages.add(str);
+ }
+ }
+
+ @Override
+ public boolean stop(final long timeout, final TimeUnit timeUnit) {
+ setStopping();
+ super.stop(timeout, timeUnit, false);
+ final Layout<? extends Serializable> layout = getLayout();
+ if (layout != null) {
+ final byte[] bytes = layout.getFooter();
+ if (bytes != null) {
+ write(bytes);
+ }
+ }
+ setStopped();
+ return true;
+ }
+
+ public ListAppender clear() {
+ events.clear();
+ messages.clear();
+ data.clear();
+ return this;
+ }
+
+ /** Returns an immutable snapshot of captured log events */
+ public List<LogEvent> getEvents() {
+ return Collections.unmodifiableList(new ArrayList<>(events));
+ }
+
+ /** Returns an immutable snapshot of captured messages */
+ public List<String> getMessages() {
+ return List.copyOf(messages);
+ }
+
+ /**
+ * Polls the messages list for it to grow to a given minimum size at most
timeout timeUnits and return a copy of
+ * what we have so far.
+ */
+ public List<String> getMessages(final int minSize, final long timeout,
final TimeUnit timeUnit)
+ throws InterruptedException {
+ final long endMillis = System.currentTimeMillis() +
timeUnit.toMillis(timeout);
+ while (messages.size() < minSize && System.currentTimeMillis() <
endMillis) {
+ Thread.sleep(100);
+ }
+ return getMessages();
+ }
+
+ /** Returns an immutable snapshot of captured data */
+ public List<byte[]> getData() {
+ return List.copyOf(data);
+ }
+
+ public static ListAppender createAppender(final String name, final boolean
newLine, final boolean raw,
+ final Layout<? extends Serializable> layout, final Filter filter) {
+ return new ListAppender(name, filter, layout, newLine, raw);
+ }
+
+ @PluginFactory
+ public static Builder newBuilder() {
+ return new Builder();
+ }
+
+ public static class Builder implements
org.apache.logging.log4j.plugins.util.Builder<ListAppender> {
+
+ private String name;
+ private boolean entryPerNewLine;
+ private boolean raw;
+ private Layout<? extends Serializable> layout;
+ private Filter filter;
+
+ public Builder setName(@Required @PluginAttribute final String name) {
+ this.name = name;
+ return this;
+ }
+
+ public Builder setEntryPerNewLine(@PluginAttribute final boolean
entryPerNewLine) {
+ this.entryPerNewLine = entryPerNewLine;
+ return this;
+ }
+
+ public Builder setRaw(@PluginAttribute final boolean raw) {
+ this.raw = raw;
+ return this;
+ }
+
+ public Builder setLayout(@PluginElement final Layout<? extends
Serializable> layout) {
+ this.layout = layout;
+ return this;
+ }
+
+ public Builder setFilter(@PluginElement final Filter filter) {
+ this.filter = filter;
+ return this;
+ }
+
+ @Override
+ public ListAppender build() {
+ return new ListAppender(name, filter, layout, entryPerNewLine,
raw);
+ }
+ }
+
+ /**
+ * Gets the named ListAppender if it has been registered.
+ *
+ * @param name
+ * the name of the ListAppender
+ * @return the named ListAppender or {@code null} if it does not exist
+ * @see LoggerContextRule#getListAppender(String)
+ */
+ public static ListAppender getListAppender(final String name) {
+ return
(LoggerContext.getContext(false)).getConfiguration().getAppender(name);
+ }
+
+ @Override
+ public String toString() {
+ return "ListAppender [events=" + events + ", messages=" + messages +
", data=" + data + ", newLine=" + newLine
+ + ", raw=" + raw + ", countDownLatch=" + countDownLatch + ",
getHandler()=" + getHandler()
+ + ", getLayout()=" + getLayout() + ", getName()=" + getName()
+ ", ignoreExceptions()="
+ + ignoreExceptions() + ", getFilter()=" + getFilter() + ",
getState()=" + getState() + "]";
+ }
+}
diff --git
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/Log4jBridgeHandlerTest.java
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/Log4jBridgeHandlerTest.java
similarity index 97%
rename from
log4j-jul/src/test/java/org/apache/logging/log4j/jul/Log4jBridgeHandlerTest.java
rename to
log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/Log4jBridgeHandlerTest.java
index 93093f868a..18b06263b0 100644
---
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/Log4jBridgeHandlerTest.java
+++
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/Log4jBridgeHandlerTest.java
@@ -1,459 +1,459 @@
-/*
- * 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.Map.Entry;
-
-import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.core.config.Configuration;
-import org.apache.logging.log4j.core.config.ConfigurationListener;
-import org.apache.logging.log4j.core.config.Configurator;
-import org.apache.logging.log4j.core.config.LoggerConfig;
-import org.apache.logging.log4j.core.config.Reconfigurable;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-
-
-/**
- * Test the Log4jBridgeHandler.
- * Requires some configurations in the log-config-files, for format/layout
- * see also jul() and log4j():
- * - JUL-config ("logging-test.properties", must be set on JVM-start via
"-D..."):
- * + handlers = org.apache.logging.log4j.jul.Log4jBridgeHandler,
java.util.logging.ConsoleHandler
- * + org.apache.logging.log4j.jul.Log4jBridgeHandler.appendSuffix = _JUL
- * + java.util.logging.ConsoleHandler.level = ALL
- * + java.util.logging.SimpleFormatter.format = JUL: %1$tT.%1$tL %4$s
[%3$s: %2$s] - %5$s%6$s%n
- * + .level = FINER
- * - log4j2-config ("log4j2-test.xml"):
- * + <Root level="TRACE">
- * + <Appenders> <Console> with target="SYSTEM_ERR", follow="true",
- * <PatternLayout> "log4j2: %d{HH:mm:ss.SSS} %5level -
[%thread][%logger: %class/%method/%line] - %message%n"
- *
- * This test needs to capture syserr because it uses
java.util.logging.ConsoleHandler.
- * Also, it performs some outputs to console (sysout and syserr); see also
field OUTPUT_CAPTURED.
- *
- * The code also contains evaluation/test code for development time. It is not
used for the unit tests
- * but kept here for reference and info. See field DEVTEST.
- */
-@FixMethodOrder(org.junit.runners.MethodSorters.NAME_ASCENDING) // is nicer
for manually checking console output
-public class Log4jBridgeHandlerTest {
- /** Perform developer tests? */
- private static final boolean DEVTEST = false;
-
- /** Do output the captured logger-output to stdout? */
- private static final boolean OUTPUT_CAPTURED = !DEVTEST &&
Boolean.parseBoolean(
- System.getProperty("log4j.Log4jBridgeHandlerTest.outputCaptured"));
-
- /** This classes' simple name = relevant part of logger name. */
- private static final String CSNAME =
Log4jBridgeHandlerTest.class.getSimpleName();
- // loggers used in many tests
- private static final java.util.logging.Logger julLog =
java.util.logging.Logger.getLogger(Log4jBridgeHandlerTest.class.getName());
- private static final org.apache.logging.log4j.Logger log4jLog =
org.apache.logging.log4j.LogManager.getLogger();
-
- // capture sysout/syserr
- //@Rule public final SystemErrRule systemOutRule = new
SystemErrRule().enableLog();
- private static final ByteArrayOutputStream sysoutBytes = new
ByteArrayOutputStream(1024);
- private static PrintStream prevSysErrStream;
-
-
- @BeforeClass
- public static void beforeClass() {
- // debug output to easily recognize misconfig.:
- //System.out.println("sys-props:\n" + System.getProperties());
- System.out.println("sysout: logging-cfg-file: " +
System.getProperty("java.util.logging.config.file"));
- if (DEVTEST) devTestBeforeClass(); // call before stderr capturing
-
- // JUL does not like setting stderr inbetween, so set it once and
reset collecting stream
- // for each method; (thus
com.github.stefanbirkner:system-rules:SystemErrRule cannot be used)
- System.err.println("vvv--- BEGIN capturing output to stderr ---vvv"
- + " (do output of captured text to orig. stderr: " +
OUTPUT_CAPTURED + ")");
- prevSysErrStream = System.err;
- System.setErr(new PrintStream(sysoutBytes, true));
- }
-
- @AfterClass
- public static void afterClass() {
- // reset sysout/err to original value
- System.setErr(prevSysErrStream);
- System.err.println("^^^--- END capturing output of stderr ---^^^");
- }
-
-
- @Before
- public void beforeTest() {
- // reset sysout collector
- sysoutBytes.reset();
- }
-
-
-
- /** Assert that captured sysout matches given regexp (any text may follow
afterwards). */
- private void assertSysoutMatches(String regex) {
- //String logOutput = systemOutRule.getLogWithNormalizedLineSeparator();
- String logOutput = sysoutBytes.toString();
- if (OUTPUT_CAPTURED) prevSysErrStream.print(logOutput);
- logOutput = logOutput.replace("\r\n", "\n");
- regex = regex + "(.|\\n)*"; // allow any text with NL afterwards
- assertTrue("Unmatching output:\n" + logOutput + "\n-- vs: --\n" +
regex + "\n----", logOutput.matches(regex));
- }
-
- /** Get regex for a JUL console output. Must match JUL-Console-Formatter!
*/
- private String jul(java.util.logging.Level lvl, String locationPartRE,
- String msgPartRE, String exceptionClassAndMsgRE) {
- return "JUL:.*" + lvl.getLocalizedName() + ".*" + CSNAME
- + ".*" + locationPartRE + ".*" + msgPartRE + ".*\n" // use
real \n at end here for better error output
- + (exceptionClassAndMsgRE == null ? ""
- : ".*" + exceptionClassAndMsgRE + ".*\\n(\tat
.*\\n)*\\n?");
- }
-
- /** Get regex for a log4j console output. Must match
log4j2-Console-Layout! */
- private String log4j(org.apache.logging.log4j.Level lvl, boolean
julBridged,
- String methodPartRE, String msgPartRE, String
exceptionClassAndMsgRE) {
- return "log4j2:.*" + lvl.name() + ".*" + CSNAME + (julBridged ?
"\\._JUL" : "")
- + ".*" + CSNAME + "/\\w*" + methodPartRE + "\\w*/.*"
- + msgPartRE + ".*\n" // use real \n at end here for
better error output
- + (exceptionClassAndMsgRE == null ? ""
- : ".*" + exceptionClassAndMsgRE + ".*\\n(\tat
.*\\n)*\\n?");
- }
-
-
-
- @Test
- public void test1SimpleLoggings1Jul() {
- julLog.info("Test-'Info'-Log with JUL");
- julLog.fine("Test-'Fine'-Log with JUL");
- julLog.finest("Test-'Finest'-Log with JUL"); // should not be
logged because JUL-level is FINER
- julLog.warning("Test-'Warn'-Log with JUL"); // thus add another log
afterwards to allow checking
- String methodRE = "SimpleLoggings1Jul";
- assertSysoutMatches(
- log4j(org.apache.logging.log4j.Level.INFO, true, methodRE,
"'Info'-Log with JUL", null)
- + jul(java.util.logging.Level.INFO, methodRE, "'Info'-Log with
JUL", null)
- + log4j(org.apache.logging.log4j.Level.DEBUG, true, methodRE,
"'Fine'-Log with JUL", null)
- + jul(java.util.logging.Level.FINE, methodRE, "'Fine'-Log with
JUL", null)
- // no finest/trace
- + log4j(org.apache.logging.log4j.Level.WARN, true, methodRE,
"'Warn'-Log with JUL", null)
- + jul(java.util.logging.Level.WARNING, methodRE, "'Warn'-Log
with JUL", null)
- );
- }
-
- @Test
- public void test1SimpleLoggings2Log4jDirect() {
- log4jLog.info("Test-'Info'-Log with log4j2");
- log4jLog.debug("Test-'Debug'-Log with log4j2");
- log4jLog.trace("Test-'Trace'-Log with log4j2");
- String methodRE = "SimpleLoggings2Log4jDirect";
- assertSysoutMatches(
- log4j(org.apache.logging.log4j.Level.INFO, false, methodRE,
"'Info'-Log with log4j2", null)
- + log4j(org.apache.logging.log4j.Level.DEBUG, false, methodRE,
"'Debug'-Log with log4j2", null)
- + log4j(org.apache.logging.log4j.Level.TRACE, false, methodRE,
"'Trace'-Log with log4j2", null)
- );
- }
-
-
- @Test
- public void test2SubMethod() {
- subMethodWithLogs(); // location info is sub method now
- String methodRE = "subMethodWithLogs";
- assertSysoutMatches(
- log4j(org.apache.logging.log4j.Level.DEBUG, true, methodRE,
"'Fine'-Log with JUL in subMethod", null)
- + jul(java.util.logging.Level.FINE, methodRE, "'Fine'-Log with
JUL in subMethod", null)
- + log4j(org.apache.logging.log4j.Level.INFO, false, methodRE,
"'Info'-Log with log4j2 in subMethod", null)
- );
- }
- private void subMethodWithLogs() {
- julLog.fine("Test-'Fine'-Log with JUL in subMethod");
- log4jLog.info("Test-'Info'-Log with log4j2 in subMethod");
- }
-
-
- @Test
- public void test3JulFlow1() {
- // note: manually given source information get lost in log4j!
- julLog.entering("enteringExampleClassParam",
"enteringExampleMethodParam");
- String methodRE = "JulFlow";
- assertSysoutMatches(
- log4j(org.apache.logging.log4j.Level.TRACE, true, methodRE,
"ENTRY", null)
- + jul(java.util.logging.Level.FINER,
"enteringExampleClassParam enteringExampleMethodParam", "ENTRY", null)
- );
- }
-
- @Test
- public void test3JulFlow2() {
- // note: manually given source information get lost in log4j!
- julLog.entering("enteringExampleClassParam",
"enteringExampleMethodParam_withParams",
- new Object[] {"with some", "parameters", 42} );
- String methodRE = "JulFlow";
- assertSysoutMatches(
- log4j(org.apache.logging.log4j.Level.TRACE, true, methodRE,
- "ENTRY.*with some.*param.*42", null)
- + jul(java.util.logging.Level.FINER,
"enteringExampleClassParam enteringExampleMethodParam_withParams",
- "ENTRY.*with some.*param.*42", null)
- );
- }
-
- @Test
- public void test3JulFlow3() {
- // note: manually given source information get lost in log4j!
- julLog.exiting("exitingExampleClassParam", "exitingExampleMethodParam",
- Arrays.asList("array of Strings", "that are the exit",
"result"));
- String methodRE = "JulFlow";
- assertSysoutMatches(
- log4j(org.apache.logging.log4j.Level.TRACE, true, methodRE,
- "RETURN.*array of Str.*that are.*result", null)
- + jul(java.util.logging.Level.FINER, "exitingExampleClassParam
exitingExampleMethodParam",
- "RETURN.*array of Str.*that are.*result", null)
- );
- }
-
- @Test
- public void test3JulFlow4() {
- // note: manually given source information get lost in log4j!
- julLog.throwing("throwingExampleClassParam",
"throwingExampleMethodParam",
- new IllegalStateException("ONLY TEST for JUL-throwing()"));
- String methodRE = "JulFlow";
- assertSysoutMatches(
- log4j(org.apache.logging.log4j.Level.TRACE, true, methodRE,
- "THROW", "IllegalStateException.*ONLY TEST for
JUL-throwing")
- + jul(java.util.logging.Level.FINER,
"throwingExampleClassParam throwingExampleMethodParam",
- "THROW", "IllegalStateException.*ONLY TEST for
JUL-throwing")
- );
- }
-
-
-
- @Test
- public void test4JulSpecials1() {
- julLog.log(java.util.logging.Level.WARNING, "JUL-Test via log() as
warning with exception",
- new java.util.zip.DataFormatException("ONLY TEST for
JUL.log()"));
- String methodRE = "JulSpecials";
- assertSysoutMatches(
- log4j(org.apache.logging.log4j.Level.WARN, true, methodRE,
- "JUL-Test via log\\(\\) as warning",
"DataFormatException.*ONLY TEST for JUL")
- + jul(java.util.logging.Level.WARNING, methodRE, "JUL-Test via
log\\(\\) as warning",
- "DataFormatException.*ONLY TEST for JUL")
- );
- }
-
- @Test
- public void test4JulSpecials2() {
- // test with MessageFormat
- julLog.log(java.util.logging.Level.INFO, "JUL-Test via log() with
parameters (0={0}, 1={1}, 2={2,number,##000.0})",
- new Object[] {"a", "b", 42} );
- String methodRE = "JulSpecials";
- assertSysoutMatches(
- log4j(org.apache.logging.log4j.Level.INFO, true, methodRE,
- "JUL-Test via log\\(\\) with parameters \\(0=a, 1=b,
2=042.0\\)", null)
- + jul(java.util.logging.Level.INFO, methodRE,
- "JUL-Test via log\\(\\) with parameters \\(0=a, 1=b,
2=042.0\\)", null)
- );
- }
-
- // no test for logrb(ResourceBundle)-case as this is very specific and
seldom used (in
- // my opinion); and it does not add any real thing to test here
-
-
- private void assertLogLevel(String loggerName, java.util.logging.Level
julLevel) {
- java.util.logging.Logger lg =
java.util.logging.LogManager.getLogManager().getLogger(loggerName);
- assertEquals("Logger '" + loggerName + "'", julLevel, (lg == null ?
null : lg.getLevel()));
- }
-
- @Test
- public void test5LevelPropFromConfigFile() {
- // JUL levels are set from config files and the initial propagation
- assertLogLevel("", java.util.logging.Level.FINE);
- assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1",
java.util.logging.Level.FINE);
- assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1.nested1",
java.util.logging.Level.FINER);
-
assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1.nested2.deeplyNested",
java.util.logging.Level.WARNING);
- assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate2",
java.util.logging.Level.ALL);
-
assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate2.nested.deeplyNested",
java.util.logging.Level.INFO);
- // these are set in logging.properties but not in log4j2.xml:
- assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate2.nested", null);
- assertLogLevel("javax.mail", null);
- // these should not exist:
- assertLogLevel("log4j.Log4jBridgeHandlerTest", null);
- assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1.nested", null);
-
assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1.nested1.deeplyNested",
null);
- }
-
-
- @Test
- public void test5LevelPropSetLevel() {
- String name = "log4j.test.new_logger_level_set";
- Configurator.setLevel(name, org.apache.logging.log4j.Level.DEBUG);
- assertLogLevel(name, java.util.logging.Level.FINE);
- test5LevelPropFromConfigFile(); // the rest should be untouched!
-
- name = "log4j.Log4jBridgeHandlerTest.propagate1.nested1";
- Configurator.setLevel(name, org.apache.logging.log4j.Level.WARN);
- assertLogLevel(name, java.util.logging.Level.WARNING);
- // the others around should be untouched
- assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1",
java.util.logging.Level.FINE);
-
assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1.nested2.deeplyNested",
java.util.logging.Level.WARNING);
-
- // note: no need to check for the other set[Root]Level() methods,
because they all call
- // loggerContext.updateLoggers() which calls firePropertyChangeEvent()
- }
-
-
- @Test
- public void test5LevelPropGC() {
- // this test will fail if you comment out "julLoggerRefs.add(julLog);"
in propagateLogLevels()
- test5LevelPropFromConfigFile(); // at start, all should be fine
- java.util.logging.Logger julLogRef = java.util.logging.Logger
- .getLogger("log4j.Log4jBridgeHandlerTest.propagate1.nested1");
- System.gc(); // a single call is sufficient
- System.out.println("sysout: test5LevelPropGC() still has reference to
JUL-logger: "
- + julLogRef.getName() + " / " + julLogRef);
- try {
- test5LevelPropFromConfigFile(); // even after GC the not
referenced loggers should still be there
- } catch (Throwable t) {
- debugPrintJulLoggers("After GC");
- // => JUL root logger, above explicitly referenced logger and its
parent ("...propagate1")
- // and the global referenced julLog
("...jul.Log4jBridgeHandlerTest") are still there, the
- // others are null-references now
- throw t;
- }
- }
-
-
- /** Print all available JUL loggers to stdout. */
- private static void debugPrintJulLoggers(String infoStr) {
- 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);
- }
- }
-
-
-
-
-////////////////
-//////////////// INTERNAL DEVELOPER TESTS follow
-//////////////// (these are NOT neccessary for unit test but source is kept
here for reference and info)
-
-
- static {
- if (DEVTEST) {
- System.out.println("sysout: static init. BEGIN");
-
- // get log4j context impl. (requires log4j-core!)
- // note: "LogManager.getContext();" does not work, it returns
another instance!?!
- LoggerContext context = LoggerContext.getContext(false); //
this matches Configurator.setLevel() impl.
- Configuration cfg = context.getConfiguration();
- // print real loggers (=> is empty when using
LogManager.getContext()!?! only contains already instantiated loggers)
- System.out.println("LogCtx " + context + " '" + context.getName()
+ "', loc = "
- + context.getConfigLocation() + ", cfg = " + cfg + " = "
+ System.identityHashCode(cfg));
- for (org.apache.logging.log4j.Logger lg : context.getLoggers()) {
- System.out.println("- Logger '" + lg.getName() + "', lvl = "
+ lg.getLevel());
- }
- // print logger configurations (=> all loggers with level are
present here)
- System.out.println("Loggers in Cfg:");
- for (Entry<String, LoggerConfig> entry :
cfg.getLoggers().entrySet()) {
- LoggerConfig lcfg = entry.getValue();
- System.out.println("- '" + entry.getKey() + "' = '" +
lcfg.getName() + "' / "
- + lcfg.getLevel() + "; " + lcfg);
- }
-
- // print JUL loggers (=> is completely init. here, even if first
JUL log and BridgeHandler-creation happens later)
- debugPrintJulLoggers("in static-class-init");
- /* java.util.logging.LogManager julMgr =
java.util.logging.LogManager.getLogManager();
- System.out.println("\nJUL-Loggers for " + julMgr);
- for (Enumeration<String> en = julMgr.getLoggerNames();
en.hasMoreElements(); ) {
- String ln = en.nextElement();
- java.util.logging.Logger lg = julMgr.getLogger(ln);
- if (lg.getLevel() == null) {
- System.out.println("- (null-Level Logger '" + ln +
"')");
- } else {
- System.out.println("- Logger '" + ln + "', lvl = " +
lg.getLevel());
- }
- } */
-
- // changing of log4j config. is to be done via
log4j.core.config.Configurator,
- // e.g. setLevel(loggerName, newLevel)
- // Note: the (internal) log4j.core.Logger has a setLevel() but
this should not be used.
- CfgListener listener = new CfgListener();
- cfg.addListener(listener); // => onChange() is never called:
not on start, not on setLevel
- context.addPropertyChangeListener(listener);
-
- System.out.println("sysout: static init. END");
- } // if
- }
-
-
- private static void devTestBeforeClass() {
- log4jLog.info("Dummy-Start-Log in beforeClass()"); // force init.
of log4j (needed?? does not harm)
- @SuppressWarnings("resource")
- LoggerContext context = LoggerContext.getContext(false); // this
matches Configurator.setLevel() impl. (instead of "LogManager.getContext();")
- System.out.println("beforeClass(): LogCtx " + context + " '" +
context.getName() + "', loc = " + context.getConfigLocation()
- + ", cfg = " + context.getConfiguration());
- for (org.apache.logging.log4j.Logger lg : context.getLoggers()) {
- System.out.println("- Logger '" + lg.getName() + "', lvl = " +
lg.getLevel());
- }
-
- // force level change
- System.out.println("sysout: now calling log4j-setLevel()");
- Configurator.setLevel("log4jTest.Dummy_set_in_devTestBeforeClass",
org.apache.logging.log4j.Level.DEBUG);
- }
-
-
- private static class CfgListener implements ConfigurationListener,
PropertyChangeListener {
- public CfgListener() {
- System.out.println("sysout: CfgListener created: " + this);
- }
-
- @Override
- public void onChange(Reconfigurable reconfigurable) { // from
ConfigurationListener
- System.out.println("sysout: CfgListener.CfgLi-onChange(): " +
reconfigurable
- + " = " + System.identityHashCode(reconfigurable));
- }
-
- @Override
- public void propertyChange(PropertyChangeEvent evt) { // from
PropertyChangeListener
- System.out.println("sysout:
CfgListener.PropChLi-propertyChange(): " + evt);
- }
- }
-
-}
+/*
+ * 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.test;
+
+//note: NO import of Logger, Level, LogManager to prevent conflicts JUL/log4j
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Map.Entry;
+
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.ConfigurationListener;
+import org.apache.logging.log4j.core.config.Configurator;
+import org.apache.logging.log4j.core.config.LoggerConfig;
+import org.apache.logging.log4j.core.config.Reconfigurable;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+
+
+/**
+ * Test the Log4jBridgeHandler.
+ * Requires some configurations in the log-config-files, for format/layout
+ * see also jul() and log4j():
+ * - JUL-config ("logging-test.properties", must be set on JVM-start via
"-D..."):
+ * + handlers = org.apache.logging.log4j.jul.Log4jBridgeHandler,
java.util.logging.ConsoleHandler
+ * + org.apache.logging.log4j.jul.Log4jBridgeHandler.appendSuffix = _JUL
+ * + java.util.logging.ConsoleHandler.level = ALL
+ * + java.util.logging.SimpleFormatter.format = JUL: %1$tT.%1$tL %4$s
[%3$s: %2$s] - %5$s%6$s%n
+ * + .level = FINER
+ * - log4j2-config ("log4j2-test.xml"):
+ * + <Root level="TRACE">
+ * + <Appenders> <Console> with target="SYSTEM_ERR", follow="true",
+ * <PatternLayout> "log4j2: %d{HH:mm:ss.SSS} %5level -
[%thread][%logger: %class/%method/%line] - %message%n"
+ *
+ * This test needs to capture syserr because it uses
java.util.logging.ConsoleHandler.
+ * Also, it performs some outputs to console (sysout and syserr); see also
field OUTPUT_CAPTURED.
+ *
+ * The code also contains evaluation/test code for development time. It is not
used for the unit tests
+ * but kept here for reference and info. See field DEVTEST.
+ */
+@FixMethodOrder(org.junit.runners.MethodSorters.NAME_ASCENDING) // is nicer
for manually checking console output
+public class Log4jBridgeHandlerTest {
+ /** Perform developer tests? */
+ private static final boolean DEVTEST = false;
+
+ /** Do output the captured logger-output to stdout? */
+ private static final boolean OUTPUT_CAPTURED = !DEVTEST &&
Boolean.parseBoolean(
+ System.getProperty("log4j.Log4jBridgeHandlerTest.outputCaptured"));
+
+ /** This classes' simple name = relevant part of logger name. */
+ private static final String CSNAME =
Log4jBridgeHandlerTest.class.getSimpleName();
+ // loggers used in many tests
+ private static final java.util.logging.Logger julLog =
java.util.logging.Logger.getLogger(Log4jBridgeHandlerTest.class.getName());
+ private static final org.apache.logging.log4j.Logger log4jLog =
org.apache.logging.log4j.LogManager.getLogger();
+
+ // capture sysout/syserr
+ //@Rule public final SystemErrRule systemOutRule = new
SystemErrRule().enableLog();
+ private static final ByteArrayOutputStream sysoutBytes = new
ByteArrayOutputStream(1024);
+ private static PrintStream prevSysErrStream;
+
+
+ @BeforeClass
+ public static void beforeClass() {
+ // debug output to easily recognize misconfig.:
+ //System.out.println("sys-props:\n" + System.getProperties());
+ System.out.println("sysout: logging-cfg-file: " +
System.getProperty("java.util.logging.config.file"));
+ if (DEVTEST) devTestBeforeClass(); // call before stderr capturing
+
+ // JUL does not like setting stderr inbetween, so set it once and
reset collecting stream
+ // for each method; (thus
com.github.stefanbirkner:system-rules:SystemErrRule cannot be used)
+ System.err.println("vvv--- BEGIN capturing output to stderr ---vvv"
+ + " (do output of captured text to orig. stderr: " +
OUTPUT_CAPTURED + ")");
+ prevSysErrStream = System.err;
+ System.setErr(new PrintStream(sysoutBytes, true));
+ }
+
+ @AfterClass
+ public static void afterClass() {
+ // reset sysout/err to original value
+ System.setErr(prevSysErrStream);
+ System.err.println("^^^--- END capturing output of stderr ---^^^");
+ }
+
+
+ @Before
+ public void beforeTest() {
+ // reset sysout collector
+ sysoutBytes.reset();
+ }
+
+
+
+ /** Assert that captured sysout matches given regexp (any text may follow
afterwards). */
+ private void assertSysoutMatches(String regex) {
+ //String logOutput = systemOutRule.getLogWithNormalizedLineSeparator();
+ String logOutput = sysoutBytes.toString();
+ if (OUTPUT_CAPTURED) prevSysErrStream.print(logOutput);
+ logOutput = logOutput.replace("\r\n", "\n");
+ regex = regex + "(.|\\n)*"; // allow any text with NL afterwards
+ assertTrue("Unmatching output:\n" + logOutput + "\n-- vs: --\n" +
regex + "\n----", logOutput.matches(regex));
+ }
+
+ /** Get regex for a JUL console output. Must match JUL-Console-Formatter!
*/
+ private String jul(java.util.logging.Level lvl, String locationPartRE,
+ String msgPartRE, String exceptionClassAndMsgRE) {
+ return "JUL:.*" + lvl.getLocalizedName() + ".*" + CSNAME
+ + ".*" + locationPartRE + ".*" + msgPartRE + ".*\n" // use
real \n at end here for better error output
+ + (exceptionClassAndMsgRE == null ? ""
+ : ".*" + exceptionClassAndMsgRE + ".*\\n(\tat
.*\\n)*\\n?");
+ }
+
+ /** Get regex for a log4j console output. Must match
log4j2-Console-Layout! */
+ private String log4j(org.apache.logging.log4j.Level lvl, boolean
julBridged,
+ String methodPartRE, String msgPartRE, String
exceptionClassAndMsgRE) {
+ return "log4j2:.*" + lvl.name() + ".*" + CSNAME + (julBridged ?
"\\._JUL" : "")
+ + ".*" + CSNAME + "/\\w*" + methodPartRE + "\\w*/.*"
+ + msgPartRE + ".*\n" // use real \n at end here for
better error output
+ + (exceptionClassAndMsgRE == null ? ""
+ : ".*" + exceptionClassAndMsgRE + ".*\\n(\tat
.*\\n)*\\n?");
+ }
+
+
+
+ @Test
+ public void test1SimpleLoggings1Jul() {
+ julLog.info("Test-'Info'-Log with JUL");
+ julLog.fine("Test-'Fine'-Log with JUL");
+ julLog.finest("Test-'Finest'-Log with JUL"); // should not be
logged because JUL-level is FINER
+ julLog.warning("Test-'Warn'-Log with JUL"); // thus add another log
afterwards to allow checking
+ String methodRE = "SimpleLoggings1Jul";
+ assertSysoutMatches(
+ log4j(org.apache.logging.log4j.Level.INFO, true, methodRE,
"'Info'-Log with JUL", null)
+ + jul(java.util.logging.Level.INFO, methodRE, "'Info'-Log with
JUL", null)
+ + log4j(org.apache.logging.log4j.Level.DEBUG, true, methodRE,
"'Fine'-Log with JUL", null)
+ + jul(java.util.logging.Level.FINE, methodRE, "'Fine'-Log with
JUL", null)
+ // no finest/trace
+ + log4j(org.apache.logging.log4j.Level.WARN, true, methodRE,
"'Warn'-Log with JUL", null)
+ + jul(java.util.logging.Level.WARNING, methodRE, "'Warn'-Log
with JUL", null)
+ );
+ }
+
+ @Test
+ public void test1SimpleLoggings2Log4jDirect() {
+ log4jLog.info("Test-'Info'-Log with log4j2");
+ log4jLog.debug("Test-'Debug'-Log with log4j2");
+ log4jLog.trace("Test-'Trace'-Log with log4j2");
+ String methodRE = "SimpleLoggings2Log4jDirect";
+ assertSysoutMatches(
+ log4j(org.apache.logging.log4j.Level.INFO, false, methodRE,
"'Info'-Log with log4j2", null)
+ + log4j(org.apache.logging.log4j.Level.DEBUG, false, methodRE,
"'Debug'-Log with log4j2", null)
+ + log4j(org.apache.logging.log4j.Level.TRACE, false, methodRE,
"'Trace'-Log with log4j2", null)
+ );
+ }
+
+
+ @Test
+ public void test2SubMethod() {
+ subMethodWithLogs(); // location info is sub method now
+ String methodRE = "subMethodWithLogs";
+ assertSysoutMatches(
+ log4j(org.apache.logging.log4j.Level.DEBUG, true, methodRE,
"'Fine'-Log with JUL in subMethod", null)
+ + jul(java.util.logging.Level.FINE, methodRE, "'Fine'-Log with
JUL in subMethod", null)
+ + log4j(org.apache.logging.log4j.Level.INFO, false, methodRE,
"'Info'-Log with log4j2 in subMethod", null)
+ );
+ }
+ private void subMethodWithLogs() {
+ julLog.fine("Test-'Fine'-Log with JUL in subMethod");
+ log4jLog.info("Test-'Info'-Log with log4j2 in subMethod");
+ }
+
+
+ @Test
+ public void test3JulFlow1() {
+ // note: manually given source information get lost in log4j!
+ julLog.entering("enteringExampleClassParam",
"enteringExampleMethodParam");
+ String methodRE = "JulFlow";
+ assertSysoutMatches(
+ log4j(org.apache.logging.log4j.Level.TRACE, true, methodRE,
"ENTRY", null)
+ + jul(java.util.logging.Level.FINER,
"enteringExampleClassParam enteringExampleMethodParam", "ENTRY", null)
+ );
+ }
+
+ @Test
+ public void test3JulFlow2() {
+ // note: manually given source information get lost in log4j!
+ julLog.entering("enteringExampleClassParam",
"enteringExampleMethodParam_withParams",
+ new Object[] {"with some", "parameters", 42} );
+ String methodRE = "JulFlow";
+ assertSysoutMatches(
+ log4j(org.apache.logging.log4j.Level.TRACE, true, methodRE,
+ "ENTRY.*with some.*param.*42", null)
+ + jul(java.util.logging.Level.FINER,
"enteringExampleClassParam enteringExampleMethodParam_withParams",
+ "ENTRY.*with some.*param.*42", null)
+ );
+ }
+
+ @Test
+ public void test3JulFlow3() {
+ // note: manually given source information get lost in log4j!
+ julLog.exiting("exitingExampleClassParam", "exitingExampleMethodParam",
+ Arrays.asList("array of Strings", "that are the exit",
"result"));
+ String methodRE = "JulFlow";
+ assertSysoutMatches(
+ log4j(org.apache.logging.log4j.Level.TRACE, true, methodRE,
+ "RETURN.*array of Str.*that are.*result", null)
+ + jul(java.util.logging.Level.FINER, "exitingExampleClassParam
exitingExampleMethodParam",
+ "RETURN.*array of Str.*that are.*result", null)
+ );
+ }
+
+ @Test
+ public void test3JulFlow4() {
+ // note: manually given source information get lost in log4j!
+ julLog.throwing("throwingExampleClassParam",
"throwingExampleMethodParam",
+ new IllegalStateException("ONLY TEST for JUL-throwing()"));
+ String methodRE = "JulFlow";
+ assertSysoutMatches(
+ log4j(org.apache.logging.log4j.Level.TRACE, true, methodRE,
+ "THROW", "IllegalStateException.*ONLY TEST for
JUL-throwing")
+ + jul(java.util.logging.Level.FINER,
"throwingExampleClassParam throwingExampleMethodParam",
+ "THROW", "IllegalStateException.*ONLY TEST for
JUL-throwing")
+ );
+ }
+
+
+
+ @Test
+ public void test4JulSpecials1() {
+ julLog.log(java.util.logging.Level.WARNING, "JUL-Test via log() as
warning with exception",
+ new java.util.zip.DataFormatException("ONLY TEST for
JUL.log()"));
+ String methodRE = "JulSpecials";
+ assertSysoutMatches(
+ log4j(org.apache.logging.log4j.Level.WARN, true, methodRE,
+ "JUL-Test via log\\(\\) as warning",
"DataFormatException.*ONLY TEST for JUL")
+ + jul(java.util.logging.Level.WARNING, methodRE, "JUL-Test via
log\\(\\) as warning",
+ "DataFormatException.*ONLY TEST for JUL")
+ );
+ }
+
+ @Test
+ public void test4JulSpecials2() {
+ // test with MessageFormat
+ julLog.log(java.util.logging.Level.INFO, "JUL-Test via log() with
parameters (0={0}, 1={1}, 2={2,number,##000.0})",
+ new Object[] {"a", "b", 42} );
+ String methodRE = "JulSpecials";
+ assertSysoutMatches(
+ log4j(org.apache.logging.log4j.Level.INFO, true, methodRE,
+ "JUL-Test via log\\(\\) with parameters \\(0=a, 1=b,
2=042.0\\)", null)
+ + jul(java.util.logging.Level.INFO, methodRE,
+ "JUL-Test via log\\(\\) with parameters \\(0=a, 1=b,
2=042.0\\)", null)
+ );
+ }
+
+ // no test for logrb(ResourceBundle)-case as this is very specific and
seldom used (in
+ // my opinion); and it does not add any real thing to test here
+
+
+ private void assertLogLevel(String loggerName, java.util.logging.Level
julLevel) {
+ java.util.logging.Logger lg =
java.util.logging.LogManager.getLogManager().getLogger(loggerName);
+ assertEquals("Logger '" + loggerName + "'", julLevel, (lg == null ?
null : lg.getLevel()));
+ }
+
+ @Test
+ public void test5LevelPropFromConfigFile() {
+ // JUL levels are set from config files and the initial propagation
+ assertLogLevel("", java.util.logging.Level.FINE);
+ assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1",
java.util.logging.Level.FINE);
+ assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1.nested1",
java.util.logging.Level.FINER);
+
assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1.nested2.deeplyNested",
java.util.logging.Level.WARNING);
+ assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate2",
java.util.logging.Level.ALL);
+
assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate2.nested.deeplyNested",
java.util.logging.Level.INFO);
+ // these are set in logging.properties but not in log4j2.xml:
+ assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate2.nested", null);
+ assertLogLevel("javax.mail", null);
+ // these should not exist:
+ assertLogLevel("log4j.Log4jBridgeHandlerTest", null);
+ assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1.nested", null);
+
assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1.nested1.deeplyNested",
null);
+ }
+
+
+ @Test
+ public void test5LevelPropSetLevel() {
+ String name = "log4j.test.new_logger_level_set";
+ Configurator.setLevel(name, org.apache.logging.log4j.Level.DEBUG);
+ assertLogLevel(name, java.util.logging.Level.FINE);
+ test5LevelPropFromConfigFile(); // the rest should be untouched!
+
+ name = "log4j.Log4jBridgeHandlerTest.propagate1.nested1";
+ Configurator.setLevel(name, org.apache.logging.log4j.Level.WARN);
+ assertLogLevel(name, java.util.logging.Level.WARNING);
+ // the others around should be untouched
+ assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1",
java.util.logging.Level.FINE);
+
assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1.nested2.deeplyNested",
java.util.logging.Level.WARNING);
+
+ // note: no need to check for the other set[Root]Level() methods,
because they all call
+ // loggerContext.updateLoggers() which calls firePropertyChangeEvent()
+ }
+
+
+ @Test
+ public void test5LevelPropGC() {
+ // this test will fail if you comment out "julLoggerRefs.add(julLog);"
in propagateLogLevels()
+ test5LevelPropFromConfigFile(); // at start, all should be fine
+ java.util.logging.Logger julLogRef = java.util.logging.Logger
+ .getLogger("log4j.Log4jBridgeHandlerTest.propagate1.nested1");
+ System.gc(); // a single call is sufficient
+ System.out.println("sysout: test5LevelPropGC() still has reference to
JUL-logger: "
+ + julLogRef.getName() + " / " + julLogRef);
+ try {
+ test5LevelPropFromConfigFile(); // even after GC the not
referenced loggers should still be there
+ } catch (Throwable t) {
+ debugPrintJulLoggers("After GC");
+ // => JUL root logger, above explicitly referenced logger and its
parent ("...propagate1")
+ // and the global referenced julLog
("...jul.Log4jBridgeHandlerTest") are still there, the
+ // others are null-references now
+ throw t;
+ }
+ }
+
+
+ /** Print all available JUL loggers to stdout. */
+ private static void debugPrintJulLoggers(String infoStr) {
+ 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);
+ }
+ }
+
+
+
+
+////////////////
+//////////////// INTERNAL DEVELOPER TESTS follow
+//////////////// (these are NOT neccessary for unit test but source is kept
here for reference and info)
+
+
+ static {
+ if (DEVTEST) {
+ System.out.println("sysout: static init. BEGIN");
+
+ // get log4j context impl. (requires log4j-core!)
+ // note: "LogManager.getContext();" does not work, it returns
another instance!?!
+ LoggerContext context = LoggerContext.getContext(false); //
this matches Configurator.setLevel() impl.
+ Configuration cfg = context.getConfiguration();
+ // print real loggers (=> is empty when using
LogManager.getContext()!?! only contains already instantiated loggers)
+ System.out.println("LogCtx " + context + " '" + context.getName()
+ "', loc = "
+ + context.getConfigLocation() + ", cfg = " + cfg + " = "
+ System.identityHashCode(cfg));
+ for (org.apache.logging.log4j.Logger lg : context.getLoggers()) {
+ System.out.println("- Logger '" + lg.getName() + "', lvl = "
+ lg.getLevel());
+ }
+ // print logger configurations (=> all loggers with level are
present here)
+ System.out.println("Loggers in Cfg:");
+ for (Entry<String, LoggerConfig> entry :
cfg.getLoggers().entrySet()) {
+ LoggerConfig lcfg = entry.getValue();
+ System.out.println("- '" + entry.getKey() + "' = '" +
lcfg.getName() + "' / "
+ + lcfg.getLevel() + "; " + lcfg);
+ }
+
+ // print JUL loggers (=> is completely init. here, even if first
JUL log and BridgeHandler-creation happens later)
+ debugPrintJulLoggers("in static-class-init");
+ /* java.util.logging.LogManager julMgr =
java.util.logging.LogManager.getLogManager();
+ System.out.println("\nJUL-Loggers for " + julMgr);
+ for (Enumeration<String> en = julMgr.getLoggerNames();
en.hasMoreElements(); ) {
+ String ln = en.nextElement();
+ java.util.logging.Logger lg = julMgr.getLogger(ln);
+ if (lg.getLevel() == null) {
+ System.out.println("- (null-Level Logger '" + ln +
"')");
+ } else {
+ System.out.println("- Logger '" + ln + "', lvl = " +
lg.getLevel());
+ }
+ } */
+
+ // changing of log4j config. is to be done via
log4j.core.config.Configurator,
+ // e.g. setLevel(loggerName, newLevel)
+ // Note: the (internal) log4j.core.Logger has a setLevel() but
this should not be used.
+ CfgListener listener = new CfgListener();
+ cfg.addListener(listener); // => onChange() is never called:
not on start, not on setLevel
+ context.addPropertyChangeListener(listener);
+
+ System.out.println("sysout: static init. END");
+ } // if
+ }
+
+
+ private static void devTestBeforeClass() {
+ log4jLog.info("Dummy-Start-Log in beforeClass()"); // force init.
of log4j (needed?? does not harm)
+ @SuppressWarnings("resource")
+ LoggerContext context = LoggerContext.getContext(false); // this
matches Configurator.setLevel() impl. (instead of "LogManager.getContext();")
+ System.out.println("beforeClass(): LogCtx " + context + " '" +
context.getName() + "', loc = " + context.getConfigLocation()
+ + ", cfg = " + context.getConfiguration());
+ for (org.apache.logging.log4j.Logger lg : context.getLoggers()) {
+ System.out.println("- Logger '" + lg.getName() + "', lvl = " +
lg.getLevel());
+ }
+
+ // force level change
+ System.out.println("sysout: now calling log4j-setLevel()");
+ Configurator.setLevel("log4jTest.Dummy_set_in_devTestBeforeClass",
org.apache.logging.log4j.Level.DEBUG);
+ }
+
+
+ private static class CfgListener implements ConfigurationListener,
PropertyChangeListener {
+ public CfgListener() {
+ System.out.println("sysout: CfgListener created: " + this);
+ }
+
+ @Override
+ public void onChange(Reconfigurable reconfigurable) { // from
ConfigurationListener
+ System.out.println("sysout: CfgListener.CfgLi-onChange(): " +
reconfigurable
+ + " = " + System.identityHashCode(reconfigurable));
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) { // from
PropertyChangeListener
+ System.out.println("sysout:
CfgListener.PropChLi-propertyChange(): " + evt);
+ }
+ }
+
+}
diff --git
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/Log4jLevelTranslatorTest.java
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/Log4jLevelTranslatorTest.java
similarity index 96%
rename from
log4j-jul/src/test/java/org/apache/logging/log4j/jul/Log4jLevelTranslatorTest.java
rename to
log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/Log4jLevelTranslatorTest.java
index dd65105642..b0979b48fe 100644
---
a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/Log4jLevelTranslatorTest.java
+++
b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/Log4jLevelTranslatorTest.java
@@ -15,7 +15,7 @@
* limitations under the license.
*/
-package org.apache.logging.log4j.jul;
+package org.apache.logging.log4j.jul.test;
import static org.junit.Assert.assertEquals;
@@ -23,6 +23,7 @@ import java.util.Arrays;
import java.util.Collection;
import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.jul.LevelTranslator;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
diff --git a/log4j-jul/src/test/resources/log4j2-calling-class.xml
b/log4j-jul/src/test/resources/log4j2-calling-class.xml
new file mode 100644
index 0000000000..4432c82806
--- /dev/null
+++ b/log4j-jul/src/test/resources/log4j2-calling-class.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+
+-->
+<Configuration name="CallerInformationTest" status="ERROR">
+ <Appenders>
+ <List name="Class">
+ <PatternLayout pattern="%class"/>
+ </List>
+ <List name="Method">
+ <PatternLayout pattern="%method"/>
+ </List>
+ </Appenders>
+ <Loggers>
+ <Logger name="ClassLogger" level="info">
+ <AppenderRef ref="Class"/>
+ </Logger>
+ <Logger name="MethodLogger" level="info">
+ <AppenderRef ref="Method"/>
+ </Logger>
+ <Root level="off"/>
+ </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/log4j-jul/src/test/resources/log4j2-julBridge-test.xml
b/log4j-jul/src/test/resources/log4j2-julBridge-test.xml
index edc0cab0b6..ea769f8617 100644
--- a/log4j-jul/src/test/resources/log4j2-julBridge-test.xml
+++ b/log4j-jul/src/test/resources/log4j2-julBridge-test.xml
@@ -13,7 +13,7 @@
</Root>
<!-- needs to be set to a lower level: -->
- <Logger name="org.apache.logging.log4j.jul.Log4jBridgeHandlerTest"
level="TRACE" />
+ <Logger
name="org.apache.logging.log4j.jul.test.Log4jBridgeHandlerTest" level="TRACE" />
<!-- some test configs: -->
<Logger name="log4j.Log4jBridgeHandlerTest.propagate1" level="DEBUG" />
<Logger name="log4j.Log4jBridgeHandlerTest.propagate1.nested1"
level="TRACE" />
diff --git a/pom.xml b/pom.xml
index 62d3d54e9e..fef715f40a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -234,7 +234,7 @@
<mongodb3.version>3.12.4</mongodb3.version>
<mongodb4.version>4.0.3</mongodb4.version>
<groovy.version>4.0.2</groovy.version>
- <compiler.plugin.version>3.8.1</compiler.plugin.version>
+ <compiler.plugin.version>3.10.1</compiler.plugin.version>
<pmd.plugin.version>3.13.0</pmd.plugin.version>
<spotbugs.plugin.version>4.0.4</spotbugs.plugin.version>
<spotbugs.version>4.1.2</spotbugs.version>