From b2c0a85013d492f2a80c0f938459619406643462 Mon Sep 17 00:00:00 2001
From: "Piotr P. Karwasz"
Date: Thu, 14 Mar 2024 15:58:42 +0100
Subject: [PATCH 01/12] Simplify `ServiceLoaderUtil`
We make `ServiceLoaderUtil` more GraalVM-friendly by replacing the usage
of `MethodHandles.Lookup` with the requirement for the caller to
instantiate the `ServiceLoader` himself.
---
.../log4j/util/ServiceLoaderUtilTest.java | 25 ++-
log4j-api/pom.xml | 4 +
.../log4j/message/ThreadDumpMessage.java | 8 +-
.../log4j/util/OsgiServiceLocator.java | 55 +++--
.../logging/log4j/util/PropertiesUtil.java | 6 +-
.../logging/log4j/util/ProviderUtil.java | 7 +-
.../logging/log4j/util/ServiceLoaderUtil.java | 193 ++++++------------
.../logging/log4j/util/StackLocator.java | 5 +-
.../log4j/core/appender/SmtpAppender.java | 10 +-
.../core/impl/ThreadContextDataInjector.java | 7 +-
.../logging/log4j/core/util/WatchManager.java | 5 +-
11 files changed, 158 insertions(+), 167 deletions(-)
diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/util/ServiceLoaderUtilTest.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/util/ServiceLoaderUtilTest.java
index 09b489565c9..8ca74a0bee6 100644
--- a/log4j-api-test/src/test/java/org/apache/logging/log4j/util/ServiceLoaderUtilTest.java
+++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/util/ServiceLoaderUtilTest.java
@@ -20,13 +20,15 @@
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceConfigurationError;
+import java.util.ServiceLoader;
import java.util.stream.Collectors;
import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.status.StatusData;
+import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.test.BetterService;
import org.apache.logging.log4j.test.ListStatusListener;
import org.apache.logging.log4j.test.Service;
@@ -35,14 +37,26 @@
public class ServiceLoaderUtilTest {
+ private static final Logger LOGGER = StatusLogger.getLogger();
+
@Test
public void testServiceResolution() {
final List
*
- * @param value The value's whose class name should be used as the Logger name.
+ * @param value The value whose class name should be used as the Logger name.
* @return The Logger, created with a {@link StringFormatterMessageFactory}
* @throws UnsupportedOperationException if {@code value} is {@code null} and the calling class cannot be
* determined.
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/Logger.java b/log4j-api/src/main/java/org/apache/logging/log4j/Logger.java
index 7dc872e21a1..ef461ddfe31 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/Logger.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/Logger.java
@@ -200,7 +200,6 @@ public interface Logger {
* @param paramSuppliers An array of functions, which when called, produce the desired log message parameters.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void debug(Marker marker, String message, Supplier>... paramSuppliers);
/**
@@ -222,7 +221,6 @@ public interface Logger {
* message factory.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void debug(Marker marker, Supplier> messageSupplier);
/**
@@ -235,7 +233,6 @@ public interface Logger {
* @param throwable A Throwable or null.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void debug(Marker marker, Supplier> messageSupplier, Throwable throwable);
/**
@@ -329,7 +326,6 @@ public interface Logger {
* @param paramSuppliers An array of functions, which when called, produce the desired log message parameters.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void debug(String message, Supplier>... paramSuppliers);
/**
@@ -348,7 +344,6 @@ public interface Logger {
* message factory.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void debug(Supplier> messageSupplier);
/**
@@ -360,7 +355,6 @@ public interface Logger {
* @param throwable the {@code Throwable} to log, including its stack trace.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void debug(Supplier> messageSupplier, Throwable throwable);
/**
@@ -811,7 +805,6 @@ void debug(
* @param paramSuppliers An array of functions, which when called, produce the desired log message parameters.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void error(Marker marker, String message, Supplier>... paramSuppliers);
/**
@@ -833,7 +826,6 @@ void debug(
* message factory.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void error(Marker marker, Supplier> messageSupplier);
/**
@@ -846,7 +838,6 @@ void debug(
* @param throwable A Throwable or null.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void error(Marker marker, Supplier> messageSupplier, Throwable throwable);
/**
@@ -940,7 +931,6 @@ void debug(
* @param paramSuppliers An array of functions, which when called, produce the desired log message parameters.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void error(String message, Supplier>... paramSuppliers);
/**
@@ -959,7 +949,6 @@ void debug(
* message factory.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void error(Supplier> messageSupplier);
/**
@@ -971,7 +960,6 @@ void debug(
* @param throwable the {@code Throwable} to log, including its stack trace.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void error(Supplier> messageSupplier, Throwable throwable);
/**
@@ -1414,7 +1402,6 @@ void error(
* @param paramSuppliers An array of functions, which when called, produce the desired log message parameters.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void fatal(Marker marker, String message, Supplier>... paramSuppliers);
/**
@@ -1436,7 +1423,6 @@ void error(
* message factory.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void fatal(Marker marker, Supplier> messageSupplier);
/**
@@ -1449,7 +1435,6 @@ void error(
* @param throwable A Throwable or null.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void fatal(Marker marker, Supplier> messageSupplier, Throwable throwable);
/**
@@ -1543,7 +1528,6 @@ void error(
* @param paramSuppliers An array of functions, which when called, produce the desired log message parameters.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void fatal(String message, Supplier>... paramSuppliers);
/**
@@ -1562,7 +1546,6 @@ void error(
* message factory.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void fatal(Supplier> messageSupplier);
/**
@@ -1574,7 +1557,6 @@ void error(
* @param throwable the {@code Throwable} to log, including its stack trace.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void fatal(Supplier> messageSupplier, Throwable throwable);
/**
@@ -1901,12 +1883,13 @@ void fatal(
/**
* Gets the message factory used to convert message Objects and Strings/CharSequences into actual log Messages.
- *
- * Since version 2.6, Log4j internally uses message factories that implement the {@link MessageFactory2} interface.
- * From version 2.6.2, the return type of this method was changed from {@link MessageFactory} to
- * {@code MF}. The returned factory will always implement {@link MessageFactory2},
- * but the return type of this method could not be changed to {@link MessageFactory2} without breaking binary
- * compatibility.
+ *
+ * Since version 2.6, Log4j internally uses message factories that implement the {@link MessageFactory2}
+ * interface. From version 2.6.2, the return type of this method was changed from {@link MessageFactory} to
+ * {@code MF}. The returned factory will always implement {@link MessageFactory2},
+ * but the return type of this method could not be changed to {@link MessageFactory2} without breaking binary
+ * compatibility.
+ *
*
* @return the message factory, as an instance of {@link MessageFactory2}
*/
@@ -2030,7 +2013,6 @@ void fatal(
* @param paramSuppliers An array of functions, which when called, produce the desired log message parameters.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void info(Marker marker, String message, Supplier>... paramSuppliers);
/**
@@ -2052,7 +2034,6 @@ void fatal(
* message factory.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void info(Marker marker, Supplier> messageSupplier);
/**
@@ -2065,7 +2046,6 @@ void fatal(
* @param throwable A Throwable or null.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void info(Marker marker, Supplier> messageSupplier, Throwable throwable);
/**
@@ -2159,7 +2139,6 @@ void fatal(
* @param paramSuppliers An array of functions, which when called, produce the desired log message parameters.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void info(String message, Supplier>... paramSuppliers);
/**
@@ -2178,7 +2157,6 @@ void fatal(
* message factory.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void info(Supplier> messageSupplier);
/**
@@ -2190,7 +2168,6 @@ void fatal(
* @param throwable the {@code Throwable} to log, including its stack trace.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void info(Supplier> messageSupplier, Throwable throwable);
/**
@@ -2737,7 +2714,6 @@ void info(
* @param paramSuppliers An array of functions, which when called, produce the desired log message parameters.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void log(Level level, Marker marker, String message, Supplier>... paramSuppliers);
/**
@@ -2760,7 +2736,6 @@ void info(
* message factory.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void log(Level level, Marker marker, Supplier> messageSupplier);
/**
@@ -2774,7 +2749,6 @@ void info(
* @param throwable A Throwable or null.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void log(Level level, Marker marker, Supplier> messageSupplier, Throwable throwable);
/**
@@ -2878,7 +2852,6 @@ void info(
* @param paramSuppliers An array of functions, which when called, produce the desired log message parameters.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void log(Level level, String message, Supplier>... paramSuppliers);
/**
@@ -2899,7 +2872,6 @@ void info(
* message factory.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void log(Level level, Supplier> messageSupplier);
/**
@@ -2912,7 +2884,6 @@ void info(
* @param throwable the {@code Throwable} to log, including its stack log.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void log(Level level, Supplier> messageSupplier, Throwable throwable);
/**
@@ -3435,7 +3406,6 @@ void log(
* @param paramSuppliers An array of functions, which when called, produce the desired log message parameters.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void trace(Marker marker, String message, Supplier>... paramSuppliers);
/**
@@ -3458,7 +3428,6 @@ void log(
* message factory.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void trace(Marker marker, Supplier> messageSupplier);
/**
@@ -3471,7 +3440,6 @@ void log(
* @param throwable A Throwable or null.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void trace(Marker marker, Supplier> messageSupplier, Throwable throwable);
/**
@@ -3567,7 +3535,6 @@ void log(
* @param paramSuppliers An array of functions, which when called, produce the desired log message parameters.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void trace(String message, Supplier>... paramSuppliers);
/**
@@ -3587,7 +3554,6 @@ void log(
* message factory.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void trace(Supplier> messageSupplier);
/**
@@ -3599,7 +3565,6 @@ void log(
* @param throwable the {@code Throwable} to log, including its stack trace.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void trace(Supplier> messageSupplier, Throwable throwable);
/**
@@ -3967,7 +3932,6 @@ void trace(
*
* @since 2.6
*/
- @SuppressWarnings("deprecation")
EntryMessage traceEntry(Supplier>... paramSuppliers);
/**
@@ -3986,7 +3950,6 @@ void trace(
*
* @since 2.6
*/
- @SuppressWarnings("deprecation")
EntryMessage traceEntry(String format, Supplier>... paramSuppliers);
/**
@@ -4205,7 +4168,6 @@ void trace(
* @param paramSuppliers An array of functions, which when called, produce the desired log message parameters.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void warn(Marker marker, String message, Supplier>... paramSuppliers);
/**
@@ -4227,7 +4189,6 @@ void trace(
* message factory.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void warn(Marker marker, Supplier> messageSupplier);
/**
@@ -4240,7 +4201,6 @@ void trace(
* @param throwable A Throwable or null.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void warn(Marker marker, Supplier> messageSupplier, Throwable throwable);
/**
@@ -4334,7 +4294,6 @@ void trace(
* @param paramSuppliers An array of functions, which when called, produce the desired log message parameters.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void warn(String message, Supplier>... paramSuppliers);
/**
@@ -4353,7 +4312,6 @@ void trace(
* message factory.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void warn(Supplier> messageSupplier);
/**
@@ -4365,7 +4323,6 @@ void trace(
* @param throwable the {@code Throwable} to log, including its stack warn.
* @since 2.4
*/
- @SuppressWarnings("deprecation")
void warn(Supplier> messageSupplier, Throwable throwable);
/**
@@ -4695,7 +4652,12 @@ void warn(
* @since 2.13.0
*/
default void logMessage(
- Level level, Marker marker, String fqcn, StackTraceElement location, Message message, Throwable throwable) {
+ final Level level,
+ final Marker marker,
+ final String fqcn,
+ final StackTraceElement location,
+ final Message message,
+ final Throwable throwable) {
// noop
}
@@ -4768,7 +4730,7 @@ default LogBuilder always() {
* @return a LogBuilder.
* @since 2.13.0
*/
- default LogBuilder atLevel(Level level) {
+ default LogBuilder atLevel(final Level level) {
return LogBuilder.NOOP;
}
}
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/BiConsumer.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/BiConsumer.java
index 7be09f0431b..e7cedb6bb3b 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/BiConsumer.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/BiConsumer.java
@@ -24,12 +24,14 @@
* @see ReadOnlyStringMap
* @since 2.7
*/
-public interface BiConsumer {
+@FunctionalInterface
+public interface BiConsumer extends java.util.function.BiConsumer {
/**
* Performs the operation given the specified arguments.
* @param k the first input argument
* @param v the second input argument
*/
+ @Override
void accept(K k, V v);
}
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/LambdaUtil.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/LambdaUtil.java
index bab3171e7f3..ef1f3b0b321 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/LambdaUtil.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/LambdaUtil.java
@@ -35,7 +35,6 @@ private LambdaUtil() {}
* @return an array containing the results of evaluating the lambda expressions (or {@code null} if the suppliers
* array was {@code null}
*/
- @SuppressWarnings("deprecation")
public static Object[] getAll(final Supplier>... suppliers) {
if (suppliers == null) {
return null;
@@ -54,7 +53,6 @@ public static Object[] getAll(final Supplier>... suppliers) {
* @return the results of evaluating the lambda expression (or {@code null} if the supplier
* was {@code null}
*/
- @SuppressWarnings("deprecation")
public static Object get(final Supplier> supplier) {
if (supplier == null) {
return null;
@@ -83,7 +81,6 @@ public static Message get(final MessageSupplier supplier) {
* @return the Message resulting from evaluating the lambda expression or the Message created by the factory for
* supplied values that are not of type Message
*/
- @SuppressWarnings("deprecation")
public static Message getMessage(final Supplier> supplier, final MessageFactory messageFactory) {
if (supplier == null) {
return null;
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/MessageSupplier.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/MessageSupplier.java
index 8b135713505..d3776a1a744 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/MessageSupplier.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/MessageSupplier.java
@@ -33,12 +33,14 @@
*
* @since 2.4
*/
-public interface MessageSupplier {
+@FunctionalInterface
+public interface MessageSupplier extends Supplier {
/**
* Gets a Message.
*
* @return a Message
*/
+ @Override
Message get();
}
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/Supplier.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/Supplier.java
index aaa4d9b89a1..45ad5c667d2 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/Supplier.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/Supplier.java
@@ -31,14 +31,15 @@
*
* @since 2.4
*/
+@FunctionalInterface
@InternalApi
-@Deprecated
-public interface Supplier {
+public interface Supplier extends java.util.function.Supplier {
/**
* Gets a value.
*
* @return a value
*/
+ @Override
T get();
}
From f3c0f6ff63abae21153e2b6818ad1dab2ed83faa Mon Sep 17 00:00:00 2001
From: "Piotr P. Karwasz"
Date: Fri, 15 Mar 2024 14:28:49 +0100
Subject: [PATCH 04/12] Add `Strings#trimToOptional`
---
.../org/apache/logging/log4j/util/Strings.java | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/Strings.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/Strings.java
index bee54324f44..8eea0e782c8 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/Strings.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/Strings.java
@@ -21,6 +21,7 @@
import java.util.Iterator;
import java.util.Locale;
import java.util.Objects;
+import java.util.Optional;
/**
* Consider this class private.
@@ -288,6 +289,19 @@ public static String trimToNull(final String str) {
return isEmpty(ts) ? null : ts;
}
+ /**
+ * Removes control characters from both ends of this String returning {@code Optional.empty()} if the String is
+ * empty ("") after the trim or if it is {@code null}.
+ * @param str The String to trim.
+ * @return An Optional containing the String.
+ *
+ * @see #trimToNull(String)
+ * @since 2.24.0
+ */
+ public static Optional trimToOptional(final String str) {
+ return Optional.ofNullable(str).map(String::trim).filter(s -> !s.isEmpty());
+ }
+
private Strings() {
// empty
}
From f7184e5018f9e5c07b0a82dfcdaf9c87550e0abb Mon Sep 17 00:00:00 2001
From: "Piotr P. Karwasz"
Date: Fri, 15 Mar 2024 14:29:50 +0100
Subject: [PATCH 05/12] Make default message factories GraalVM friendly
---
.../message/DefaultFlowMessageFactory.java | 22 ++++++++++++-------
.../logging/log4j/spi/AbstractLogger.java | 14 ++----------
2 files changed, 16 insertions(+), 20 deletions(-)
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/DefaultFlowMessageFactory.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/DefaultFlowMessageFactory.java
index 1c6fcd3f459..3ca2aeba41a 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/DefaultFlowMessageFactory.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/DefaultFlowMessageFactory.java
@@ -17,8 +17,7 @@
package org.apache.logging.log4j.message;
import java.io.Serializable;
-import org.apache.logging.log4j.spi.AbstractLogger;
-import org.apache.logging.log4j.util.LoaderUtil;
+import java.util.Objects;
import org.apache.logging.log4j.util.StringBuilderFormattable;
import org.apache.logging.log4j.util.StringBuilders;
import org.apache.logging.log4j.util.Strings;
@@ -34,6 +33,8 @@ public class DefaultFlowMessageFactory implements FlowMessageFactory, Serializab
private static final String ENTRY_DEFAULT_PREFIX = "Enter";
private static final long serialVersionUID = 8578655591131397576L;
+ public static final FlowMessageFactory INSTANCE = new DefaultFlowMessageFactory();
+
private final String entryText;
private final String exitText;
private final MessageFactory messageFactory;
@@ -51,17 +52,22 @@ public DefaultFlowMessageFactory() {
* @param exitText the text to use for trace exit, like {@code "Exit"}.
*/
public DefaultFlowMessageFactory(final String entryText, final String exitText) {
+ this(entryText, exitText, createDefaultMessageFactory());
+ }
+
+ public DefaultFlowMessageFactory(final MessageFactory messageFactory) {
+ this(ENTRY_DEFAULT_PREFIX, EXIT_DEFAULT_PREFIX, Objects.requireNonNull(messageFactory));
+ }
+
+ private DefaultFlowMessageFactory(
+ final String entryText, final String exitText, final MessageFactory messageFactory) {
this.entryText = entryText;
this.exitText = exitText;
- this.messageFactory = createDefaultMessageFactory();
+ this.messageFactory = messageFactory;
}
private static MessageFactory createDefaultMessageFactory() {
- try {
- return LoaderUtil.newInstanceOf(AbstractLogger.DEFAULT_MESSAGE_FACTORY_CLASS);
- } catch (final ReflectiveOperationException e) {
- throw new IllegalStateException(e);
- }
+ return ParameterizedMessageFactory.INSTANCE;
}
private static class AbstractFlowMessage implements FlowMessage, StringBuilderFormattable {
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLogger.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLogger.java
index d9543f17b52..30d0cffef02 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLogger.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLogger.java
@@ -35,7 +35,6 @@
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.Constants;
import org.apache.logging.log4j.util.LambdaUtil;
-import org.apache.logging.log4j.util.LoaderUtil;
import org.apache.logging.log4j.util.MessageSupplier;
import org.apache.logging.log4j.util.PerformanceSensitive;
import org.apache.logging.log4j.util.StackLocatorUtil;
@@ -198,12 +197,7 @@ protected Message catchingMsg(final Throwable throwable) {
}
private static MessageFactory2 createDefaultMessageFactory() {
- try {
- final MessageFactory result = LoaderUtil.newInstanceOf(DEFAULT_MESSAGE_FACTORY_CLASS);
- return narrow(result);
- } catch (final ReflectiveOperationException e) {
- throw new IllegalStateException(e);
- }
+ return ParameterizedMessageFactory.INSTANCE;
}
private static MessageFactory2 narrow(final MessageFactory result) {
@@ -214,11 +208,7 @@ private static MessageFactory2 narrow(final MessageFactory result) {
}
private static FlowMessageFactory createDefaultFlowMessageFactory() {
- try {
- return LoaderUtil.newInstanceOf(DEFAULT_FLOW_MESSAGE_FACTORY_CLASS);
- } catch (final ReflectiveOperationException e) {
- throw new IllegalStateException(e);
- }
+ return DefaultFlowMessageFactory.INSTANCE;
}
@Override
From 91579573a58ab16b0070c83e2a89c8170335d87e Mon Sep 17 00:00:00 2001
From: "Piotr P. Karwasz"
Date: Fri, 15 Mar 2024 16:04:10 +0100
Subject: [PATCH 06/12] Port `Tags` from 3.x
---
.../apache/logging/log4j/test/junit/Tags.java | 33 +++++++++++++++++++
.../log4j/test/junit/package-info.java | 2 +-
2 files changed, 34 insertions(+), 1 deletion(-)
create mode 100644 log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/Tags.java
diff --git a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/Tags.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/Tags.java
new file mode 100644
index 00000000000..06bef43b06d
--- /dev/null
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/Tags.java
@@ -0,0 +1,33 @@
+/*
+ * 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.test.junit;
+
+/**
+ * A set of tags for JUnit 5 tests.
+ */
+public final class Tags {
+
+ /**
+ * Marks tests that don't modify the global environment.
+ *
+ * These tests can safely be run in parallel.
+ *
+ */
+ public static final String PARALLEL = "parallel";
+
+ private Tags() {}
+}
diff --git a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/package-info.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/package-info.java
index 22e32873bee..3207042de87 100644
--- a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/package-info.java
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/package-info.java
@@ -15,7 +15,7 @@
* limitations under the license.
*/
@Export
-@Version("2.23.1")
+@Version("2.24.0")
package org.apache.logging.log4j.test.junit;
import org.osgi.annotation.bundle.Export;
From c2c3a018255b7d2cd2289965340a383f2adf8480 Mon Sep 17 00:00:00 2001
From: "Piotr P. Karwasz"
Date: Tue, 19 Mar 2024 14:11:41 +0100
Subject: [PATCH 07/12] Remove reflection from `log4j-to-jul` and
`log4j-to-slf4j`
By removing the reflective instantiation of `LoggerContextFactory` and
`ThreadContextMap`, we make `log4j-to-jul` and `log4j-to-slf4j` more
GraalVM-friendly.
---
.../logging/log4j/tojul/JULProvider.java | 16 +++++++++++++++-
.../logging/log4j/tojul/package-info.java | 2 +-
.../apache/logging/slf4j/SLF4JProvider.java | 18 +++++++++++++++++-
.../org/apache/logging/slf4j/package-info.java | 2 +-
4 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/JULProvider.java b/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/JULProvider.java
index 9022d9abeb8..0f371f43ef0 100644
--- a/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/JULProvider.java
+++ b/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/JULProvider.java
@@ -18,6 +18,7 @@
import aQute.bnd.annotation.Resolution;
import aQute.bnd.annotation.spi.ServiceProvider;
+import org.apache.logging.log4j.spi.LoggerContextFactory;
import org.apache.logging.log4j.spi.Provider;
/**
@@ -27,7 +28,20 @@
*/
@ServiceProvider(value = Provider.class, resolution = Resolution.OPTIONAL)
public class JULProvider extends Provider {
+ private static final LoggerContextFactory CONTEXT_FACTORY = new JULLoggerContextFactory();
+
public JULProvider() {
- super(20, "2.6.0", JULLoggerContextFactory.class, null);
+ super(20, CURRENT_VERSION);
+ }
+
+ @Override
+ public LoggerContextFactory getLoggerContextFactory() {
+ return CONTEXT_FACTORY;
+ }
+
+ @Override
+ public String getThreadContextMap() {
+ // JUL does not provide an MDC implementation
+ return NO_OP_CONTEXT_MAP;
}
}
diff --git a/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/package-info.java b/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/package-info.java
index f333fffe246..aa117c7995c 100644
--- a/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/package-info.java
+++ b/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/package-info.java
@@ -21,7 +21,7 @@
* @author Michael Vorburger.ch for Google
*/
@Export
-@Version("2.20.1")
+@Version("2.24.0")
package org.apache.logging.log4j.tojul;
import org.osgi.annotation.bundle.Export;
diff --git a/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JProvider.java b/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JProvider.java
index b8514c4f632..318d7937f66 100644
--- a/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JProvider.java
+++ b/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JProvider.java
@@ -18,14 +18,30 @@
import aQute.bnd.annotation.Resolution;
import aQute.bnd.annotation.spi.ServiceProvider;
+import org.apache.logging.log4j.spi.LoggerContextFactory;
import org.apache.logging.log4j.spi.Provider;
+import org.apache.logging.log4j.spi.ThreadContextMap;
/**
* Bind the Log4j API to SLF4J.
*/
@ServiceProvider(value = Provider.class, resolution = Resolution.OPTIONAL)
public class SLF4JProvider extends Provider {
+
+ private static final LoggerContextFactory CONTEXT_FACTORY = new SLF4JLoggerContextFactory();
+ private static final ThreadContextMap THREAD_CONTEXT_MAP = new MDCContextMap();
+
public SLF4JProvider() {
- super(15, "2.6.0", SLF4JLoggerContextFactory.class, MDCContextMap.class);
+ super(15, CURRENT_VERSION);
+ }
+
+ @Override
+ public LoggerContextFactory getLoggerContextFactory() {
+ return CONTEXT_FACTORY;
+ }
+
+ @Override
+ public ThreadContextMap getThreadContextMapInstance() {
+ return THREAD_CONTEXT_MAP;
}
}
diff --git a/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/package-info.java b/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/package-info.java
index e354601ca71..ba4cb130be1 100644
--- a/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/package-info.java
+++ b/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/package-info.java
@@ -18,7 +18,7 @@
* SLF4J support.
*/
@Export
-@Version("2.20.1")
+@Version("2.24.0")
package org.apache.logging.slf4j;
import org.osgi.annotation.bundle.Export;
From a567c580ff51d645c710c8edd396679c58beea11 Mon Sep 17 00:00:00 2001
From: "Piotr P. Karwasz"
Date: Tue, 19 Mar 2024 14:11:41 +0100
Subject: [PATCH 08/12] Add constants to mark global resource usage
---
.../logging/log4j/test/junit/Resources.java | 33 ++++++++++++++++---
1 file changed, 29 insertions(+), 4 deletions(-)
diff --git a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/Resources.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/Resources.java
index 980900cd965..8956311e499 100644
--- a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/Resources.java
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/Resources.java
@@ -20,11 +20,36 @@
/**
* Constants to use the {@link ResourceLock} annotation.
- *
*/
-public class Resources {
+public final class Resources {
+
+ /**
+ * Marks tests that require access to {@link org.apache.logging.log4j.LogManager} methods or change its
+ * underlying {@link org.apache.logging.log4j.spi.LoggerContextFactory} implementation.
+ */
+ public static final String LOG_MANAGER = "log4j.LogManager";
+
+ /**
+ * Marks tests that require access to {@link org.apache.logging.log4j.ThreadContext} methods or change its
+ * underlying {@link org.apache.logging.log4j.spi.ThreadContextMap} implementation.
+ */
+ public static final String THREAD_CONTEXT = "log4j.ThreadContext";
+
+ /**
+ * Marks tests that require access to {@link org.apache.logging.log4j.MarkerManager} methods.
+ */
+ public static final String MARKER_MANAGER = "log4j.MarkerManager";
+
+ /**
+ * Marks tests that requires access to {@link org.apache.logging.log4j.Level} static methods to create new levels.
+ */
+ public static final String LEVEL = "log4j.Level";
- public static final String THREAD_CONTEXT = "log4j2.ThreadContext";
+ /**
+ * Marks tests that require access to {@link org.apache.logging.log4j.status.StatusLogger} static methods or
+ * change its underlying implementation.
+ */
+ public static final String STATUS_LOGGER = "log4j.StatusLogger";
- public static final String MARKER_MANAGER = "log4j2.MarkerManager";
+ private Resources() {}
}
From 08a17c3e1fbf23498ce64ce9da6bdd161edc7a2b Mon Sep 17 00:00:00 2001
From: "Piotr P. Karwasz"
Date: Fri, 22 Mar 2024 11:32:24 +0100
Subject: [PATCH 09/12] Apply suggestions of review #2392
---
.../apache/logging/log4j/test/junit/Tags.java | 33 -------------------
.../message/DefaultFlowMessageFactory.java | 26 +++------------
.../apache/logging/log4j/util/Strings.java | 14 --------
3 files changed, 5 insertions(+), 68 deletions(-)
delete mode 100644 log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/Tags.java
diff --git a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/Tags.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/Tags.java
deleted file mode 100644
index 06bef43b06d..00000000000
--- a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/Tags.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.logging.log4j.test.junit;
-
-/**
- * A set of tags for JUnit 5 tests.
- */
-public final class Tags {
-
- /**
- * Marks tests that don't modify the global environment.
- *
- * These tests can safely be run in parallel.
- *
- */
- public static final String PARALLEL = "parallel";
-
- private Tags() {}
-}
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/DefaultFlowMessageFactory.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/DefaultFlowMessageFactory.java
index 3ca2aeba41a..57dbd29b8ab 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/DefaultFlowMessageFactory.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/DefaultFlowMessageFactory.java
@@ -17,7 +17,6 @@
package org.apache.logging.log4j.message;
import java.io.Serializable;
-import java.util.Objects;
import org.apache.logging.log4j.util.StringBuilderFormattable;
import org.apache.logging.log4j.util.StringBuilders;
import org.apache.logging.log4j.util.Strings;
@@ -37,7 +36,6 @@ public class DefaultFlowMessageFactory implements FlowMessageFactory, Serializab
private final String entryText;
private final String exitText;
- private final MessageFactory messageFactory;
/**
* Constructs a message factory with {@code "Enter"} and {@code "Exit"} as the default flow strings.
@@ -52,22 +50,8 @@ public DefaultFlowMessageFactory() {
* @param exitText the text to use for trace exit, like {@code "Exit"}.
*/
public DefaultFlowMessageFactory(final String entryText, final String exitText) {
- this(entryText, exitText, createDefaultMessageFactory());
- }
-
- public DefaultFlowMessageFactory(final MessageFactory messageFactory) {
- this(ENTRY_DEFAULT_PREFIX, EXIT_DEFAULT_PREFIX, Objects.requireNonNull(messageFactory));
- }
-
- private DefaultFlowMessageFactory(
- final String entryText, final String exitText, final MessageFactory messageFactory) {
this.entryText = entryText;
this.exitText = exitText;
- this.messageFactory = messageFactory;
- }
-
- private static MessageFactory createDefaultMessageFactory() {
- return ParameterizedMessageFactory.INSTANCE;
}
private static class AbstractFlowMessage implements FlowMessage, StringBuilderFormattable {
@@ -200,9 +184,9 @@ public EntryMessage newEntryMessage(final String format, final Object... params)
final boolean hasFormat = Strings.isNotEmpty(format);
final Message message;
if (params == null || params.length == 0) {
- message = hasFormat ? messageFactory.newMessage(format) : null;
+ message = hasFormat ? ParameterizedMessageFactory.INSTANCE.newMessage(format) : null;
} else if (hasFormat) {
- message = messageFactory.newMessage(format, params);
+ message = ParameterizedMessageFactory.INSTANCE.newMessage(format, params);
} else {
final StringBuilder sb = new StringBuilder("params(");
for (int i = 0; i < params.length; i++) {
@@ -212,7 +196,7 @@ public EntryMessage newEntryMessage(final String format, final Object... params)
sb.append("{}");
}
sb.append(")");
- message = messageFactory.newMessage(sb.toString(), params);
+ message = ParameterizedMessageFactory.INSTANCE.newMessage(sb.toString(), params);
}
return newEntryMessage(message);
}
@@ -239,9 +223,9 @@ public ExitMessage newExitMessage(final String format, final Object result) {
final boolean hasFormat = Strings.isNotEmpty(format);
final Message message;
if (result == null) {
- message = hasFormat ? messageFactory.newMessage(format) : null;
+ message = hasFormat ? ParameterizedMessageFactory.INSTANCE.newMessage(format) : null;
} else {
- message = messageFactory.newMessage(hasFormat ? format : "with({})", result);
+ message = ParameterizedMessageFactory.INSTANCE.newMessage(hasFormat ? format : "with({})", result);
}
return newExitMessage(message);
}
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/Strings.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/Strings.java
index 8eea0e782c8..bee54324f44 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/Strings.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/Strings.java
@@ -21,7 +21,6 @@
import java.util.Iterator;
import java.util.Locale;
import java.util.Objects;
-import java.util.Optional;
/**
* Consider this class private.
@@ -289,19 +288,6 @@ public static String trimToNull(final String str) {
return isEmpty(ts) ? null : ts;
}
- /**
- * Removes control characters from both ends of this String returning {@code Optional.empty()} if the String is
- * empty ("") after the trim or if it is {@code null}.
- * @param str The String to trim.
- * @return An Optional containing the String.
- *
- * @see #trimToNull(String)
- * @since 2.24.0
- */
- public static Optional trimToOptional(final String str) {
- return Optional.ofNullable(str).map(String::trim).filter(s -> !s.isEmpty());
- }
-
private Strings() {
// empty
}
From a1c2bd1785379d67be05ffd2f2c0e666f714432c Mon Sep 17 00:00:00 2001
From: "Piotr P. Karwasz"
Date: Fri, 22 Mar 2024 11:43:39 +0100
Subject: [PATCH 10/12] Add changelog for GraalVM-compatibility
---
src/changelog/.2.x.x/1539_graalvm_friendly.xml | 8 ++++++++
1 file changed, 8 insertions(+)
create mode 100644 src/changelog/.2.x.x/1539_graalvm_friendly.xml
diff --git a/src/changelog/.2.x.x/1539_graalvm_friendly.xml b/src/changelog/.2.x.x/1539_graalvm_friendly.xml
new file mode 100644
index 00000000000..74964f43564
--- /dev/null
+++ b/src/changelog/.2.x.x/1539_graalvm_friendly.xml
@@ -0,0 +1,8 @@
+
+
+
+ Fix usage of `log4j-api` in GraalVM without additional reachability data.
+
From f0e82d15e7f718059ecb4207c6f63396e3fb7421 Mon Sep 17 00:00:00 2001
From: "Piotr P. Karwasz"
Date: Fri, 22 Mar 2024 11:51:15 +0100
Subject: [PATCH 11/12] Fix BND baseline error
---
.../java/org/apache/logging/log4j/test/junit/Resources.java | 2 ++
1 file changed, 2 insertions(+)
diff --git a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/Resources.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/Resources.java
index 8956311e499..66631c194e6 100644
--- a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/Resources.java
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/Resources.java
@@ -16,11 +16,13 @@
*/
package org.apache.logging.log4j.test.junit;
+import aQute.bnd.annotation.baseline.BaselineIgnore;
import org.junit.jupiter.api.parallel.ResourceLock;
/**
* Constants to use the {@link ResourceLock} annotation.
*/
+@BaselineIgnore("2.24.0")
public final class Resources {
/**
From 11209a3abf4b5eb65cf416c5f22a992357fd45fc Mon Sep 17 00:00:00 2001
From: "Piotr P. Karwasz"
Date: Fri, 22 Mar 2024 13:20:39 +0100
Subject: [PATCH 12/12] Rollback breaking change in `ReusableMessage`
---
.../org/apache/logging/log4j/message/ReusableMessage.java | 8 --------
1 file changed, 8 deletions(-)
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableMessage.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableMessage.java
index 5a5d264e680..35e8fa3919c 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableMessage.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableMessage.java
@@ -18,7 +18,6 @@
import org.apache.logging.log4j.util.PerformanceSensitive;
import org.apache.logging.log4j.util.StringBuilderFormattable;
-import org.osgi.annotation.versioning.ProviderType;
/**
* Messages implementing this interface are reused between logging calls.
@@ -30,7 +29,6 @@
* @since 2.6
*/
@PerformanceSensitive("allocation")
-@ProviderType
public interface ReusableMessage extends Message, StringBuilderFormattable {
/**
@@ -71,10 +69,4 @@ public interface ReusableMessage extends Message, StringBuilderFormattable {
* @return an immutable snapshot of this message
*/
Message memento();
-
- /**
- * Resets the object to a clean state.
- * @since 2.24.0
- */
- void clear();
}