You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by pk...@apache.org on 2024/09/09 18:25:30 UTC
(logging-log4j2) 01/02: Update `log4j-jul` to Java 17
This is an automated email from the ASF dual-hosted git repository.
pkarwasz pushed a commit to branch feature/main/split-jul
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit cde1fbc4c29cd3a04e1dba28f55c8e1d8161ea35
Author: Piotr P. Karwasz <pi...@karwasz.org>
AuthorDate: Mon Sep 9 11:22:05 2024 +0200
Update `log4j-jul` to Java 17
We update `log4j-jul` to:
- implement methods introduced in Java 9,
- remove methods deprecated in Java 9.
---
log4j-jul/pom.xml | 37 +--
.../logging/log4j/jul/AbstractLoggerAdapter.java | 17 +-
.../org/apache/logging/log4j/jul/ApiLogger.java | 315 ++++++++++++++++-----
.../org/apache/logging/log4j/jul/LogManager.java | 22 +-
.../apache/logging/log4j/jul/WrappedLogger.java | 8 +
.../logging/log4j/jul/test/ApiLoggerTest.java | 5 -
.../log4j/jul/test/CallerInformationTest.java | 41 ++-
.../logging/log4j/jul/test/ResourceBundleTest.java | 91 ++++++
...calling-class.xml => CallerInformationTest.xml} | 18 +-
.../test/resources/ResourceBundleTest.properties | 21 ++
...j2-calling-class.xml => ResourceBundleTest.xml} | 23 +-
11 files changed, 456 insertions(+), 142 deletions(-)
diff --git a/log4j-jul/pom.xml b/log4j-jul/pom.xml
index 00f55786df..888dd58a5c 100644
--- a/log4j-jul/pom.xml
+++ b/log4j-jul/pom.xml
@@ -28,57 +28,48 @@
<name>Apache Log4j JUL Adapter</name>
<description>The Apache Log4j implementation of java.util.logging</description>
- <properties>
- <log4jParentDir>${basedir}/..</log4jParentDir>
-
- <!--
- ~ OSGi and JPMS options
- -->
- <bnd-extra-package-options>
- <!-- Log4j Core is optional -->
- org.apache.logging.log4j.core.*;resolution:=optional
- </bnd-extra-package-options>
-
- <!-- PTS requires using the JUnit Platform, which interferes with JUL initialization -->
- <predictive.test.selection.enabled>false</predictive.test.selection.enabled>
- </properties>
-
<dependencies>
+
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</dependency>
+
<dependency>
<groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-core</artifactId>
- <optional>true</optional>
+ <artifactId>log4j-kit</artifactId>
</dependency>
+
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
- <!-- Required for AsyncLogger testing -->
- <dependency>
- <groupId>com.lmax</groupId>
- <artifactId>disruptor</artifactId>
- <scope>test</scope>
- </dependency>
+
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<scope>test</scope>
</dependency>
+
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
+
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-async-logger</artifactId>
<scope>test</scope>
</dependency>
+
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core-test</artifactId>
diff --git a/log4j-jul/src/main/java/org/apache/logging/log4j/jul/AbstractLoggerAdapter.java b/log4j-jul/src/main/java/org/apache/logging/log4j/jul/AbstractLoggerAdapter.java
index 7c33636a36..5b4d7f5c51 100644
--- a/log4j-jul/src/main/java/org/apache/logging/log4j/jul/AbstractLoggerAdapter.java
+++ b/log4j-jul/src/main/java/org/apache/logging/log4j/jul/AbstractLoggerAdapter.java
@@ -22,9 +22,22 @@ import org.apache.logging.log4j.spi.LoggerContext;
import org.apache.logging.log4j.util.StackLocatorUtil;
/**
- * Abstract Logger registry. Due to the optionality of using log4j-core, there are two registries available at runtime
- * to create: {@link ApiLoggerAdapter} and {@link CoreLoggerAdapter}.
+ * Abstract Logger registry.
+ * <p>
+ * JUL contains methods, such as {@link Logger#setLevel}, which modify the configuration of the logging backend.
+ * To fully implement all {@code Logger} methods, we need to provide a different {@code Logger} implementation
+ * for each Log4j API implementation.
+ * </p>
+ * <p>
+ * Older Log4j versions provided an alternative {@code CoreLoggerAdapter} implementation that supported
+ * the modification of Log4j Core configuration using JUL.
+ * </p>
+ * Since version 2.24.0, however, this implementation was deprecated for removal.
+ * If you wish to enable this feature again, you need to implement this class and provide its FQCN
+ * as {@code log4j.jul.loggerAdapter} configuration property.
+ * </p>
*
+ * @see <a href="https://github.com/apache/logging-log4j2/issues/2353">Issue #2353</a>
* @since 2.1
*/
public abstract class AbstractLoggerAdapter extends org.apache.logging.log4j.spi.AbstractLoggerAdapter<Logger> {
diff --git a/log4j-jul/src/main/java/org/apache/logging/log4j/jul/ApiLogger.java b/log4j-jul/src/main/java/org/apache/logging/log4j/jul/ApiLogger.java
index eee946fc8c..fc4d4d38a3 100644
--- a/log4j-jul/src/main/java/org/apache/logging/log4j/jul/ApiLogger.java
+++ b/log4j-jul/src/main/java/org/apache/logging/log4j/jul/ApiLogger.java
@@ -16,12 +16,15 @@
*/
package org.apache.logging.log4j.jul;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
+import static org.apache.logging.log4j.jul.LevelTranslator.toLevel;
+
+import java.util.ResourceBundle;
+import java.util.function.Supplier;
import java.util.logging.Filter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
+import org.apache.logging.log4j.message.LocalizedMessage;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.MessageFactory;
import org.apache.logging.log4j.spi.ExtendedLogger;
@@ -49,11 +52,7 @@ public class ApiLogger extends Logger {
ApiLogger(final ExtendedLogger logger) {
super(logger.getName(), null);
final Level javaLevel = LevelTranslator.toJavaLevel(logger.getLevel());
- // "java.util.logging.LoggingPermission" "control"
- AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
- ApiLogger.super.setLevel(javaLevel);
- return null;
- });
+ super.setLevel(javaLevel);
this.logger = new WrappedLogger(logger);
}
@@ -62,7 +61,7 @@ public class ApiLogger extends Logger {
if (isFiltered(record)) {
return;
}
- final org.apache.logging.log4j.Level level = LevelTranslator.toLevel(record.getLevel());
+ final org.apache.logging.log4j.Level level = toLevel(record.getLevel());
final Object[] parameters = record.getParameters();
final MessageFactory messageFactory = logger.getMessageFactory();
final Message message = parameters == null
@@ -80,7 +79,7 @@ public class ApiLogger extends Logger {
@Override
public boolean isLoggable(final Level level) {
- return logger.isEnabled(LevelTranslator.toLevel(level));
+ return logger.isEnabled(toLevel(level));
}
@Override
@@ -116,45 +115,111 @@ public class ApiLogger extends Logger {
throw new UnsupportedOperationException("Cannot set parent logger");
}
+ private org.apache.logging.log4j.util.Supplier<String> toLog4jSupplier(Supplier<String> msgSupplier) {
+ return msgSupplier::get;
+ }
+
+ private org.apache.logging.log4j.util.Supplier<Message> toMessageSupplier(Supplier<String> msgSupplier) {
+ return () -> logger.getMessageFactory().newMessage(msgSupplier.get());
+ }
+
+ private org.apache.logging.log4j.util.Supplier<LocalizedMessage> toLocalizedMessageSupplier(
+ ResourceBundle bundle, String msg) {
+ return () -> new LocalizedMessage(bundle, msg);
+ }
+
+ private org.apache.logging.log4j.util.Supplier<LocalizedMessage> toLocalizedMessageSupplier(
+ ResourceBundle bundle, String msg, Object[] params) {
+ return () -> new LocalizedMessage(bundle, msg, params);
+ }
+
+ private StackTraceElement toLocation(String sourceClass, String sourceMethod) {
+ return new StackTraceElement(sourceClass, sourceMethod, null, 0);
+ }
+
@Override
public void log(final Level level, final String msg) {
- if (getFilter() == null) {
- logger.log(LevelTranslator.toLevel(level), msg);
- } else {
+ if (hasFilter()) {
super.log(level, msg);
+ } else {
+ logger.log(toLevel(level), msg);
}
}
+ /**
+ * @since 3.0.0
+ */
@Override
- public void log(final Level level, final String msg, final Object param1) {
- if (getFilter() == null) {
- logger.log(LevelTranslator.toLevel(level), msg, param1);
+ public void log(Level level, Supplier<String> msgSupplier) {
+ if (hasFilter()) {
+ super.log(level, msgSupplier);
} else {
+ logger.log(toLevel(level), toLog4jSupplier(msgSupplier));
+ }
+ }
+
+ @Override
+ public void log(final Level level, final String msg, final Object param1) {
+ if (hasFilter()) {
super.log(level, msg, param1);
+ } else {
+ logger.log(toLevel(level), msg, param1);
}
}
@Override
public void log(final Level level, final String msg, final Object[] params) {
- if (getFilter() == null) {
- logger.log(LevelTranslator.toLevel(level), msg, params);
- } else {
+ if (hasFilter()) {
super.log(level, msg, params);
+ } else {
+ logger.log(toLevel(level), msg, params);
}
}
@Override
public void log(final Level level, final String msg, final Throwable thrown) {
- if (getFilter() == null) {
- logger.log(LevelTranslator.toLevel(level), msg, thrown);
- } else {
+ if (hasFilter()) {
super.log(level, msg, thrown);
+ } else {
+ logger.log(toLevel(level), msg, thrown);
+ }
+ }
+
+ /**
+ * @since 3.0.0
+ */
+ @Override
+ public void log(Level level, Throwable thrown, Supplier<String> msgSupplier) {
+ if (hasFilter()) {
+ super.log(level, thrown, msgSupplier);
+ } else {
+ logger.log(toLevel(level), toLog4jSupplier(msgSupplier), thrown);
}
}
@Override
public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg) {
- log(level, msg);
+ if (hasFilter()) {
+ super.logp(level, sourceClass, sourceMethod, msg);
+ } else {
+ logger.atLevel(toLevel(level))
+ .withLocation(toLocation(sourceClass, sourceMethod))
+ .log(msg);
+ }
+ }
+
+ /**
+ * @since 3.0.0
+ */
+ @Override
+ public void logp(Level level, String sourceClass, String sourceMethod, Supplier<String> msgSupplier) {
+ if (hasFilter()) {
+ super.logp(level, sourceClass, sourceMethod, msgSupplier);
+ } else {
+ logger.atLevel(toLevel(level))
+ .withLocation(toLocation(sourceClass, sourceMethod))
+ .log(toMessageSupplier(msgSupplier));
+ }
}
@Override
@@ -164,7 +229,13 @@ public class ApiLogger extends Logger {
final String sourceMethod,
final String msg,
final Object param1) {
- log(level, msg, param1);
+ if (hasFilter()) {
+ super.logp(level, sourceClass, sourceMethod, msg, param1);
+ } else {
+ logger.atLevel(toLevel(level))
+ .withLocation(toLocation(sourceClass, sourceMethod))
+ .log(msg, param1);
+ }
}
@Override
@@ -174,7 +245,13 @@ public class ApiLogger extends Logger {
final String sourceMethod,
final String msg,
final Object[] params) {
- log(level, msg, params);
+ if (hasFilter()) {
+ super.logp(level, sourceClass, sourceMethod, msg, params);
+ } else {
+ logger.atLevel(toLevel(level))
+ .withLocation(toLocation(sourceClass, sourceMethod))
+ .log(msg, params);
+ }
}
@Override
@@ -184,50 +261,82 @@ public class ApiLogger extends Logger {
final String sourceMethod,
final String msg,
final Throwable thrown) {
- log(level, msg, thrown);
+ if (hasFilter()) {
+ super.logp(level, sourceClass, sourceMethod, msg, thrown);
+ } else {
+ logger.atLevel(toLevel(level))
+ .withLocation(toLocation(sourceClass, sourceMethod))
+ .withThrowable(thrown)
+ .log(msg);
+ }
}
+ /**
+ * @since 3.0.0
+ */
@Override
- public void logrb(
- final Level level,
- final String sourceClass,
- final String sourceMethod,
- final String bundleName,
- final String msg) {
- log(level, msg);
+ public void logp(
+ Level level, String sourceClass, String sourceMethod, Throwable thrown, Supplier<String> msgSupplier) {
+ if (hasFilter()) {
+ super.logp(level, sourceClass, sourceMethod, thrown, msgSupplier);
+ } else {
+ logger.atLevel(toLevel(level))
+ .withLocation(toLocation(sourceClass, sourceMethod))
+ .withThrowable(thrown)
+ .log(toMessageSupplier(msgSupplier));
+ }
}
+ /**
+ * @since 3.0.0
+ */
@Override
public void logrb(
- final Level level,
- final String sourceClass,
- final String sourceMethod,
- final String bundleName,
- final String msg,
- final Object param1) {
- log(level, msg, param1);
+ Level level, String sourceClass, String sourceMethod, ResourceBundle bundle, String msg, Object... params) {
+ if (hasFilter()) {
+ super.logrb(level, sourceClass, sourceMethod, bundle, msg, params);
+ } else {
+ logger.atLevel(toLevel(level))
+ .withLocation(toLocation(sourceClass, sourceMethod))
+ .log(toLocalizedMessageSupplier(bundle, msg, params));
+ }
}
@Override
public void logrb(
- final Level level,
- final String sourceClass,
- final String sourceMethod,
- final String bundleName,
- final String msg,
- final Object[] params) {
- log(level, msg, params);
+ Level level, String sourceClass, String sourceMethod, ResourceBundle bundle, String msg, Throwable thrown) {
+ if (hasFilter()) {
+ super.logrb(level, sourceClass, sourceMethod, bundle, msg, thrown);
+ } else {
+ logger.atLevel(toLevel(level))
+ .withLocation(toLocation(sourceClass, sourceMethod))
+ .withThrowable(thrown)
+ .log(toLocalizedMessageSupplier(bundle, msg));
+ }
}
+ /**
+ * @since 3.0.0
+ */
@Override
- public void logrb(
- final Level level,
- final String sourceClass,
- final String sourceMethod,
- final String bundleName,
- final String msg,
- final Throwable thrown) {
- log(level, msg, thrown);
+ public void logrb(Level level, ResourceBundle bundle, String msg, Object... params) {
+ if (hasFilter()) {
+ super.logrb(level, bundle, msg, params);
+ } else {
+ logger.log(toLevel(level), toLocalizedMessageSupplier(bundle, msg, params));
+ }
+ }
+
+ /**
+ * @since 3.0.0
+ */
+ @Override
+ public void logrb(Level level, ResourceBundle bundle, String msg, Throwable thrown) {
+ if (hasFilter()) {
+ super.logrb(level, bundle, msg, thrown);
+ } else {
+ logger.atLevel(toLevel(level)).withThrowable(thrown).log(toLocalizedMessageSupplier(bundle, msg));
+ }
}
@Override
@@ -262,64 +371,134 @@ public class ApiLogger extends Logger {
@Override
public void severe(final String msg) {
- if (getFilter() == null) {
+ if (hasFilter()) {
+ super.severe(msg);
+ } else {
logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.ERROR, null, msg);
+ }
+ }
+
+ /**
+ * @since 3.0.0
+ */
+ @Override
+ public void severe(Supplier<String> msgSupplier) {
+ if (hasFilter()) {
+ super.severe(msgSupplier);
} else {
- super.severe(msg);
+ logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.ERROR, null, toMessageSupplier(msgSupplier), null);
}
}
@Override
public void warning(final String msg) {
- if (getFilter() == null) {
+ if (hasFilter()) {
+ super.warning(msg);
+ } else {
logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.WARN, null, msg);
+ }
+ }
+
+ @Override
+ public void warning(Supplier<String> msgSupplier) {
+ if (hasFilter()) {
+ super.warning(msgSupplier);
} else {
- super.warning(msg);
+ logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.WARN, null, toMessageSupplier(msgSupplier), null);
}
}
@Override
public void info(final String msg) {
- if (getFilter() == null) {
+ if (hasFilter()) {
+ super.info(msg);
+ } else {
logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.INFO, null, msg);
+ }
+ }
+
+ @Override
+ public void info(Supplier<String> msgSupplier) {
+ if (hasFilter()) {
+ super.info(msgSupplier);
} else {
- super.info(msg);
+ logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.INFO, null, toMessageSupplier(msgSupplier), null);
}
}
@Override
public void config(final String msg) {
- if (getFilter() == null) {
+ if (hasFilter()) {
+ super.config(msg);
+ } else {
logger.logIfEnabled(FQCN, LevelTranslator.CONFIG, null, msg);
+ }
+ }
+
+ @Override
+ public void config(Supplier<String> msgSupplier) {
+ if (hasFilter()) {
+ super.config(msgSupplier);
} else {
- super.config(msg);
+ logger.logIfEnabled(FQCN, LevelTranslator.CONFIG, null, toMessageSupplier(msgSupplier), null);
}
}
@Override
public void fine(final String msg) {
- if (getFilter() == null) {
+ if (hasFilter()) {
+ super.fine(msg);
+ } else {
logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.DEBUG, null, msg);
+ }
+ }
+
+ @Override
+ public void fine(Supplier<String> msgSupplier) {
+ if (hasFilter()) {
+ super.fine(msgSupplier);
} else {
- super.fine(msg);
+ logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.DEBUG, null, toMessageSupplier(msgSupplier), null);
}
}
@Override
public void finer(final String msg) {
- if (getFilter() == null) {
+ if (hasFilter()) {
+ super.finer(msg);
+ } else {
logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.TRACE, null, msg);
+ }
+ }
+
+ @Override
+ public void finer(Supplier<String> msgSupplier) {
+ if (hasFilter()) {
+ super.finer(msgSupplier);
} else {
- super.finer(msg);
+ logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.TRACE, null, toMessageSupplier(msgSupplier), null);
}
}
@Override
public void finest(final String msg) {
- if (getFilter() == null) {
+ if (hasFilter()) {
+ super.finest(msg);
+ } else {
logger.logIfEnabled(FQCN, LevelTranslator.FINEST, null, msg);
+ }
+ }
+
+ @Override
+ public void finest(Supplier<String> msgSupplier) {
+ if (hasFilter()) {
+ super.finest(msgSupplier);
} else {
- super.finest(msg);
+ logger.logIfEnabled(FQCN, LevelTranslator.FINEST, null, toMessageSupplier(msgSupplier), null);
}
}
+
+ private boolean hasFilter() {
+ return getFilter() != null;
+ }
}
diff --git a/log4j-jul/src/main/java/org/apache/logging/log4j/jul/LogManager.java b/log4j-jul/src/main/java/org/apache/logging/log4j/jul/LogManager.java
index b92d87bdf8..2bcadf4df1 100644
--- a/log4j-jul/src/main/java/org/apache/logging/log4j/jul/LogManager.java
+++ b/log4j-jul/src/main/java/org/apache/logging/log4j/jul/LogManager.java
@@ -21,7 +21,6 @@ import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;
-import org.apache.logging.log4j.LoggingException;
import org.apache.logging.log4j.kit.env.PropertyEnvironment;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.LoaderUtil;
@@ -41,9 +40,6 @@ import org.apache.logging.log4j.util.LoaderUtil;
public class LogManager extends java.util.logging.LogManager {
private static final org.apache.logging.log4j.Logger LOGGER = StatusLogger.getLogger();
- private static final String CORE_LOGGER_CLASS_NAME = "org.apache.logging.log4j.core.Logger";
- private static final String CORE_LOGGER_ADAPTER_CLASS_NAME = "org.apache.logging.log4j.jul.CoreLoggerAdapter";
- private static final String API_LOGGER_ADAPTER_CLASS_NAME = "org.apache.logging.log4j.jul.ApiLoggerAdapter";
private final AbstractLoggerAdapter loggerAdapter;
// Contains the set of logger names that are actively being requested using getLogger.
private final ThreadLocal<Set<String>> recursive = ThreadLocal.withInitial(HashSet::new);
@@ -62,21 +58,9 @@ public class LogManager extends java.util.logging.LogManager {
}
}
if (adapter == null) {
- // default adapter
- String adapterClassName;
- try {
- // find out if log4j-core is available
- LoaderUtil.loadClass(CORE_LOGGER_CLASS_NAME);
- adapterClassName = CORE_LOGGER_ADAPTER_CLASS_NAME;
- } catch (final ClassNotFoundException ignored) {
- adapterClassName = API_LOGGER_ADAPTER_CLASS_NAME;
- }
- LOGGER.debug("Attempting to use {}", adapterClassName);
- try {
- adapter = LoaderUtil.newCheckedInstanceOf(adapterClassName, AbstractLoggerAdapter.class);
- } catch (final Exception e) {
- throw LOGGER.throwing(new LoggingException(e));
- }
+ // Use API by default
+ // See https://github.com/apache/logging-log4j2/issues/2353
+ adapter = new ApiLoggerAdapter();
}
loggerAdapter = adapter;
LOGGER.info("Registered Log4j as the java.util.logging.LogManager.");
diff --git a/log4j-jul/src/main/java/org/apache/logging/log4j/jul/WrappedLogger.java b/log4j-jul/src/main/java/org/apache/logging/log4j/jul/WrappedLogger.java
index 8c5d035628..4ef6009985 100644
--- a/log4j-jul/src/main/java/org/apache/logging/log4j/jul/WrappedLogger.java
+++ b/log4j-jul/src/main/java/org/apache/logging/log4j/jul/WrappedLogger.java
@@ -17,7 +17,9 @@
package org.apache.logging.log4j.jul;
import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.message.EntryMessage;
+import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.spi.ExtendedLogger;
import org.apache.logging.log4j.spi.ExtendedLoggerWrapper;
@@ -64,4 +66,10 @@ class WrappedLogger extends ExtendedLoggerWrapper {
public <T extends Throwable> T throwing(final T t) {
return throwing(FQCN, LevelTranslator.toLevel(java.util.logging.Level.FINER), t);
}
+
+ @Override
+ protected void log(
+ Level level, Marker marker, String fqcn, StackTraceElement location, Message message, Throwable throwable) {
+ logger.logMessage(level, marker, fqcn, location, message, throwable);
+ }
}
diff --git a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/ApiLoggerTest.java b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/ApiLoggerTest.java
index ce58daf202..49fb19d2b5 100644
--- a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/ApiLoggerTest.java
+++ b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/ApiLoggerTest.java
@@ -16,16 +16,13 @@
*/
package org.apache.logging.log4j.jul.test;
-import static org.apache.logging.log4j.jul.test.JulTestProperties.JUL_LOGGER_ADAPTER;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import java.util.logging.Logger;
-import org.apache.logging.log4j.core.test.TestConstants;
import org.apache.logging.log4j.core.test.appender.ListAppender;
-import org.apache.logging.log4j.jul.ApiLoggerAdapter;
import org.apache.logging.log4j.jul.LogManager;
import org.junit.After;
import org.junit.AfterClass;
@@ -40,13 +37,11 @@ public class ApiLoggerTest extends AbstractLoggerTest {
@BeforeClass
public static void setUpClass() {
System.setProperty("java.util.logging.manager", LogManager.class.getName());
- oldAdapter = TestConstants.setSystemProperty(JUL_LOGGER_ADAPTER, ApiLoggerAdapter.class.getName());
}
@AfterClass
public static void tearDownClass() {
System.clearProperty("java.util.logging.manager");
- TestConstants.setSystemProperty(JUL_LOGGER_ADAPTER, oldAdapter);
}
@Before
diff --git a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/CallerInformationTest.java b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/CallerInformationTest.java
index ff644a40d3..ce8c981f06 100644
--- a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/CallerInformationTest.java
+++ b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/CallerInformationTest.java
@@ -19,6 +19,7 @@ package org.apache.logging.log4j.jul.test;
import static org.junit.Assert.assertEquals;
import java.util.List;
+import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.logging.log4j.core.test.appender.ListAppender;
import org.apache.logging.log4j.core.test.junit.LoggerContextRule;
@@ -30,11 +31,13 @@ import org.junit.Test;
public class CallerInformationTest {
- // config from log4j-core test-jar
- private static final String CONFIG = "log4j2-calling-class.xml";
+ private static final String PARAM_1 = "PARAM_1";
+ private static final String[] PARAMS = {PARAM_1, "PARAM_2"};
+ private static final String SOURCE_CLASS = "SourceClass";
+ private static final String SOURCE_METHOD = "sourceMethod";
@Rule
- public final LoggerContextRule ctx = new LoggerContextRule(CONFIG);
+ public final LoggerContextRule ctx = new LoggerContextRule("CallerInformationTest.xml");
@BeforeClass
public static void setUpClass() {
@@ -53,11 +56,25 @@ public class CallerInformationTest {
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();
+ 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 passing the location information directly
+ app.clear();
+ logger.logp(Level.INFO, SOURCE_CLASS, SOURCE_METHOD, "Hello!");
+ logger.logp(Level.INFO, SOURCE_CLASS, SOURCE_METHOD, "Hello {1}!", PARAM_1);
+ logger.logp(Level.INFO, SOURCE_CLASS, SOURCE_METHOD, "Hello {1} and {2}!", PARAMS);
+ logger.logp(Level.INFO, SOURCE_CLASS, SOURCE_METHOD, "Hello!", new RuntimeException());
+ logger.logp(Level.INFO, SOURCE_CLASS, SOURCE_METHOD, () -> "Hello" + PARAM_1 + "!");
+ logger.logp(Level.INFO, SOURCE_CLASS, SOURCE_METHOD, new RuntimeException(), () -> "Hello " + PARAM_1 + "!");
+ messages = app.getMessages();
+ assertEquals("Incorrect number of messages.", 6, messages.size());
+ for (final String message : messages) {
+ assertEquals("Incorrect caller class name.", SOURCE_CLASS, message);
+ }
}
@Test
@@ -69,10 +86,24 @@ public class CallerInformationTest {
logger.severe("ZOMBIES!!!");
logger.warning("brains~~~");
logger.info("Itchy. Tasty.");
- final List<String> messages = app.getMessages();
+ 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);
}
+
+ // Test passing the location information directly
+ app.clear();
+ logger.logp(Level.INFO, SOURCE_CLASS, SOURCE_METHOD, "Hello!");
+ logger.logp(Level.INFO, SOURCE_CLASS, SOURCE_METHOD, "Hello {1}!", PARAM_1);
+ logger.logp(Level.INFO, SOURCE_CLASS, SOURCE_METHOD, "Hello {1} and {2}!", PARAMS);
+ logger.logp(Level.INFO, SOURCE_CLASS, SOURCE_METHOD, "Hello!", new RuntimeException());
+ logger.logp(Level.INFO, SOURCE_CLASS, SOURCE_METHOD, () -> "Hello " + PARAM_1 + "!");
+ logger.logp(Level.INFO, SOURCE_CLASS, SOURCE_METHOD, new RuntimeException(), () -> "Hello " + PARAM_1 + "!");
+ messages = app.getMessages();
+ assertEquals("Incorrect number of messages.", 6, messages.size());
+ for (final String message : messages) {
+ assertEquals("Incorrect caller method name.", SOURCE_METHOD, message);
+ }
}
}
diff --git a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/ResourceBundleTest.java b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/ResourceBundleTest.java
new file mode 100644
index 0000000000..7431759751
--- /dev/null
+++ b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/ResourceBundleTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import java.util.ResourceBundle;
+import java.util.logging.Level;
+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.core.test.junit.LoggerContextRule;
+import org.apache.logging.log4j.jul.LogManager;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Test methods that accept a resource bundle
+ */
+public class ResourceBundleTest {
+
+ private static final ResourceBundle BUNDLE = ResourceBundle.getBundle("ResourceBundleTest");
+ private static final String SOURCE_CLASS = "SourceClass";
+ private static final String SOURCE_METHOD = "sourceMethod";
+
+ private static final String[] EXPECTED_MESSAGES = {"Hello!", "Hello Log4j and JUL!"};
+ private static final String[] EXPECTED_CLASS_NAMES = {ResourceBundleTest.class.getName(), SOURCE_CLASS};
+ private static final String[] EXPECTED_METHOD_NAMES = {"testCorrectMessageAndLocation", SOURCE_METHOD};
+
+ @Rule
+ public final LoggerContextRule ctx = new LoggerContextRule("ResourceBundleTest.xml");
+
+ @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 testCorrectMessageAndLocation() {
+ ListAppender appender = ctx.getListAppender("LIST").clear();
+ Logger logger = Logger.getLogger(ResourceBundleTest.class.getName());
+
+ Throwable thrown = new RuntimeException();
+ logger.logrb(Level.INFO, BUNDLE, "msg_1", thrown);
+ logger.logrb(Level.INFO, BUNDLE, "msg_2", "Log4j", "JUL");
+ logger.logrb(Level.INFO, SOURCE_CLASS, SOURCE_METHOD, BUNDLE, "msg_1", thrown);
+ logger.logrb(Level.INFO, SOURCE_CLASS, SOURCE_METHOD, BUNDLE, "msg_2", "Log4j", "JUL");
+
+ LogEvent[] logEvents = appender.getEvents().toArray(LogEvent[]::new);
+ for (int idx = 0; idx < logEvents.length; ++idx) {
+ assertEquals(
+ String.format("Message of event %d", idx),
+ EXPECTED_MESSAGES[idx % 2],
+ logEvents[idx].getMessage().getFormattedMessage());
+ assertEquals(
+ String.format("Source class of event %d", idx),
+ EXPECTED_CLASS_NAMES[idx / 2],
+ logEvents[idx].getSource().getClassName());
+ assertEquals(
+ String.format("Source method of event %d", idx),
+ EXPECTED_METHOD_NAMES[idx / 2],
+ logEvents[idx].getSource().getMethodName());
+ assertSame(
+ String.format("Exception of event %d", idx),
+ idx % 2 == 0 ? thrown : null,
+ logEvents[idx].getThrown());
+ }
+ }
+}
diff --git a/log4j-jul/src/test/resources/log4j2-calling-class.xml b/log4j-jul/src/test/resources/CallerInformationTest.xml
similarity index 65%
copy from log4j-jul/src/test/resources/log4j2-calling-class.xml
copy to log4j-jul/src/test/resources/CallerInformationTest.xml
index 1af22eaa82..4a73dddcc7 100644
--- a/log4j-jul/src/test/resources/log4j2-calling-class.xml
+++ b/log4j-jul/src/test/resources/CallerInformationTest.xml
@@ -15,22 +15,28 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<Configuration name="CallerInformationTest" status="ERROR">
+<Configuration xmlns="https://logging.apache.org/xml/ns"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ https://logging.apache.org/xml/ns
+ https://logging.apache.org/xml/ns/log4j-config-3.xsd">
<Appenders>
<List name="Class">
- <PatternLayout pattern="%class"/>
+ <PatternLayout pattern="%class"
+ alwaysWriteExceptions="false"/>
</List>
<List name="Method">
- <PatternLayout pattern="%method"/>
+ <PatternLayout pattern="%method"
+ alwaysWriteExceptions="false"/>
</List>
</Appenders>
<Loggers>
- <Logger name="ClassLogger" level="info">
+ <Logger name="ClassLogger" level="INFO">
<AppenderRef ref="Class"/>
</Logger>
- <Logger name="MethodLogger" level="info">
+ <Logger name="MethodLogger" level="INFO">
<AppenderRef ref="Method"/>
</Logger>
- <Root level="off"/>
+ <Root level="OFF"/>
</Loggers>
</Configuration>
diff --git a/log4j-jul/src/test/resources/ResourceBundleTest.properties b/log4j-jul/src/test/resources/ResourceBundleTest.properties
new file mode 100644
index 0000000000..3563a11978
--- /dev/null
+++ b/log4j-jul/src/test/resources/ResourceBundleTest.properties
@@ -0,0 +1,21 @@
+#
+# 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.
+#
+##
+# Resource bundle used in ResourceBundleTest
+
+msg_1 = Hello!
+msg_2 = Hello %s and %s!
diff --git a/log4j-jul/src/test/resources/log4j2-calling-class.xml b/log4j-jul/src/test/resources/ResourceBundleTest.xml
similarity index 68%
rename from log4j-jul/src/test/resources/log4j2-calling-class.xml
rename to log4j-jul/src/test/resources/ResourceBundleTest.xml
index 1af22eaa82..3d2d891500 100644
--- a/log4j-jul/src/test/resources/log4j2-calling-class.xml
+++ b/log4j-jul/src/test/resources/ResourceBundleTest.xml
@@ -15,22 +15,17 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<Configuration name="CallerInformationTest" status="ERROR">
+<Configuration xmlns="https://logging.apache.org/xml/ns"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ https://logging.apache.org/xml/ns
+ https://logging.apache.org/xml/ns/log4j-config-3.xsd">
<Appenders>
- <List name="Class">
- <PatternLayout pattern="%class"/>
- </List>
- <List name="Method">
- <PatternLayout pattern="%method"/>
- </List>
+ <List name="LIST"/>
</Appenders>
<Loggers>
- <Logger name="ClassLogger" level="info">
- <AppenderRef ref="Class"/>
- </Logger>
- <Logger name="MethodLogger" level="info">
- <AppenderRef ref="Method"/>
- </Logger>
- <Root level="off"/>
+ <Root level="INFO">
+ <AppenderRef ref="LIST"/>
+ </Root>
</Loggers>
</Configuration>