You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2023/11/03 18:53:12 UTC

(logging-log4j2) branch main updated (0341c108b4 -> 4020b013a3)

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

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


    from 0341c108b4 Removed unused `FastDateParser` (LOG4J2-3672, #1848)
     new 61548e477f Avoid using DefaultLogEventFactory::newInstance
     new 4020b013a3 Clean up DI usage and PatternParser

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../java/org/apache/logging/log4j/LogManager.java  |  2 +-
 .../core/appender/OutputStreamAppenderTest.java    | 11 +++-
 .../log4j/core/appender/WriterAppenderTest.java    |  8 ++-
 .../log4j/core/pattern/PatternParserTest.java      |  2 +-
 .../apache/logging/log4j/core/LoggerContext.java   |  7 ++-
 .../apache/logging/log4j/core/StringLayout.java    | 15 +----
 .../log4j/core/appender/AbstractAppender.java      | 18 +++---
 .../log4j/core/appender/ConsoleAppender.java       | 13 +----
 .../log4j/core/appender/OutputStreamAppender.java  | 67 ++++++----------------
 .../log4j/core/appender/WriterAppender.java        | 46 +--------------
 .../appender/rolling/DefaultRolloverStrategy.java  |  9 ++-
 .../core/appender/rolling/PatternProcessor.java    | 15 ++---
 .../log4j/core/config/NullConfiguration.java       |  7 ++-
 .../log4j/core/filter/AbstractFilterable.java      | 11 ++--
 .../logging/log4j/core/layout/AbstractLayout.java  | 21 +++----
 .../log4j/core/layout/AbstractStringLayout.java    | 37 +++++-------
 .../logging/log4j/core/layout/PatternLayout.java   | 15 +++--
 .../logging/log4j/core/pattern/PatternParser.java  | 44 ++++++--------
 .../core/selector/ClassLoaderContextSelector.java  |  5 +-
 .../logging/log4j/smtp/appender/SmtpAppender.java  | 63 +-------------------
 .../log4j/web/appender/ServletAppender.java        | 40 ++-----------
 .../logging/log4j/smtp/appender/SmtpAppender.java  | 61 --------------------
 .../log4j/web/appender/ServletAppender.java        | 12 +---
 23 files changed, 129 insertions(+), 400 deletions(-)


(logging-log4j2) 02/02: Clean up DI usage and PatternParser

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 4020b013a385c99c0b419cd370ee3d89d82b68da
Author: Matt Sicker <ma...@apache.org>
AuthorDate: Fri Nov 3 13:51:49 2023 -0500

    Clean up DI usage and PatternParser
---
 .../java/org/apache/logging/log4j/LogManager.java  |  2 +-
 .../core/appender/OutputStreamAppenderTest.java    | 11 +++-
 .../log4j/core/appender/WriterAppenderTest.java    |  8 ++-
 .../log4j/core/pattern/PatternParserTest.java      |  2 +-
 .../apache/logging/log4j/core/LoggerContext.java   |  7 ++-
 .../apache/logging/log4j/core/StringLayout.java    | 15 +----
 .../log4j/core/appender/AbstractAppender.java      | 18 +++---
 .../log4j/core/appender/ConsoleAppender.java       | 13 +----
 .../log4j/core/appender/OutputStreamAppender.java  | 67 ++++++----------------
 .../log4j/core/appender/WriterAppender.java        | 46 +--------------
 .../appender/rolling/DefaultRolloverStrategy.java  |  9 ++-
 .../core/appender/rolling/PatternProcessor.java    | 15 ++---
 .../log4j/core/config/NullConfiguration.java       |  7 ++-
 .../log4j/core/filter/AbstractFilterable.java      | 11 ++--
 .../logging/log4j/core/layout/AbstractLayout.java  | 21 +++----
 .../log4j/core/layout/AbstractStringLayout.java    | 16 ++----
 .../logging/log4j/core/layout/PatternLayout.java   | 15 +++--
 .../logging/log4j/core/pattern/PatternParser.java  | 44 ++++++--------
 .../core/selector/ClassLoaderContextSelector.java  |  5 +-
 .../logging/log4j/smtp/appender/SmtpAppender.java  | 63 +-------------------
 .../log4j/web/appender/ServletAppender.java        | 40 ++-----------
 .../logging/log4j/smtp/appender/SmtpAppender.java  | 61 --------------------
 .../log4j/web/appender/ServletAppender.java        | 12 +---
 23 files changed, 119 insertions(+), 389 deletions(-)

diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/LogManager.java b/log4j-api/src/main/java/org/apache/logging/log4j/LogManager.java
index 501e58d3e9..d528e95d2f 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/LogManager.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/LogManager.java
@@ -41,7 +41,7 @@ import org.apache.logging.log4j.util.Strings;
 public class LogManager {
 
     /**
-     * The name of the root Logger is {@value #ROOT_LOGGER_NAME}.
+     * Constant holding the name of the root logger (the empty string).
      */
     public static final String ROOT_LOGGER_NAME = Strings.EMPTY;
 
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamAppenderTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamAppenderTest.java
index 41b01e2d38..901932b3df 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamAppenderTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamAppenderTest.java
@@ -53,7 +53,12 @@ public class OutputStreamAppenderTest {
         final LoggerContext context = LoggerContext.getContext(false);
         final Configuration config = context.getConfiguration();
         final PatternLayout layout = PatternLayout.createDefaultLayout(config);
-        final Appender appender = OutputStreamAppender.createAppender(layout, null, outputStream, outputStreamName, false, true);
+        final OutputStreamAppender appender = OutputStreamAppender.newBuilder()
+                .setLayout(layout)
+                .setConfiguration(config)
+                .setTarget(outputStream)
+                .setName(outputStreamName)
+                .build();
         appender.start();
         config.addAppender(appender);
         ConfigurationTestUtils.updateLoggers(appender, config);
@@ -63,7 +68,7 @@ public class OutputStreamAppenderTest {
     public void testBuildFilter() {
         final NoMarkerFilter filter = NoMarkerFilter.newBuilder().build();
         // @formatter:off
-        final OutputStreamAppender.Builder builder = OutputStreamAppender.newBuilder()
+        final var builder = OutputStreamAppender.newBuilder()
                 .setName("test")
                 .setFilter(filter);
         // @formatter:on
@@ -102,7 +107,7 @@ public class OutputStreamAppenderTest {
      */
     @Test
     public void testUpdatePatternWithFileAppender() {
-        final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
+        final LoggerContext ctx = LoggerContext.getContext(false);
         final Configuration config = ctx.getConfiguration();
         // @formatter:off
         final Appender appender = FileAppender.newBuilder()
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/WriterAppenderTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/WriterAppenderTest.java
index 0136e43920..d04ca062b2 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/WriterAppenderTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/WriterAppenderTest.java
@@ -26,7 +26,6 @@ import java.lang.reflect.Method;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.Appender;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.layout.PatternLayout;
@@ -77,7 +76,12 @@ public class WriterAppenderTest {
         final LoggerContext context = LoggerContext.getContext(false);
         final Configuration config = context.getConfiguration();
         final PatternLayout layout = PatternLayout.createDefaultLayout(config);
-        final Appender appender = WriterAppender.createAppender(layout, null, writer, writerName, false, true);
+        final WriterAppender appender = WriterAppender.newBuilder()
+                .setLayout(layout)
+                .setConfiguration(config)
+                .setTarget(writer)
+                .setName(writerName)
+                .build();
         appender.start();
         config.addAppender(appender);
         ConfigurationTestUtils.updateLoggers(appender, config);
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/PatternParserTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/PatternParserTest.java
index f606ef883d..38a3a5884e 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/PatternParserTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/PatternParserTest.java
@@ -66,7 +66,7 @@ public class PatternParserTest {
 
     @BeforeEach
     public void setup() {
-        parser = new PatternParser(KEY);
+        parser = new PatternParser(ctx.getConfiguration(), KEY, null);
     }
 
     private void validateConverter(final List<PatternFormatter> formatter, final int index, final String name) {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
index 97761befb5..03284e641e 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
@@ -74,8 +74,6 @@ public class LoggerContext extends AbstractLifeCycle
 
     public static final Key<LoggerContext> KEY = Key.forClass(LoggerContext.class);
 
-    private static final Configuration NULL_CONFIGURATION = new NullConfiguration();
-
     private final LoggerRegistry<Logger> loggerRegistry = new LoggerRegistry<>();
     private final List<Consumer<Configuration>> configurationStartedListeners = new ArrayList<>();
     private final List<Consumer<Configuration>> configurationStoppedListeners = new ArrayList<>();
@@ -88,6 +86,7 @@ public class LoggerContext extends AbstractLifeCycle
      * reference is updated.
      */
     private volatile Configuration configuration = new DefaultConfiguration();
+    private final Configuration nullConfiguration;
     private static final String EXTERNAL_CONTEXT_KEY = "__EXTERNAL_CONTEXT_KEY__";
     private final ConcurrentMap<String, Object> externalMap = new ConcurrentHashMap<>();
     private String contextName;
@@ -143,6 +142,7 @@ public class LoggerContext extends AbstractLifeCycle
         this.configLocation = configLocn;
         this.instanceFactory = instanceFactory.newChildInstanceFactory();
         initializeInstanceFactory();
+        this.nullConfiguration = new NullConfiguration(this);
     }
 
     /**
@@ -185,6 +185,7 @@ public class LoggerContext extends AbstractLifeCycle
         }
         this.instanceFactory = instanceFactory.newChildInstanceFactory();
         initializeInstanceFactory();
+        this.nullConfiguration = new NullConfiguration(this);
     }
 
     private void initializeInstanceFactory() {
@@ -421,7 +422,7 @@ public class LoggerContext extends AbstractLifeCycle
                 shutdownCallback = null;
             }
             final Configuration prev = configuration;
-            configuration = NULL_CONFIGURATION;
+            configuration = nullConfiguration;
             updateLoggers();
             prev.stop(timeout, timeUnit);
             externalMap.clear();
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/StringLayout.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/StringLayout.java
index 33e305d873..42dd383b8a 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/StringLayout.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/StringLayout.java
@@ -16,18 +16,7 @@
  */
 package org.apache.logging.log4j.core;
 
-import java.nio.charset.Charset;
-
 /**
- * Instantiates the @{link Layout} type for String-based layouts.
+ * Legacy interface from when layouts used to support more than strings or bytes.
  */
-public interface StringLayout extends Layout {
-
-    /**
-     * Gets the Charset this layout uses to encode Strings into bytes.
-     *
-     * @return the Charset this layout uses to encode Strings into bytes.
-     */
-    Charset getCharset();
-
-}
+public interface StringLayout extends Layout {}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
index b057c00e0b..c30f0176b1 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
@@ -26,10 +26,11 @@ import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.Property;
-import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
 import org.apache.logging.log4j.core.filter.AbstractFilterable;
 import org.apache.logging.log4j.core.layout.PatternLayout;
 import org.apache.logging.log4j.core.util.Integers;
+import org.apache.logging.log4j.plugins.Inject;
+import org.apache.logging.log4j.plugins.PluginAttribute;
 import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
 import org.apache.logging.log4j.plugins.PluginElement;
 import org.apache.logging.log4j.plugins.validation.constraints.Required;
@@ -50,14 +51,8 @@ public abstract class AbstractAppender extends AbstractFilterable implements App
         @PluginBuilderAttribute
         private boolean ignoreExceptions = true;
 
-        @PluginElement("Layout")
         private Layout layout;
-
-        @PluginBuilderAttribute
-        @Required(message = "No appender name provided")
         private String name;
-
-        @PluginConfiguration
         private Configuration configuration;
 
         public String getName() {
@@ -72,7 +67,7 @@ public abstract class AbstractAppender extends AbstractFilterable implements App
             return layout;
         }
 
-        public B setName(final String name) {
+        public B setName(@PluginAttribute @Required(message = "No appender name provided") final String name) {
             this.name = name;
             return asBuilder();
         }
@@ -82,25 +77,26 @@ public abstract class AbstractAppender extends AbstractFilterable implements App
             return asBuilder();
         }
 
-        public B setLayout(final Layout layout) {
+        public B setLayout(@PluginElement final Layout layout) {
             this.layout = layout;
             return asBuilder();
         }
 
         public Layout getOrCreateLayout() {
             if (layout == null) {
-                return PatternLayout.createDefaultLayout();
+                return PatternLayout.createDefaultLayout(getConfiguration());
             }
             return layout;
         }
 
         public Layout getOrCreateLayout(final Charset charset) {
             if (layout == null) {
-                return PatternLayout.newBuilder().setCharset(charset).build();
+                return PatternLayout.newBuilder().setConfiguration(getConfiguration()).setCharset(charset).build();
             }
             return layout;
         }
 
+        @Inject
         public B setConfiguration(final Configuration configuration) {
             this.configuration = configuration;
             return asBuilder();
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
index ccd92a899c..528cc2a26b 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
@@ -31,7 +31,6 @@ import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.Property;
-import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
 import org.apache.logging.log4j.core.impl.Log4jPropertyKey;
 import org.apache.logging.log4j.core.util.CloseShieldOutputStream;
 import org.apache.logging.log4j.core.util.Loader;
@@ -134,8 +133,6 @@ public final class ConsoleAppender extends AbstractOutputStreamAppender<OutputSt
 
         @PluginBuilderAttribute
         private boolean direct;
-        @PluginConfiguration
-        private Configuration configuration;
 
         public B setTarget(final Target aTarget) {
             this.target = aTarget;
@@ -152,21 +149,13 @@ public final class ConsoleAppender extends AbstractOutputStreamAppender<OutputSt
             return asBuilder();
         }
 
-        /**
-         * @param configuration
-         *        The Configuration. Used to access properties.
-         */
-        public B setConfiguration(final Configuration configuration) {
-            this.configuration = configuration;
-            return asBuilder();
-        }
-
         @Override
         public ConsoleAppender build() {
             if (follow && direct) {
                 throw new IllegalArgumentException("Cannot use both follow and direct on ConsoleAppender '" + getName() + "'");
             }
             final Layout layout = getOrCreateLayout(target.getDefaultCharset());
+            final Configuration configuration = getConfiguration();
             final PropertyEnvironment propertyEnvironment = configuration != null
                     && configuration.getLoggerContext() != null
                     ? configuration.getLoggerContext().getProperties() : PropertiesUtil.getProperties();
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamAppender.java
index 9396adafad..91b79c3473 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamAppender.java
@@ -18,15 +18,10 @@ package org.apache.logging.log4j.core.appender;
 
 import java.io.OutputStream;
 
-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.config.Property;
-import org.apache.logging.log4j.core.layout.PatternLayout;
 import org.apache.logging.log4j.core.util.CloseShieldOutputStream;
-import org.apache.logging.log4j.plugins.Configurable;
-import org.apache.logging.log4j.plugins.Plugin;
-import org.apache.logging.log4j.plugins.PluginFactory;
 
 /**
  * Appends log events to a given output stream using a layout.
@@ -34,8 +29,6 @@ import org.apache.logging.log4j.plugins.PluginFactory;
  * Character encoding is handled within the Layout.
  * </p>
  */
-@Configurable(elementType = Appender.ELEMENT_TYPE, printObject = true)
-@Plugin("OutputStream")
 public final class OutputStreamAppender extends AbstractOutputStreamAppender<OutputStreamManager> {
 
     /**
@@ -44,19 +37,19 @@ public final class OutputStreamAppender extends AbstractOutputStreamAppender<Out
      * @param <B>
      *            The type to build.
      */
-    public static class Builder<B extends Builder<B>> extends AbstractOutputStreamAppender.Builder<B>
+    public static abstract class Builder<B extends Builder<B>> extends AbstractOutputStreamAppender.Builder<B>
             implements org.apache.logging.log4j.plugins.util.Builder<OutputStreamAppender> {
 
         private boolean follow = false;
 
-        private final Layout layout = PatternLayout.createDefaultLayout();
-
         private OutputStream target;
 
-        @Override
-        public OutputStreamAppender build() {
+        public boolean isFollow() {
+            return follow;
+        }
 
-            return new OutputStreamAppender(getName(), layout, getFilter(), getManager(target, follow, layout), isIgnoreExceptions(), getPropertyArray());
+        public OutputStream getTarget() {
+            return target;
         }
 
         public B setFollow(final boolean shouldFollow) {
@@ -69,6 +62,16 @@ public final class OutputStreamAppender extends AbstractOutputStreamAppender<Out
             return asBuilder();
         }
     }
+
+    public static class OutputStreamAppenderBuilder extends Builder<OutputStreamAppenderBuilder> {
+        @Override
+        public OutputStreamAppender build() {
+            final Layout layout = getOrCreateLayout();
+            final OutputStreamManager manager = getManager(getTarget(), isFollow(), layout);
+            return new OutputStreamAppender(getName(), layout, getFilter(), manager, isIgnoreExceptions(), getPropertyArray());
+        }
+    }
+
     /**
      * Holds data to pass to factory method.
      */
@@ -116,39 +119,6 @@ public final class OutputStreamAppender extends AbstractOutputStreamAppender<Out
 
     private static final OutputStreamManagerFactory factory = new OutputStreamManagerFactory();
 
-    /**
-     * Creates an OutputStream Appender.
-     *
-     * @param layout
-     *            The layout to use or null to get the default layout.
-     * @param filter
-     *            The Filter or null.
-     * @param target
-     *            an output stream.
-     * @param follow
-     *            If true will follow changes to the underlying output stream.
-     *            Use false as the default.
-     * @param name
-     *            The name of the Appender (required).
-     * @param ignore
-     *            If {@code "true"} (default) exceptions encountered when
-     *            appending events are logged; otherwise they are propagated to
-     *            the caller. Use true as the default.
-     * @return The ConsoleAppender.
-     */
-    @PluginFactory
-    public static OutputStreamAppender createAppender(Layout layout, final Filter filter,
-                                                      final OutputStream target, final String name, final boolean follow, final boolean ignore) {
-        if (name == null) {
-            LOGGER.error("No name provided for OutputStreamAppender");
-            return null;
-        }
-        if (layout == null) {
-            layout = PatternLayout.createDefaultLayout();
-        }
-        return new OutputStreamAppender(name, layout, filter, getManager(target, follow, layout), ignore, null);
-    }
-
     private static OutputStreamManager getManager(final OutputStream target, final boolean follow,
             final Layout layout) {
         final OutputStream os = target == null ? OutputStream.nullOutputStream() : new CloseShieldOutputStream(target);
@@ -158,9 +128,8 @@ public final class OutputStreamAppender extends AbstractOutputStreamAppender<Out
         return OutputStreamManager.getManager(managerName, new FactoryData(os, managerName, layout), factory);
     }
 
-    @PluginFactory
-    public static <B extends Builder<B>> B newBuilder() {
-        return new Builder<B>().asBuilder();
+    public static OutputStreamAppenderBuilder newBuilder() {
+        return new OutputStreamAppenderBuilder();
     }
 
     private OutputStreamAppender(final String name, final Layout layout, final Filter filter,
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/WriterAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/WriterAppender.java
index 7c3058d73e..cb4002043e 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/WriterAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/WriterAppender.java
@@ -18,21 +18,14 @@ package org.apache.logging.log4j.core.appender;
 
 import java.io.Writer;
 
-import org.apache.logging.log4j.core.Appender;
 import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.StringLayout;
 import org.apache.logging.log4j.core.config.Property;
-import org.apache.logging.log4j.core.layout.PatternLayout;
 import org.apache.logging.log4j.core.util.CloseShieldWriter;
-import org.apache.logging.log4j.plugins.Configurable;
-import org.apache.logging.log4j.plugins.Plugin;
-import org.apache.logging.log4j.plugins.PluginFactory;
 
 /**
  * Appends log events to a {@link Writer}.
  */
-@Configurable(elementType = Appender.ELEMENT_TYPE, printObject = true)
-@Plugin("Writer")
 public final class WriterAppender extends AbstractWriterAppender<WriterManager> {
 
     /**
@@ -47,9 +40,8 @@ public final class WriterAppender extends AbstractWriterAppender<WriterManager>
 
         @Override
         public WriterAppender build() {
-            final StringLayout layout = (StringLayout) getLayout();
-            final StringLayout actualLayout = layout != null ? layout : PatternLayout.createDefaultLayout();
-            return new WriterAppender(getName(), actualLayout, getFilter(), getManager(target, follow, actualLayout),
+            final StringLayout layout = (StringLayout) getOrCreateLayout();
+            return new WriterAppender(getName(), layout, getFilter(), getManager(target, follow, layout),
                     isIgnoreExceptions(), getPropertyArray());
         }
 
@@ -107,39 +99,6 @@ public final class WriterAppender extends AbstractWriterAppender<WriterManager>
 
     private static final WriterManagerFactory factory = new WriterManagerFactory();
 
-    /**
-     * Creates a WriterAppender.
-     *
-     * @param layout
-     *            The layout to use or null to get the default layout.
-     * @param filter
-     *            The Filter or null.
-     * @param target
-     *            The target Writer
-     * @param follow
-     *            If true will follow changes to the underlying output stream.
-     *            Use false as the default.
-     * @param name
-     *            The name of the Appender (required).
-     * @param ignore
-     *            If {@code "true"} (default) exceptions encountered when
-     *            appending events are logged; otherwise they are propagated to
-     *            the caller. Use true as the default.
-     * @return The ConsoleAppender.
-     */
-    @PluginFactory
-    public static WriterAppender createAppender(StringLayout layout, final Filter filter, final Writer target,
-            final String name, final boolean follow, final boolean ignore) {
-        if (name == null) {
-            LOGGER.error("No name provided for WriterAppender");
-            return null;
-        }
-        if (layout == null) {
-            layout = PatternLayout.createDefaultLayout();
-        }
-        return new WriterAppender(name, layout, filter, getManager(target, follow, layout), ignore, Property.EMPTY_ARRAY);
-    }
-
     private static WriterManager getManager(final Writer target, final boolean follow, final StringLayout layout) {
         final Writer writer = new CloseShieldWriter(target);
         final String managerName = target.getClass().getName() + "@" + Integer.toHexString(target.hashCode()) + '.'
@@ -147,7 +106,6 @@ public final class WriterAppender extends AbstractWriterAppender<WriterManager>
         return WriterManager.getManager(managerName, new FactoryData(writer, managerName, layout), factory);
     }
 
-    @PluginFactory
     public static <B extends Builder<B>> B newBuilder() {
         return new Builder<B>().asBuilder();
     }
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java
index cb64ea0e52..93021eab68 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java
@@ -34,6 +34,7 @@ import org.apache.logging.log4j.core.appender.rolling.action.FileRenameAction;
 import org.apache.logging.log4j.core.appender.rolling.action.PathCondition;
 import org.apache.logging.log4j.core.appender.rolling.action.PosixViewAttributeAction;
 import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.NullConfiguration;
 import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
 import org.apache.logging.log4j.core.lookup.StrSubstitutor;
 import org.apache.logging.log4j.core.util.Integers;
@@ -143,9 +144,10 @@ public class DefaultRolloverStrategy extends AbstractRolloverStrategy {
             final String trimmedCompressionLevelStr = compressionLevelStr != null ? compressionLevelStr.trim() : compressionLevelStr;
             final int compressionLevel = Integers.parseInt(trimmedCompressionLevelStr, Deflater.DEFAULT_COMPRESSION);
             // The config object can be null when this object is built programmatically.
-            final StrSubstitutor nonNullStrSubstitutor = config != null ? config.getStrSubstitutor() : new StrSubstitutor();
+            final Configuration configuration = config != null ? config : new NullConfiguration();
+            final StrSubstitutor nonNullStrSubstitutor = configuration.getStrSubstitutor();
             return new DefaultRolloverStrategy(minIndex, maxIndex, useMax, compressionLevel, nonNullStrSubstitutor,
-                    customActions, stopCustomActionsOnError, tempCompressedFilePattern);
+                    customActions, stopCustomActionsOnError, tempCompressedFilePattern, configuration);
         }
 
         public String getMax() {
@@ -302,7 +304,8 @@ public class DefaultRolloverStrategy extends AbstractRolloverStrategy {
      */
     protected DefaultRolloverStrategy(final int minIndex, final int maxIndex, final boolean useMax,
             final int compressionLevel, final StrSubstitutor strSubstitutor, final Action[] customActions,
-            final boolean stopCustomActionsOnError, final String tempCompressedFilePatternString) {
+            final boolean stopCustomActionsOnError, final String tempCompressedFilePatternString,
+            final Configuration configuration) {
         super(strSubstitutor);
         this.minIndex = minIndex;
         this.maxIndex = maxIndex;
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java
index 9c83f46e5b..4941a40eb5 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java
@@ -80,14 +80,14 @@ public class PatternProcessor {
      */
     public PatternProcessor(final String pattern) {
         this.pattern = pattern;
-        final PatternParser parser = createPatternParser();
-        // FIXME: this seems to expect List<ArrayPatternConverter> in practice; types need to be fixed around this
+        final PatternParser parser = new PatternParser(null, KEY, ArrayPatternConverter.class);
         final List<PatternConverter> converters = new ArrayList<>();
         final List<FormattingInfo> fields = new ArrayList<>();
         parser.parse(pattern, converters, fields, false, false, false);
-        patternFields = fields.toArray(FormattingInfo.EMPTY_ARRAY);
-        final ArrayPatternConverter[] converterArray = new ArrayPatternConverter[converters.size()];
-        patternConverters = converters.toArray(converterArray);
+        patternFields = fields.toArray(FormattingInfo[]::new);
+        patternConverters = converters.stream()
+                .map(ArrayPatternConverter.class::cast)
+                .toArray(ArrayPatternConverter[]::new);
         this.fileExtension = FileExtension.lookupForFile(pattern);
 
         for (final ArrayPatternConverter converter : patternConverters) {
@@ -352,11 +352,6 @@ public class PatternProcessor {
         return null;
     }
 
-    private PatternParser createPatternParser() {
-
-        return new PatternParser(null, KEY, null);
-    }
-
     private boolean patternContains(final String pattern, final char... chars) {
         for (final char character : chars) {
             if (patternContains(pattern, character)) {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/NullConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/NullConfiguration.java
index c150a13ef4..3384b42fd6 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/NullConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/NullConfiguration.java
@@ -17,6 +17,7 @@
 package org.apache.logging.log4j.core.config;
 
 import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.LoggerContext;
 
 /**
  * This configuration defaults to no logging.
@@ -29,11 +30,13 @@ public class NullConfiguration extends AbstractConfiguration {
     public static final String NULL_NAME = "Null";
 
     public NullConfiguration() {
-        super(null, ConfigurationSource.NULL_SOURCE);
+        this(null);
+    }
 
+    public NullConfiguration(final LoggerContext loggerContext) {
+        super(loggerContext, ConfigurationSource.NULL_SOURCE);
         setName(NULL_NAME);
         final LoggerConfig root = getRootLogger();
         root.setLevel(Level.OFF);
     }
-
 }
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/AbstractFilterable.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/AbstractFilterable.java
index 6c5f91df1b..0c007bf7ca 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/AbstractFilterable.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/AbstractFilterable.java
@@ -25,6 +25,7 @@ import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.Property;
 import org.apache.logging.log4j.plugins.PluginElement;
+import org.apache.logging.log4j.util.Cast;
 
 /**
  * Enhances a Class by allowing it to contain Filters.
@@ -38,15 +39,11 @@ public abstract class AbstractFilterable extends AbstractLifeCycle implements Fi
      */
     public abstract static class Builder<B extends Builder<B>> {
 
-        @PluginElement("Filter")
         private Filter filter;
-
-        @PluginElement("Properties")
         private Property[] propertyArray;
 
-        @SuppressWarnings("unchecked")
         public B asBuilder() {
-            return (B) this;
+            return Cast.cast(this);
         }
 
         public Filter getFilter() {
@@ -57,12 +54,12 @@ public abstract class AbstractFilterable extends AbstractLifeCycle implements Fi
             return propertyArray;
         }
 
-        public B setFilter(final Filter filter) {
+        public B setFilter(@PluginElement final Filter filter) {
             this.filter = filter;
             return asBuilder();
         }
 
-        public B setPropertyArray(final Property[] properties) {
+        public B setPropertyArray(@PluginElement final Property... properties) {
             this.propertyArray = properties;
             return asBuilder();
         }
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractLayout.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractLayout.java
index 51268573b1..6871137bc7 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractLayout.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractLayout.java
@@ -16,22 +16,21 @@
  */
 package org.apache.logging.log4j.core.layout;
 
-import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.StringLayout;
 import org.apache.logging.log4j.core.config.Configuration;
-import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
-import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
+import org.apache.logging.log4j.plugins.Inject;
+import org.apache.logging.log4j.plugins.PluginAttribute;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.util.Cast;
 
 /**
  * Abstract base class for Layouts.
  */
-public abstract class AbstractLayout implements Layout {
+public abstract class AbstractLayout implements StringLayout {
 
     /**
      * Subclasses can extend this abstract Builder.
@@ -40,13 +39,8 @@ public abstract class AbstractLayout implements Layout {
      */
     public abstract static class Builder<B extends Builder<B>> {
 
-        @PluginConfiguration
         private Configuration configuration;
-
-        @PluginBuilderAttribute
         private byte[] footer;
-
-        @PluginBuilderAttribute
         private byte[] header;
 
         public B asBuilder() {
@@ -65,17 +59,18 @@ public abstract class AbstractLayout implements Layout {
             return header;
         }
 
+        @Inject
         public B setConfiguration(final Configuration configuration) {
             this.configuration = configuration;
             return asBuilder();
         }
 
-        public B setFooter(final byte[] footer) {
+        public B setFooter(@PluginAttribute final byte[] footer) {
             this.footer = footer;
             return asBuilder();
         }
 
-        public B setHeader(final byte[] header) {
+        public B setHeader(@PluginAttribute final byte[] header) {
             this.header = header;
             return asBuilder();
         }
@@ -130,7 +125,7 @@ public abstract class AbstractLayout implements Layout {
 
     @Override
     public Map<String, String> getContentFormat() {
-        return new HashMap<>();
+        return Map.of();
     }
 
     /**
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractStringLayout.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractStringLayout.java
index 68c0b4eeb4..39064163a7 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractStringLayout.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractStringLayout.java
@@ -20,14 +20,13 @@ import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 
 import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.StringLayout;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.LoggerConfig;
 import org.apache.logging.log4j.core.impl.Log4jPropertyKey;
 import org.apache.logging.log4j.core.impl.LogEventFactory;
 import org.apache.logging.log4j.core.util.Constants;
 import org.apache.logging.log4j.core.util.StringEncoder;
-import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
+import org.apache.logging.log4j.plugins.PluginAttribute;
 import org.apache.logging.log4j.plugins.PluginElement;
 import org.apache.logging.log4j.spi.AbstractLogger;
 import org.apache.logging.log4j.util.PropertiesUtil;
@@ -41,17 +40,12 @@ import org.apache.logging.log4j.util.StringBuilders;
  * performance: all characters are simply cast to bytes.
  * </p>
  */
-public abstract class AbstractStringLayout extends AbstractLayout implements StringLayout {
+public abstract class AbstractStringLayout extends AbstractLayout {
 
     public abstract static class Builder<B extends Builder<B>> extends AbstractLayout.Builder<B> {
 
-        @PluginBuilderAttribute(value = "charset")
         private Charset charset;
-
-        @PluginElement("footerSerializer")
         private Serializer footerSerializer;
-
-        @PluginElement("headerSerializer")
         private Serializer headerSerializer;
 
         public Charset getCharset() {
@@ -66,17 +60,17 @@ public abstract class AbstractStringLayout extends AbstractLayout implements Str
             return headerSerializer;
         }
 
-        public B setCharset(final Charset charset) {
+        public B setCharset(@PluginAttribute final Charset charset) {
             this.charset = charset;
             return asBuilder();
         }
 
-        public B setFooterSerializer(final Serializer footerSerializer) {
+        public B setFooterSerializer(@PluginElement final Serializer footerSerializer) {
             this.footerSerializer = footerSerializer;
             return asBuilder();
         }
 
-        public B setHeaderSerializer(final Serializer headerSerializer) {
+        public B setHeaderSerializer(@PluginElement final Serializer headerSerializer) {
             this.headerSerializer = headerSerializer;
             return asBuilder();
         }
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
index 75af30f258..8f97c5c0cb 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
@@ -18,7 +18,6 @@ package org.apache.logging.log4j.core.layout;
 
 import java.nio.charset.Charset;
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -94,7 +93,7 @@ public final class PatternLayout extends AbstractStringLayout {
      * @param eventPattern conversion pattern.
      * @param patternSelector The PatternSelector.
      * @param charset The character set.
-     * @param alwaysWriteExceptions Whether or not exceptions should always be handled in this pattern (if {@code true},
+     * @param alwaysWriteExceptions Whether exceptions should always be handled in this pattern (if {@code true},
      *                         exceptions will be written even if the pattern does not specify so).
      * @param disableAnsi
      *            If {@code "true"}, do not output ANSI escape codes
@@ -170,11 +169,11 @@ public final class PatternLayout extends AbstractStringLayout {
      */
     @Override
     public Map<String, String> getContentFormat() {
-        final Map<String, String> result = new HashMap<>();
-        result.put("structured", "false");
-        result.put("formatType", "conversion");
-        result.put("format", conversionPattern);
-        return result;
+        return Map.of(
+                "structured", "false",
+                "formatType", "conversion",
+                "format", conversionPattern
+        );
     }
 
     /**
@@ -219,7 +218,7 @@ public final class PatternLayout extends AbstractStringLayout {
      */
     public static PatternParser createPatternParser(final Configuration config) {
         if (config == null) {
-            return new PatternParser(config, KEY, LogEventPatternConverter.class);
+            return new PatternParser(null, KEY, LogEventPatternConverter.class);
         }
         PatternParser parser = config.getComponent(KEY);
         if (parser == null) {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/PatternParser.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/PatternParser.java
index a47ad7296d..1a1bf87eae 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/PatternParser.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/PatternParser.java
@@ -27,8 +27,8 @@ import java.util.Objects;
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.NullConfiguration;
 import org.apache.logging.log4j.core.time.SystemNanoClock;
-import org.apache.logging.log4j.plugins.di.DI;
 import org.apache.logging.log4j.plugins.di.Key;
 import org.apache.logging.log4j.plugins.model.PluginNamespace;
 import org.apache.logging.log4j.plugins.model.PluginType;
@@ -93,23 +93,13 @@ public final class PatternParser {
 
     private final Map<String, Class<? extends PatternConverter>> converterRules;
 
-    /**
-     * Constructor.
-     *
-     * @param converterKey
-     *            The type of converters that will be used.
-     */
-    public PatternParser(final String converterKey) {
-        this(null, converterKey, null, null);
-    }
-
     /**
      * Constructor.
      *
      * @param config
      *            The current Configuration.
      * @param converterKey
-     *            The key to lookup the converters.
+     *            The key to look up the converters.
      * @param expected
      *            The expected base Class of each Converter.
      */
@@ -120,36 +110,38 @@ public final class PatternParser {
     /**
      * Constructor.
      *
-     * @param config
+     * @param configuration
      *            The current Configuration.
      * @param converterKey
-     *            The key to lookup the converters.
+     *            The key to look up the converters.
      * @param expectedClass
      *            The expected base Class of each Converter.
      * @param filterClass
      *            Filter the returned plugins after calling the plugin manager.
      */
-    public PatternParser(final Configuration config, final String converterKey, final Class<?> expectedClass,
+    public PatternParser(
+            final Configuration configuration,
+            final String converterKey,
+            final Class<?> expectedClass,
             final Class<?> filterClass) {
-        this.config = config;
-        final PluginNamespace plugins;
+        config = configuration != null ? configuration : new NullConfiguration();
         final Key<PluginNamespace> pluginCategoryKey = PLUGIN_CATEGORY_KEY.withNamespace(converterKey);
-        if (config == null) {
-            plugins = DI.createInitializedFactory().getInstance(pluginCategoryKey);
-        } else {
-            plugins = config.getComponent(pluginCategoryKey);
-        }
+        final PluginNamespace plugins = config.getComponent(pluginCategoryKey);
 
         final Map<String, Class<? extends PatternConverter>> converters = new LinkedHashMap<>();
 
         for (final PluginType<?> type : plugins) {
             try {
-                final Class<? extends PatternConverter> clazz = type.getPluginClass().asSubclass(PatternConverter.class);
-                if (filterClass != null && !filterClass.isAssignableFrom(clazz)) {
+                final Class<?> pluginClass = type.getPluginClass();
+                if (expectedClass != null && !expectedClass.isAssignableFrom(pluginClass)) {
+                    continue;
+                }
+                if (filterClass != null && !filterClass.isAssignableFrom(pluginClass)) {
                     continue;
                 }
-                final ConverterKeys keys = clazz.getAnnotation(ConverterKeys.class);
+                final ConverterKeys keys = pluginClass.getAnnotation(ConverterKeys.class);
                 if (keys != null) {
+                    final Class<? extends PatternConverter> clazz = pluginClass.asSubclass(PatternConverter.class);
                     for (final String key : keys.value()) {
                         if (converters.containsKey(key)) {
                             LOGGER.warn("Converter key '{}' is already mapped to '{}'. " +
@@ -161,7 +153,7 @@ public final class PatternParser {
                     }
                 }
             } catch (final Exception ex) {
-                LOGGER.error("Error processing plugin " + type.getElementType(), ex);
+                LOGGER.error("Error processing plugin {}", type.getElementType(), ex);
             }
         }
         converterRules = converters;
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/ClassLoaderContextSelector.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/ClassLoaderContextSelector.java
index b8b2ea0865..1a7f4cabad 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/ClassLoaderContextSelector.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/ClassLoaderContextSelector.java
@@ -195,8 +195,7 @@ public class ClassLoaderContextSelector implements ContextSelector, LoggerContex
                 return (ConfigurableInstanceFactory) value;
             }
         }
-        final ConfigurableInstanceFactory instanceFactory = this.instanceFactory;
-        return instanceFactory != null ? instanceFactory.newChildInstanceFactory() : null;
+        return instanceFactory;
     }
 
     private LoggerContext locateContext(
@@ -278,7 +277,7 @@ public class ClassLoaderContextSelector implements ContextSelector, LoggerContex
 
     protected LoggerContext createContext(final String name, final URI configLocation) {
         final ConfigurableInstanceFactory instanceFactory = this.instanceFactory;
-        return createContext(name, configLocation, instanceFactory != null ? instanceFactory.newChildInstanceFactory() : null);
+        return createContext(name, configLocation, instanceFactory);
     }
 
     protected LoggerContext createContext(final String name, final URI configLocation, final ConfigurableInstanceFactory instanceFactory) {
diff --git a/log4j-jakarta-smtp/src/main/java/org/apache/logging/log4j/smtp/appender/SmtpAppender.java b/log4j-jakarta-smtp/src/main/java/org/apache/logging/log4j/smtp/appender/SmtpAppender.java
index 5b6e90f79c..559269cd8d 100644
--- a/log4j-jakarta-smtp/src/main/java/org/apache/logging/log4j/smtp/appender/SmtpAppender.java
+++ b/log4j-jakarta-smtp/src/main/java/org/apache/logging/log4j/smtp/appender/SmtpAppender.java
@@ -21,13 +21,10 @@ 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.appender.AbstractAppender;
-import org.apache.logging.log4j.core.config.Configuration;
-import org.apache.logging.log4j.core.config.DefaultConfiguration;
 import org.apache.logging.log4j.core.config.Property;
 import org.apache.logging.log4j.core.filter.ThresholdFilter;
 import org.apache.logging.log4j.core.layout.HtmlLayout;
 import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
-import org.apache.logging.log4j.core.util.Booleans;
 import org.apache.logging.log4j.plugins.Configurable;
 import org.apache.logging.log4j.plugins.Plugin;
 import org.apache.logging.log4j.plugins.PluginAttribute;
@@ -46,7 +43,7 @@ import org.apache.logging.log4j.plugins.validation.constraints.ValidPort;
  * memory requirements at a reasonable level while still delivering useful
  * application context.
  *
- * By default, an email message will formatted as HTML. This can be modified by
+ * By default, an email message will be formatted as HTML. This can be modified by
  * setting a layout for the appender.
  *
  * By default, an email message will be sent when an ERROR or higher severity
@@ -229,24 +226,6 @@ public final class SmtpAppender extends AbstractAppender {
             return this;
         }
 
-        /**
-         * Specifies the layout used for the email message body. By default, this uses the
-         * {@linkplain HtmlLayout#createDefaultLayout() default HTML layout}.
-         */
-        @Override
-        public Builder setLayout(final Layout layout) {
-            return super.setLayout(layout);
-        }
-
-        /**
-         * Specifies the filter used for this appender. By default, uses a {@link ThresholdFilter} with a level of
-         * ERROR.
-         */
-        @Override
-        public Builder setFilter(final Filter filter) {
-            return super.setFilter(filter);
-        }
-
         @Override
         public SmtpAppender build() {
             if (getLayout() == null) {
@@ -270,46 +249,6 @@ public final class SmtpAppender extends AbstractAppender {
         return new Builder();
     }
 
-    /**
-     * Create a SmtpAppender.
-     * @deprecated Use {@link #newBuilder()} to create and configure a {@link Builder} instance.
-     * @see Builder
-     */
-    public static SmtpAppender createAppender(final Configuration config, final String name, final String to,
-                                              final String cc, final String bcc, final String from,
-                                              final String replyTo, final String subject, final String smtpProtocol,
-                                              final String smtpHost, final String smtpPortStr,
-                                              final String smtpUsername, final String smtpPassword,
-                                              final String smtpDebug, final String bufferSizeStr,
-                                              Layout layout, Filter filter,
-                                              final String ignore) {
-        if (name == null) {
-            LOGGER.error("No name provided for SmtpAppender");
-            return null;
-        }
-
-        final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
-        final int smtpPort = AbstractAppender.parseInt(smtpPortStr, 0);
-        final boolean isSmtpDebug = Boolean.parseBoolean(smtpDebug);
-        final int bufferSize = bufferSizeStr == null ? DEFAULT_BUFFER_SIZE : Integer.parseInt(bufferSizeStr);
-
-        if (layout == null) {
-            layout = HtmlLayout.createDefaultLayout();
-        }
-        if (filter == null) {
-            filter = ThresholdFilter.createFilter(null, null, null);
-        }
-        final Configuration configuration = config != null ? config : new DefaultConfiguration();
-
-        final SmtpManager manager = SmtpManager.getSmtpManager(configuration, to, cc, bcc, from, replyTo, subject, smtpProtocol,
-            smtpHost, smtpPort, smtpUsername, smtpPassword, isSmtpDebug, filter.toString(),  bufferSize, null);
-        if (manager == null) {
-            return null;
-        }
-
-        return new SmtpAppender(name, filter, layout, ignoreExceptions, Property.EMPTY_ARRAY, manager);
-    }
-
     /**
      * Capture all events in CyclicBuffer.
      * @param event The Log event.
diff --git a/log4j-jakarta-web/src/main/java/org/apache/logging/log4j/web/appender/ServletAppender.java b/log4j-jakarta-web/src/main/java/org/apache/logging/log4j/web/appender/ServletAppender.java
index 9f17ef6807..9b590f4ede 100644
--- a/log4j-jakarta-web/src/main/java/org/apache/logging/log4j/web/appender/ServletAppender.java
+++ b/log4j-jakarta-web/src/main/java/org/apache/logging/log4j/web/appender/ServletAppender.java
@@ -24,12 +24,10 @@ import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.appender.AbstractAppender;
 import org.apache.logging.log4j.core.config.Property;
-import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
-import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
-import org.apache.logging.log4j.core.layout.AbstractStringLayout;
-import org.apache.logging.log4j.core.layout.PatternLayout;
 import org.apache.logging.log4j.plugins.Configurable;
+import org.apache.logging.log4j.plugins.Factory;
 import org.apache.logging.log4j.plugins.Plugin;
+import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
 import org.apache.logging.log4j.web.WebLoggerContextUtils;
 
 /**
@@ -40,7 +38,7 @@ import org.apache.logging.log4j.web.WebLoggerContextUtils;
 public final class ServletAppender extends AbstractAppender {
 
     public static class Builder<B extends Builder<B>> extends AbstractAppender.Builder<B>
-            implements org.apache.logging.log4j.core.util.Builder<ServletAppender> {
+            implements org.apache.logging.log4j.plugins.util.Builder<ServletAppender> {
 
         @PluginBuilderAttribute
         private boolean logThrowables;
@@ -56,13 +54,7 @@ public final class ServletAppender extends AbstractAppender {
                 LOGGER.error("No servlet context is available");
                 return null;
             }
-            Layout layout = getLayout();
-            if (layout == null) {
-                layout = PatternLayout.createDefaultLayout();
-            } else if (!(layout instanceof AbstractStringLayout)) {
-                LOGGER.error("Layout must be a StringLayout to log to ServletContext");
-                return null;
-            }
+            Layout layout = getOrCreateLayout();
             return new ServletAppender(name, layout, getFilter(), servletContext, isIgnoreExceptions(), logThrowables);
         }
 
@@ -84,7 +76,7 @@ public final class ServletAppender extends AbstractAppender {
 
     }
 
-    @PluginBuilderFactory
+    @Factory
     public static <B extends Builder<B>> B newBuilder() {
         return new Builder<B>().asBuilder();
     }
@@ -101,31 +93,11 @@ public final class ServletAppender extends AbstractAppender {
 
     @Override
     public void append(final LogEvent event) {
-        final String serialized = ((AbstractStringLayout) getLayout()).toSerializable(event);
+        final String serialized = getLayout().toSerializable(event);
         if (logThrowables) {
             servletContext.log(serialized, event.getThrown());
         } else {
             servletContext.log(serialized);
         }
     }
-
-    /**
-     * Creates a Servlet Appender.
-     * @param layout The layout to use (required). Must extend {@link AbstractStringLayout}.
-     * @param filter The Filter or null.
-     * @param name The name of the Appender (required).
-     * @param ignoreExceptions If {@code true} (default) exceptions encountered when appending events are logged;
-     *                         otherwise they are propagated to the caller.
-     * @return The ServletAppender.
-     * @deprecated Use {@link #newBuilder()}.
-     */
-    @Deprecated
-    public static ServletAppender createAppender(final Layout layout, final Filter filter,
-                                                 final String name, final boolean ignoreExceptions) {
-        // @formatter:off
-        return newBuilder().setFilter(filter).setIgnoreExceptions(ignoreExceptions).setLayout(layout).setName(name)
-                .build();
-        // @formatter:on
-    }
-
 }
diff --git a/log4j-smtp/src/main/java/org/apache/logging/log4j/smtp/appender/SmtpAppender.java b/log4j-smtp/src/main/java/org/apache/logging/log4j/smtp/appender/SmtpAppender.java
index 5b6e90f79c..a96a2f8d45 100644
--- a/log4j-smtp/src/main/java/org/apache/logging/log4j/smtp/appender/SmtpAppender.java
+++ b/log4j-smtp/src/main/java/org/apache/logging/log4j/smtp/appender/SmtpAppender.java
@@ -21,13 +21,10 @@ 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.appender.AbstractAppender;
-import org.apache.logging.log4j.core.config.Configuration;
-import org.apache.logging.log4j.core.config.DefaultConfiguration;
 import org.apache.logging.log4j.core.config.Property;
 import org.apache.logging.log4j.core.filter.ThresholdFilter;
 import org.apache.logging.log4j.core.layout.HtmlLayout;
 import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
-import org.apache.logging.log4j.core.util.Booleans;
 import org.apache.logging.log4j.plugins.Configurable;
 import org.apache.logging.log4j.plugins.Plugin;
 import org.apache.logging.log4j.plugins.PluginAttribute;
@@ -229,24 +226,6 @@ public final class SmtpAppender extends AbstractAppender {
             return this;
         }
 
-        /**
-         * Specifies the layout used for the email message body. By default, this uses the
-         * {@linkplain HtmlLayout#createDefaultLayout() default HTML layout}.
-         */
-        @Override
-        public Builder setLayout(final Layout layout) {
-            return super.setLayout(layout);
-        }
-
-        /**
-         * Specifies the filter used for this appender. By default, uses a {@link ThresholdFilter} with a level of
-         * ERROR.
-         */
-        @Override
-        public Builder setFilter(final Filter filter) {
-            return super.setFilter(filter);
-        }
-
         @Override
         public SmtpAppender build() {
             if (getLayout() == null) {
@@ -270,46 +249,6 @@ public final class SmtpAppender extends AbstractAppender {
         return new Builder();
     }
 
-    /**
-     * Create a SmtpAppender.
-     * @deprecated Use {@link #newBuilder()} to create and configure a {@link Builder} instance.
-     * @see Builder
-     */
-    public static SmtpAppender createAppender(final Configuration config, final String name, final String to,
-                                              final String cc, final String bcc, final String from,
-                                              final String replyTo, final String subject, final String smtpProtocol,
-                                              final String smtpHost, final String smtpPortStr,
-                                              final String smtpUsername, final String smtpPassword,
-                                              final String smtpDebug, final String bufferSizeStr,
-                                              Layout layout, Filter filter,
-                                              final String ignore) {
-        if (name == null) {
-            LOGGER.error("No name provided for SmtpAppender");
-            return null;
-        }
-
-        final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
-        final int smtpPort = AbstractAppender.parseInt(smtpPortStr, 0);
-        final boolean isSmtpDebug = Boolean.parseBoolean(smtpDebug);
-        final int bufferSize = bufferSizeStr == null ? DEFAULT_BUFFER_SIZE : Integer.parseInt(bufferSizeStr);
-
-        if (layout == null) {
-            layout = HtmlLayout.createDefaultLayout();
-        }
-        if (filter == null) {
-            filter = ThresholdFilter.createFilter(null, null, null);
-        }
-        final Configuration configuration = config != null ? config : new DefaultConfiguration();
-
-        final SmtpManager manager = SmtpManager.getSmtpManager(configuration, to, cc, bcc, from, replyTo, subject, smtpProtocol,
-            smtpHost, smtpPort, smtpUsername, smtpPassword, isSmtpDebug, filter.toString(),  bufferSize, null);
-        if (manager == null) {
-            return null;
-        }
-
-        return new SmtpAppender(name, filter, layout, ignoreExceptions, Property.EMPTY_ARRAY, manager);
-    }
-
     /**
      * Capture all events in CyclicBuffer.
      * @param event The Log event.
diff --git a/log4j-web/src/main/java/org/apache/logging/log4j/web/appender/ServletAppender.java b/log4j-web/src/main/java/org/apache/logging/log4j/web/appender/ServletAppender.java
index 3a3a0118b3..94936469ae 100644
--- a/log4j-web/src/main/java/org/apache/logging/log4j/web/appender/ServletAppender.java
+++ b/log4j-web/src/main/java/org/apache/logging/log4j/web/appender/ServletAppender.java
@@ -24,8 +24,6 @@ import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.appender.AbstractAppender;
 import org.apache.logging.log4j.core.config.Property;
-import org.apache.logging.log4j.core.layout.AbstractStringLayout;
-import org.apache.logging.log4j.core.layout.PatternLayout;
 import org.apache.logging.log4j.plugins.Configurable;
 import org.apache.logging.log4j.plugins.Plugin;
 import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
@@ -56,13 +54,7 @@ public final class ServletAppender extends AbstractAppender {
                 LOGGER.error("No servlet context is available");
                 return null;
             }
-            Layout layout = getLayout();
-            if (layout == null) {
-                layout = PatternLayout.createDefaultLayout();
-            } else if (!(layout instanceof AbstractStringLayout)) {
-                LOGGER.error("Layout must be a StringLayout to log to ServletContext");
-                return null;
-            }
+            Layout layout = getOrCreateLayout();
             return new ServletAppender(name, layout, getFilter(), servletContext, isIgnoreExceptions(), logThrowables,
                     getPropertyArray());
         }
@@ -103,7 +95,7 @@ public final class ServletAppender extends AbstractAppender {
 
     @Override
     public void append(final LogEvent event) {
-        final String serialized = ((AbstractStringLayout) getLayout()).toSerializable(event);
+        final String serialized = getLayout().toSerializable(event);
         if (logThrowables) {
             servletContext.log(serialized, event.getThrown());
         } else {


(logging-log4j2) 01/02: Avoid using DefaultLogEventFactory::newInstance

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 61548e477f96247869d056b02c2cb050c500d96d
Author: Matt Sicker <ma...@apache.org>
AuthorDate: Thu Nov 2 17:11:58 2023 -0500

    Avoid using DefaultLogEventFactory::newInstance
    
    Signed-off-by: Matt Sicker <ma...@apache.org>
---
 .../log4j/core/layout/AbstractStringLayout.java     | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractStringLayout.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractStringLayout.java
index a9cfad761a..68c0b4eeb4 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractStringLayout.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractStringLayout.java
@@ -23,8 +23,8 @@ import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.StringLayout;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.LoggerConfig;
-import org.apache.logging.log4j.core.impl.DefaultLogEventFactory;
 import org.apache.logging.log4j.core.impl.Log4jPropertyKey;
+import org.apache.logging.log4j.core.impl.LogEventFactory;
 import org.apache.logging.log4j.core.util.Constants;
 import org.apache.logging.log4j.core.util.StringEncoder;
 import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
@@ -33,7 +33,6 @@ import org.apache.logging.log4j.spi.AbstractLogger;
 import org.apache.logging.log4j.util.PropertiesUtil;
 import org.apache.logging.log4j.util.PropertyKey;
 import org.apache.logging.log4j.util.StringBuilders;
-import org.apache.logging.log4j.util.Strings;
 
 /**
  * Abstract base class for Layouts that result in a String.
@@ -236,11 +235,6 @@ public abstract class AbstractStringLayout extends AbstractLayout implements Str
         return headerSerializer;
     }
 
-    private DefaultLogEventFactory getLogEventFactory() {
-        // TODO: inject this
-        return DefaultLogEventFactory.newInstance();
-    }
-
     /**
      * Returns a {@code Encoder<StringBuilder>} that this Layout implementation can use for encoding log events.
      *
@@ -265,10 +259,15 @@ public abstract class AbstractStringLayout extends AbstractLayout implements Str
         if (serializer == null) {
             return null;
         }
-        final LoggerConfig rootLogger = getConfiguration().getRootLogger();
-        // Using "" for the FQCN, does it matter?
-        final LogEvent logEvent = getLogEventFactory().createEvent(rootLogger.getName(), null, Strings.EMPTY,
-                rootLogger.getLevel(), null, null, null);
+        final Configuration config = getConfiguration();
+        if (config == null) {
+            return null;
+        }
+        final LoggerConfig rootLogger = config.getRootLogger();
+        final LogEventFactory logEventFactory = config.getComponent(LogEventFactory.KEY);
+        final String fqcn = getClass().getName();
+        final LogEvent logEvent = logEventFactory.createEvent(
+                rootLogger.getName(), null, fqcn, rootLogger.getLevel(), null, null, null);
         return serializer.toSerializable(logEvent);
     }