This is an automated email from the ASF dual-hosted git repository. vy pushed a commit to branch deprecate-Message-getFormat in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit b3636b2fdff405b92c792ed28f66a37ace045b3f Author: Volkan Yazıcı <[email protected]> AuthorDate: Fri Jul 26 20:42:07 2024 +0200 Deprecate `Message#getFormat()` --- .../apache/logging/log4j/AbstractLoggerTest.java | 5 ----- .../org/apache/logging/log4j/message/Message.java | 16 ++++++-------- .../async/AsyncLoggerArgumentFreedOnErrorTest.java | 5 ----- .../core/async/AsyncLoggerConfigErrorOnFormat.java | 5 ----- .../core/async/QueueFullAsyncLogger3Test.java | 5 ----- .../core/lookup/JndiRestrictedLookupTest.java | 6 ------ .../json/resolver/MessageResolverTest.java | 19 +++++++++++----- .../template/json/resolver/MessageResolver.java | 25 +++------------------- .../logging/log4j/perf/nogc/NoGcMessage.java | 5 ----- ...andling.xml => deprecate-Message-getFormat.xml} | 4 ++-- .../antora/modules/ROOT/pages/manual/messages.adoc | 6 ++---- 11 files changed, 28 insertions(+), 73 deletions(-) diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/AbstractLoggerTest.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/AbstractLoggerTest.java index a1370ba21f..f83afb25a9 100644 --- a/log4j-api-test/src/test/java/org/apache/logging/log4j/AbstractLoggerTest.java +++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/AbstractLoggerTest.java @@ -1446,11 +1446,6 @@ public class AbstractLoggerTest { return null; } - @Override - public String getFormat() { - return null; - } - @Override public Object[] getParameters() { return Constants.EMPTY_OBJECT_ARRAY; diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/Message.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/Message.java index a6e687686e..1b1dcaab26 100644 --- a/log4j-api/src/main/java/org/apache/logging/log4j/message/Message.java +++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/Message.java @@ -69,17 +69,15 @@ public interface Message extends Serializable { String getFormattedMessage(); /** - * Gets the format portion of the Message. + * This method has unclear semantics and inconsistent implementations – its usage is strongly discouraged. * - * @return The message format. Some implementations, such as ParameterizedMessage, will use this as - * the message "pattern". Other Messages may simply return an empty String. - * TODO Do all messages have a format? What syntax? Using a Formatter object could be cleaner. - * (RG) In SimpleMessage the format is identical to the formatted message. In ParameterizedMessage and - * StructuredDataMessage it is not. It is up to the Message implementer to determine what this - * method will return. A Formatter is inappropriate as this is very specific to the Message - * implementation so it isn't clear to me how having a Formatter separate from the Message would be cleaner. + * @deprecated Deprecated since version {@code 2.24.0}. + * Use {@link MultiformatMessage} instead to implement messages that can format themselves in one or more encodings. */ - String getFormat(); + @Deprecated + default String getFormat() { + return null; + } /** * Gets parameter values, if any. diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerArgumentFreedOnErrorTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerArgumentFreedOnErrorTest.java index b521f1fe14..f145182afc 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerArgumentFreedOnErrorTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerArgumentFreedOnErrorTest.java @@ -83,11 +83,6 @@ public class AsyncLoggerArgumentFreedOnErrorTest { throw new Error("Expected"); } - @Override - public String getFormat() { - return Strings.EMPTY; - } - @Override public Object[] getParameters() { return org.apache.logging.log4j.util.Constants.EMPTY_OBJECT_ARRAY; diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigErrorOnFormat.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigErrorOnFormat.java index 96f13e70d3..58020a8115 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigErrorOnFormat.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigErrorOnFormat.java @@ -83,11 +83,6 @@ public class AsyncLoggerConfigErrorOnFormat { "getFormattedMessage invoked on " + Thread.currentThread().getName()); } - @Override - public String getFormat() { - return null; - } - @Override public Object[] getParameters() { return null; diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLogger3Test.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLogger3Test.java index 3be89c6f9b..8802b694ad 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLogger3Test.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLogger3Test.java @@ -93,11 +93,6 @@ public class QueueFullAsyncLogger3Test extends QueueFullAbstractTest { return "formatted"; } - @Override - public String getFormat() { - return null; - } - @Override public Object[] getParameters() { return org.apache.logging.log4j.util.Constants.EMPTY_OBJECT_ARRAY; diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/lookup/JndiRestrictedLookupTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/lookup/JndiRestrictedLookupTest.java index a66c8cb8dc..ae69a1dc5d 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/lookup/JndiRestrictedLookupTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/lookup/JndiRestrictedLookupTest.java @@ -25,7 +25,6 @@ import javax.naming.Reference; import javax.naming.Referenceable; import javax.naming.StringRefAddr; import org.apache.logging.log4j.message.Message; -import org.apache.logging.log4j.util.Strings; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @@ -151,11 +150,6 @@ public class JndiRestrictedLookupTest { return message; } - @Override - public String getFormat() { - return Strings.EMPTY; - } - @Override public Object[] getParameters() { return null; diff --git a/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/resolver/MessageResolverTest.java b/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/resolver/MessageResolverTest.java index 5e166b6de3..dab3bab00f 100644 --- a/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/resolver/MessageResolverTest.java +++ b/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/resolver/MessageResolverTest.java @@ -37,6 +37,7 @@ import org.apache.logging.log4j.core.test.junit.Named; import org.apache.logging.log4j.layout.template.json.JsonTemplateLayout; import org.apache.logging.log4j.layout.template.json.util.JsonReader; import org.apache.logging.log4j.message.Message; +import org.apache.logging.log4j.message.MultiformatMessage; import org.apache.logging.log4j.message.ObjectMessage; import org.apache.logging.log4j.message.SimpleMessage; import org.apache.logging.log4j.message.StringMapMessage; @@ -203,7 +204,7 @@ class MessageResolverTest { } @Test - void test_custom_Message() { + void test_MultiformatMessage() { // Create the event template final String eventTemplate = writeJson(asMap("$resolver", "message")); @@ -216,7 +217,7 @@ class MessageResolverTest { // Create the log event with a `TestMessage` final LogEvent logEvent = Log4jLogEvent.newBuilder() - .setMessage(new TestMessage()) + .setMessage(new TestMultiformatMessage()) .setTimeMillis(System.currentTimeMillis()) .build(); @@ -225,7 +226,7 @@ class MessageResolverTest { .isEqualTo("bar")); } - private static final class TestMessage implements Message { + private static final class TestMultiformatMessage implements MultiformatMessage { @Override public String getFormattedMessage() { @@ -233,8 +234,16 @@ class MessageResolverTest { } @Override - public String getFormat() { - return "JSON"; + public String[] getFormats() { + return new String[] {"JSON"}; + } + + @Override + public String getFormattedMessage(final String[] formats) { + if (formats.length != 1 || !"JSON".equals(formats[0])) { + throw new UnsupportedOperationException(); + } + return getFormattedMessage(); } @Override diff --git a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/MessageResolver.java b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/MessageResolver.java index a9d8618c5d..143cfe4183 100644 --- a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/MessageResolver.java +++ b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/MessageResolver.java @@ -137,22 +137,17 @@ public final class MessageResolver implements EventResolver { private static EventResolver createObjectResolver(final String fallbackKey) { return (final LogEvent logEvent, final JsonWriter jsonWriter) -> { - // Skip custom serializers for `SimpleMessage` + // Skip custom serializers for SimpleMessage. final Message message = logEvent.getMessage(); final boolean simple = message instanceof SimpleMessage; if (!simple) { - // Try `Message` serializer - if (writeMessage(jsonWriter, message)) { - return; - } - - // Try `MultiformatMessage` serializer + // Try MultiformatMessage serializer. if (writeMultiformatMessage(jsonWriter, message)) { return; } - // Try `ObjectMessage` serializer + // Try ObjectMessage serializer. if (writeObjectMessage(jsonWriter, message)) { return; } @@ -163,20 +158,6 @@ public final class MessageResolver implements EventResolver { }; } - private static boolean writeMessage(final JsonWriter jsonWriter, final Message message) { - - // Check the format - final String format = message.getFormat(); - if (!FORMATS[0].equalsIgnoreCase(format)) { - return false; - } - - // Write the formatted message - final String messageJson = message.getFormattedMessage(); - jsonWriter.writeRawString(messageJson); - return true; - } - private static boolean writeMultiformatMessage(final JsonWriter jsonWriter, final Message message) { // Check type. diff --git a/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/nogc/NoGcMessage.java b/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/nogc/NoGcMessage.java index 4631b38766..572213e33d 100644 --- a/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/nogc/NoGcMessage.java +++ b/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/nogc/NoGcMessage.java @@ -87,11 +87,6 @@ public class NoGcMessage implements Message { return getState().buffer.toString(); // not called by NoGcLayout } - @Override - public String getFormat() { - return null; - } - @Override public Object[] getParameters() { return getState().getParamsCopy(); diff --git a/src/changelog/.2.x.x/fix-MessageResolver-getFormat-handling.xml b/src/changelog/.2.x.x/deprecate-Message-getFormat.xml similarity index 62% rename from src/changelog/.2.x.x/fix-MessageResolver-getFormat-handling.xml rename to src/changelog/.2.x.x/deprecate-Message-getFormat.xml index a788c1b46a..ec3bff91a8 100644 --- a/src/changelog/.2.x.x/fix-MessageResolver-getFormat-handling.xml +++ b/src/changelog/.2.x.x/deprecate-Message-getFormat.xml @@ -2,6 +2,6 @@ <entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://logging.apache.org/xml/ns" xsi:schemaLocation="https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd" - type="fixed"> - <description format="asciidoc">Fix handling of `Message#getFormat()` in `MessageResolver` of `JsonTemplateLayout`</description> + type="deprecated"> + <description format="asciidoc">Deprecate `Message#getFormat()` due to unclear semantics and inconsistent implementations</description> </entry> diff --git a/src/site/antora/modules/ROOT/pages/manual/messages.adoc b/src/site/antora/modules/ROOT/pages/manual/messages.adoc index f88ad4a1e9..eb143526ec 100644 --- a/src/site/antora/modules/ROOT/pages/manual/messages.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/messages.adoc @@ -288,11 +288,9 @@ include::example$manual/messages/CustomMessageExample.java[tag=loginFailure] [#format-type] === Format type -The link:../javadoc/log4j-api/org/apache/logging/log4j/message/Message.html[`Message`] interface supports the notion of _format_ (e.g., JSON, XML) through its `getFormat()` method of return type `String`. +You can extend from <<MultiformatMessage>> (and optionally from <<MultiFormatStringBuilderFormattable>>) to implement messages that can format themselves in one or more encodings; JSON, XML, etc. Layouts leverage this mechanism to encode a message in a particular format. -For instance, when xref:manual/json-template-layout.adoc[] figures out that `getFormat()` of a `Message` returns `JSON`, it injects the `Message#getFormattedMessage()` output as is without quoting it. -This way a message implementation can communicate its support for a particular encoding. -If you want to support multiple formats, extend from <<MultiformatMessage>>, and optionally from <<MultiFormatStringBuilderFormattable>>, instead. +For instance, when xref:manual/json-template-layout.adoc[] figures out that the array returned by `getFormats()` of a `MultiformatMessage` contains `JSON`, it injects the `MultiformatMessage#getFormattedMessage({"JSON"})` output as is without quoting it. [#marker-interfaces] === Marker interfaces
