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 2022/03/31 05:49:50 UTC

[logging-log4j2] branch master updated (cfcaa13 -> 6f96c3c)

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

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


    from cfcaa13  Set 2.17.2 release date.
     new 510e090  Modernize syntax
     new 9c160a9  Use null sentinel in LazyValue
     new 4419e66  Make JmxRuntimeInputArgumentsLookup a lazy singleton
     new ceb4e8a  Lazy init of SslConfiguration
     new 5997cd8  Lazy init of escape code tables
     new 922aa12  Make LoggerContextFactory init lazier
     new 6f96c3c  Re-add Injector integration to BuilderManager

The 7 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:
 .../org/apache/log4j/builders/BuilderManager.java  |  25 ++---
 .../java/org/apache/logging/log4j/LogManager.java  | 124 ++++++++++-----------
 .../logging/log4j/spi/DefaultThreadContextMap.java |  24 ++--
 .../org/apache/logging/log4j/util/LazyValue.java   |  16 ++-
 .../lookup/MainInputArgumentsJmxLookupTest.java    |   6 +-
 .../lookup/JmxRuntimeInputArgumentsLookup.java     |  20 ++--
 .../core/net/ssl/SslConfigurationFactory.java      |  27 +++--
 .../log4j/core/pattern/HighlightConverter.java     |  57 +++++-----
 .../apache/logging/log4j/core/util/JsonUtils.java  |  18 +--
 .../layout/template/json/util/JsonWriter.java      |  19 ++--
 10 files changed, 176 insertions(+), 160 deletions(-)

[logging-log4j2] 07/07: Re-add Injector integration to BuilderManager

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

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

commit 6f96c3c8119f02d0b0c8ad12440065cfdb0c633e
Author: Matt Sicker <ma...@apache.org>
AuthorDate: Wed Mar 30 23:50:57 2022 -0500

    Re-add Injector integration to BuilderManager
    
    Signed-off-by: Matt Sicker <ma...@apache.org>
---
 .../org/apache/log4j/builders/BuilderManager.java  | 25 +++++++++-------------
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/BuilderManager.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/BuilderManager.java
index 6277afb..b524dfe 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/BuilderManager.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/BuilderManager.java
@@ -16,12 +16,6 @@
  */
 package org.apache.log4j.builders;
 
-import java.util.Locale;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Properties;
-import java.util.function.Function;
-
 import org.apache.log4j.Appender;
 import org.apache.log4j.Layout;
 import org.apache.log4j.builders.appender.AppenderBuilder;
@@ -39,9 +33,14 @@ import org.apache.logging.log4j.plugins.di.Key;
 import org.apache.logging.log4j.plugins.util.PluginManager;
 import org.apache.logging.log4j.plugins.util.PluginType;
 import org.apache.logging.log4j.status.StatusLogger;
-import org.apache.logging.log4j.util.LoaderUtil;
 import org.w3c.dom.Element;
 
+import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.function.Function;
+
 /**
  *
  */
@@ -72,7 +71,7 @@ public class BuilderManager {
             if (AbstractBuilder.class.isAssignableFrom(clazz)) {
                 return clazz.getConstructor(CONSTRUCTOR_PARAMS).newInstance(prefix, props);
             }
-            final T builder = LoaderUtil.newInstanceOf(clazz);
+            final T builder = injector.getInstance(clazz);
             // Reasonable message instead of `ClassCastException`
             if (!Builder.class.isAssignableFrom(clazz)) {
                 LOGGER.warn("Unable to load plugin: builder {} does not implement {}", clazz, Builder.class);
@@ -99,13 +98,9 @@ public class BuilderManager {
 
     private <T extends Builder<U>, U> U newInstance(final PluginType<T> plugin, final Function<T, U> consumer) {
         if (plugin != null) {
-            try {
-                final T builder = LoaderUtil.newInstanceOf(plugin.getPluginClass());
-                if (builder != null) {
-                    return consumer.apply(builder);
-                }
-            } catch (final ReflectiveOperationException ex) {
-                LOGGER.warn("Unable to load plugin: {} due to: {}", plugin.getKey(), ex.getMessage());
+            final T builder = injector.getInstance(plugin.getPluginClass());
+            if (builder != null) {
+                return consumer.apply(builder);
             }
         }
         return null;

[logging-log4j2] 03/07: Make JmxRuntimeInputArgumentsLookup a lazy singleton

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

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

commit 4419e66408cc1cb965a2df02fcbf75eb4f5c5e38
Author: Matt Sicker <ma...@apache.org>
AuthorDate: Wed Mar 30 21:53:15 2022 -0500

    Make JmxRuntimeInputArgumentsLookup a lazy singleton
    
    Signed-off-by: Matt Sicker <ma...@apache.org>
---
 .../core/lookup/MainInputArgumentsJmxLookupTest.java |  6 +++---
 .../core/lookup/JmxRuntimeInputArgumentsLookup.java  | 20 +++++++++++++-------
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java
index a3106a1..16b1a31 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java
@@ -18,7 +18,7 @@ package org.apache.logging.log4j.core.lookup;
 
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertNull;
 
 /**
  * Tests {@link JmxRuntimeInputArgumentsLookup} from the command line, not a JUnit test.
@@ -35,14 +35,14 @@ public class MainInputArgumentsJmxLookupTest {
 
     @Test
     public void testMap() {
-        final JmxRuntimeInputArgumentsLookup lookup = JmxRuntimeInputArgumentsLookup.JMX_SINGLETON;
+        final JmxRuntimeInputArgumentsLookup lookup = JmxRuntimeInputArgumentsLookup.getInstance();
         assertNull(lookup.lookup(null));
         assertNull(lookup.lookup("X"));
         assertNull(lookup.lookup("foo.txt"));
     }
 
     public void callFromMain() {
-        final JmxRuntimeInputArgumentsLookup lookup = JmxRuntimeInputArgumentsLookup.JMX_SINGLETON;
+        final JmxRuntimeInputArgumentsLookup lookup = JmxRuntimeInputArgumentsLookup.getInstance();
         assertNull(lookup.lookup(null));
         assertNull(lookup.lookup("X"));
         // Eclipse adds -Dfile.encoding=Cp1252
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java
index 2e3c5b0..3e90516 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java
@@ -16,12 +16,15 @@
  */
 package org.apache.logging.log4j.core.lookup;
 
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.plugins.Plugin;
+import org.apache.logging.log4j.plugins.PluginFactory;
+import org.apache.logging.log4j.util.LazyValue;
+
 import java.lang.management.ManagementFactory;
 import java.util.List;
 import java.util.Map;
-
-import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.plugins.Plugin;
+import java.util.function.Supplier;
 
 /**
  * Maps JVM input arguments (but not main arguments) using JMX to acquire JVM arguments.
@@ -32,12 +35,15 @@ import org.apache.logging.log4j.plugins.Plugin;
 @Plugin(name = "jvmrunargs", category = StrLookup.CATEGORY)
 public class JmxRuntimeInputArgumentsLookup extends MapLookup {
 
-    static {
+    private static final Supplier<JmxRuntimeInputArgumentsLookup> INSTANCE = LazyValue.from(() -> {
         final List<String> argsList = ManagementFactory.getRuntimeMXBean().getInputArguments();
-        JMX_SINGLETON = new JmxRuntimeInputArgumentsLookup(MapLookup.toMap(argsList));
-    }
+        return new JmxRuntimeInputArgumentsLookup(MapLookup.toMap(argsList));
+    });
 
-    public static final JmxRuntimeInputArgumentsLookup JMX_SINGLETON;
+    @PluginFactory
+    public static JmxRuntimeInputArgumentsLookup getInstance() {
+        return INSTANCE.get();
+    }
 
     /**
      * Constructor when used directly as a plugin.

[logging-log4j2] 06/07: Make LoggerContextFactory init lazier

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

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

commit 922aa12b2eab33349de9a814acc0a5df5a65f0a7
Author: Matt Sicker <ma...@apache.org>
AuthorDate: Wed Mar 30 21:55:41 2022 -0500

    Make LoggerContextFactory init lazier
    
    Signed-off-by: Matt Sicker <ma...@apache.org>
---
 .../java/org/apache/logging/log4j/LogManager.java  | 124 ++++++++++-----------
 1 file changed, 61 insertions(+), 63 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 887e1ed..c2d6b46 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
@@ -16,11 +16,6 @@
  */
 package org.apache.logging.log4j;
 
-import java.net.URI;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
 import org.apache.logging.log4j.internal.LogManagerStatus;
 import org.apache.logging.log4j.message.MessageFactory;
 import org.apache.logging.log4j.message.StringFormatterMessageFactory;
@@ -30,12 +25,18 @@ import org.apache.logging.log4j.spi.LoggerContextFactory;
 import org.apache.logging.log4j.spi.Provider;
 import org.apache.logging.log4j.spi.Terminable;
 import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.LazyValue;
 import org.apache.logging.log4j.util.LoaderUtil;
 import org.apache.logging.log4j.util.PropertiesUtil;
 import org.apache.logging.log4j.util.ProviderUtil;
 import org.apache.logging.log4j.util.StackLocatorUtil;
 import org.apache.logging.log4j.util.Strings;
 
+import java.net.URI;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
 /**
  * The anchor point for the Log4j logging system. The most common usage of this class is to obtain a named
  * {@link Logger}. The method {@link #getLogger()} is provided as the most convenient way to obtain a named Logger based
@@ -63,19 +64,17 @@ public class LogManager {
     // for convenience
     private static final String FQCN = LogManager.class.getName();
 
-    private static volatile LoggerContextFactory factory;
-
     /**
      * Scans the classpath to find all logging implementation. Currently, only one will be used but this could be
      * extended to allow multiple implementations to be used.
      */
-    static {
+    private static final LazyValue<LoggerContextFactory> PROVIDER = LazyValue.from(() -> {
         // Shortcut binding to force a specific logging implementation.
         final PropertiesUtil managerProps = PropertiesUtil.getProperties();
         final String factoryClassName = managerProps.getStringProperty(FACTORY_PROPERTY_NAME);
         if (factoryClassName != null) {
             try {
-                factory = LoaderUtil.newCheckedInstanceOf(factoryClassName, LoggerContextFactory.class);
+                return LoaderUtil.newCheckedInstanceOf(factoryClassName, LoggerContextFactory.class);
             } catch (final ClassNotFoundException cnfe) {
                 LOGGER.error("Unable to locate configured LoggerContextFactory {}", factoryClassName);
             } catch (final Exception ex) {
@@ -83,48 +82,48 @@ public class LogManager {
             }
         }
 
-        if (factory == null) {
-            final SortedMap<Integer, LoggerContextFactory> factories = new TreeMap<>();
-            // note that the following initial call to ProviderUtil may block until a Provider has been installed when
-            // running in an OSGi environment
-            if (ProviderUtil.hasProviders()) {
-                for (final Provider provider : ProviderUtil.getProviders()) {
-                    final Class<? extends LoggerContextFactory> factoryClass = provider.loadLoggerContextFactory();
-                    if (factoryClass != null) {
-                        try {
-                            factories.put(provider.getPriority(), factoryClass.newInstance());
-                        } catch (final Exception e) {
-                            LOGGER.error("Unable to create class {} specified in provider URL {}", factoryClass.getName(), provider
-                                    .getUrl(), e);
-                        }
-                    }
-                }
-
-                if (factories.isEmpty()) {
-                    LOGGER.error("Log4j2 could not find a logging implementation. "
-                            + "Please add log4j-core to the classpath. Using SimpleLogger to log to the console...");
-                    factory = SimpleLoggerContextFactory.INSTANCE;
-                } else if (factories.size() == 1) {
-                    factory = factories.get(factories.lastKey());
-                } else {
-                    final StringBuilder sb = new StringBuilder("Multiple logging implementations found: \n");
-                    for (final Map.Entry<Integer, LoggerContextFactory> entry : factories.entrySet()) {
-                        sb.append("Factory: ").append(entry.getValue().getClass().getName());
-                        sb.append(", Weighting: ").append(entry.getKey()).append('\n');
-                    }
-                    factory = factories.get(factories.lastKey());
-                    sb.append("Using factory: ").append(factory.getClass().getName());
-                    LOGGER.warn(sb.toString());
+        // note that the following initial call to ProviderUtil may block until a Provider has been installed when
+        // running in an OSGi environment
+        if (!ProviderUtil.hasProviders()) {
+            LOGGER.error("Log4j2 could not find a logging implementation. "
+                    + "Please add log4j-core to the classpath. Using SimpleLogger to log to the console...");
+            return SimpleLoggerContextFactory.INSTANCE;
+        }
 
+        final SortedMap<Integer, LoggerContextFactory> factories = new TreeMap<>();
+        for (final Provider provider : ProviderUtil.getProviders()) {
+            final Class<? extends LoggerContextFactory> factoryClass = provider.loadLoggerContextFactory();
+            if (factoryClass != null) {
+                try {
+                    factories.put(provider.getPriority(), factoryClass.newInstance());
+                } catch (final Exception e) {
+                    LOGGER.error("Unable to create class {} specified in provider URL {}", factoryClass.getName(), provider
+                            .getUrl(), e);
                 }
-            } else {
-                LOGGER.error("Log4j2 could not find a logging implementation. "
-                        + "Please add log4j-core to the classpath. Using SimpleLogger to log to the console...");
-                factory = SimpleLoggerContextFactory.INSTANCE;
             }
         }
+
+        if (factories.isEmpty()) {
+            LOGGER.error("Log4j2 could not find a logging implementation. "
+                    + "Please add log4j-core to the classpath. Using SimpleLogger to log to the console...");
+            return SimpleLoggerContextFactory.INSTANCE;
+        } else if (factories.size() == 1) {
+            return factories.get(factories.lastKey());
+        } else {
+            final StringBuilder sb = new StringBuilder("Multiple logging implementations found: \n");
+            for (final Map.Entry<Integer, LoggerContextFactory> entry : factories.entrySet()) {
+                sb.append("Factory: ").append(entry.getValue().getClass().getName());
+                sb.append(", Weighting: ").append(entry.getKey()).append('\n');
+            }
+            final var factory = factories.get(factories.lastKey());
+            sb.append("Using factory: ").append(factory.getClass().getName());
+            LOGGER.warn(sb.toString());
+            return factory;
+        }
+    }).map(factory -> {
         LogManagerStatus.setInitialized(true);
-    }
+        return factory;
+    });
 
     /**
      * Prevents instantiation
@@ -154,7 +153,7 @@ public class LogManager {
      */
     public static LoggerContext getContext() {
         try {
-            return factory.getContext(FQCN, null, null, true);
+            return getFactory().getContext(FQCN, null, null, true);
         } catch (final IllegalStateException ex) {
             LOGGER.warn(ex.getMessage() + " Using SimpleLogger");
             return SimpleLoggerContextFactory.INSTANCE.getContext(FQCN, null, null, true);
@@ -173,7 +172,7 @@ public class LogManager {
     public static LoggerContext getContext(final boolean currentContext) {
         // TODO: would it be a terrible idea to try and find the caller ClassLoader here?
         try {
-            return factory.getContext(FQCN, null, null, currentContext, null, null);
+            return getFactory().getContext(FQCN, null, null, currentContext, null, null);
         } catch (final IllegalStateException ex) {
             LOGGER.warn(ex.getMessage() + " Using SimpleLogger");
             return SimpleLoggerContextFactory.INSTANCE.getContext(FQCN, null, null, currentContext, null, null);
@@ -193,7 +192,7 @@ public class LogManager {
      */
     public static LoggerContext getContext(final ClassLoader loader, final boolean currentContext) {
         try {
-            return factory.getContext(FQCN, loader, null, currentContext);
+            return getFactory().getContext(FQCN, loader, null, currentContext);
         } catch (final IllegalStateException ex) {
             LOGGER.warn(ex.getMessage() + " Using SimpleLogger");
             return SimpleLoggerContextFactory.INSTANCE.getContext(FQCN, loader, null, currentContext);
@@ -215,7 +214,7 @@ public class LogManager {
     public static LoggerContext getContext(final ClassLoader loader, final boolean currentContext,
             final Object externalContext) {
         try {
-            return factory.getContext(FQCN, loader, externalContext, currentContext);
+            return getFactory().getContext(FQCN, loader, externalContext, currentContext);
         } catch (final IllegalStateException ex) {
             LOGGER.warn(ex.getMessage() + " Using SimpleLogger");
             return SimpleLoggerContextFactory.INSTANCE.getContext(FQCN, loader, externalContext, currentContext);
@@ -237,7 +236,7 @@ public class LogManager {
     public static LoggerContext getContext(final ClassLoader loader, final boolean currentContext,
             final URI configLocation) {
         try {
-            return factory.getContext(FQCN, loader, null, currentContext, configLocation, null);
+            return getFactory().getContext(FQCN, loader, null, currentContext, configLocation, null);
         } catch (final IllegalStateException ex) {
             LOGGER.warn(ex.getMessage() + " Using SimpleLogger");
             return SimpleLoggerContextFactory.INSTANCE.getContext(FQCN, loader, null, currentContext, configLocation,
@@ -261,7 +260,7 @@ public class LogManager {
     public static LoggerContext getContext(final ClassLoader loader, final boolean currentContext,
             final Object externalContext, final URI configLocation) {
         try {
-            return factory.getContext(FQCN, loader, externalContext, currentContext, configLocation, null);
+            return getFactory().getContext(FQCN, loader, externalContext, currentContext, configLocation, null);
         } catch (final IllegalStateException ex) {
             LOGGER.warn(ex.getMessage() + " Using SimpleLogger");
             return SimpleLoggerContextFactory.INSTANCE.getContext(FQCN, loader, externalContext, currentContext,
@@ -286,7 +285,7 @@ public class LogManager {
     public static LoggerContext getContext(final ClassLoader loader, final boolean currentContext,
             final Object externalContext, final URI configLocation, final String name) {
         try {
-            return factory.getContext(FQCN, loader, externalContext, currentContext, configLocation, name);
+            return getFactory().getContext(FQCN, loader, externalContext, currentContext, configLocation, name);
         } catch (final IllegalStateException ex) {
             LOGGER.warn(ex.getMessage() + " Using SimpleLogger");
             return SimpleLoggerContextFactory.INSTANCE.getContext(FQCN, loader, externalContext, currentContext,
@@ -306,7 +305,7 @@ public class LogManager {
      */
     protected static LoggerContext getContext(final String fqcn, final boolean currentContext) {
         try {
-            return factory.getContext(fqcn, null, null, currentContext);
+            return getFactory().getContext(fqcn, null, null, currentContext);
         } catch (final IllegalStateException ex) {
             LOGGER.warn(ex.getMessage() + " Using SimpleLogger");
             return SimpleLoggerContextFactory.INSTANCE.getContext(fqcn, null, null, currentContext);
@@ -328,7 +327,7 @@ public class LogManager {
     protected static LoggerContext getContext(final String fqcn, final ClassLoader loader,
             final boolean currentContext) {
         try {
-            return factory.getContext(fqcn, loader, null, currentContext);
+            return getFactory().getContext(fqcn, loader, null, currentContext);
         } catch (final IllegalStateException ex) {
             LOGGER.warn(ex.getMessage() + " Using SimpleLogger");
             return SimpleLoggerContextFactory.INSTANCE.getContext(fqcn, loader, null, currentContext);
@@ -353,7 +352,7 @@ public class LogManager {
     protected static LoggerContext getContext(final String fqcn, final ClassLoader loader,
                                               final boolean currentContext, final URI configLocation, final String name) {
         try {
-            return factory.getContext(fqcn, loader, null, currentContext, configLocation, name);
+            return getFactory().getContext(fqcn, loader, null, currentContext, configLocation, name);
         } catch (final IllegalStateException ex) {
             LOGGER.warn(ex.getMessage() + " Using SimpleLogger");
             return SimpleLoggerContextFactory.INSTANCE.getContext(fqcn, loader, null, currentContext);
@@ -389,7 +388,7 @@ public class LogManager {
      * @since 2.6
      */
     public static void shutdown(final boolean currentContext) {
-        factory.shutdown(FQCN, null, currentContext, false);
+        getFactory().shutdown(FQCN, null, currentContext, false);
     }
 
     /**
@@ -409,7 +408,7 @@ public class LogManager {
      * @since 2.13.0
      */
     public static void shutdown(final boolean currentContext, final boolean allContexts) {
-        factory.shutdown(FQCN, null, currentContext, allContexts);
+        getFactory().shutdown(FQCN, null, currentContext, allContexts);
     }
 
     /**
@@ -422,7 +421,7 @@ public class LogManager {
      * @since 2.6
      */
     public static void shutdown(final LoggerContext context) {
-        if (context != null && context instanceof Terminable) {
+        if (context instanceof Terminable) {
             ((Terminable) context).terminate();
         }
     }
@@ -433,7 +432,7 @@ public class LogManager {
      * @return The LoggerContextFactory.
      */
     public static LoggerContextFactory getFactory() {
-        return factory;
+        return PROVIDER.get();
     }
 
     /**
@@ -449,9 +448,8 @@ public class LogManager {
      *
      * @param factory the LoggerContextFactory to use.
      */
-    // FIXME: should we allow only one update of the factory?
     public static void setFactory(final LoggerContextFactory factory) {
-        LogManager.factory = factory;
+        PROVIDER.set(factory);
     }
 
     /**
@@ -687,7 +685,7 @@ public class LogManager {
      * @return The Logger.
      */
     protected static Logger getLogger(final String fqcn, final String name) {
-        return factory.getContext(fqcn, null, null, false).getLogger(name);
+        return getFactory().getContext(fqcn, null, null, false).getLogger(name);
     }
 
     /**

[logging-log4j2] 02/07: Use null sentinel in LazyValue

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

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

commit 9c160a9e0df002d840fb3b494ae8dcdb35428756
Author: Matt Sicker <ma...@apache.org>
AuthorDate: Wed Mar 30 21:51:16 2022 -0500

    Use null sentinel in LazyValue
    
    Signed-off-by: Matt Sicker <ma...@apache.org>
---
 .../java/org/apache/logging/log4j/util/LazyValue.java    | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/LazyValue.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/LazyValue.java
index 0398868..20d7965 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/LazyValue.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/LazyValue.java
@@ -27,6 +27,13 @@ import java.util.function.Supplier;
  */
 public final class LazyValue<T> implements Supplier<T> {
 
+    private static final Object NULL_INSTANCE = new Object();
+
+    @SuppressWarnings("unchecked")
+    private static <T> T nullInstance() {
+        return (T) NULL_INSTANCE;
+    }
+
     /**
      * Creates a lazy value using the provided Supplier for initialization.
      */
@@ -53,11 +60,16 @@ public final class LazyValue<T> implements Supplier<T> {
             synchronized (this) {
                 value = this.value;
                 if (value == null) {
-                    this.value = value = supplier.get();
+                    value = supplier.get();
+                    this.value = value == null ? nullInstance() : value;
                 }
             }
         }
-        return value;
+        return value == NULL_INSTANCE ? null : value;
+    }
+
+    public void set(final T value) {
+        this.value = value;
     }
 
     /**

[logging-log4j2] 04/07: Lazy init of SslConfiguration

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

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

commit ceb4e8a583bda5a46c3b50232595b5efb36a7ea7
Author: Matt Sicker <ma...@apache.org>
AuthorDate: Wed Mar 30 21:53:33 2022 -0500

    Lazy init of SslConfiguration
    
    Signed-off-by: Matt Sicker <ma...@apache.org>
---
 .../core/net/ssl/SslConfigurationFactory.java      | 27 ++++++++++++----------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfigurationFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfigurationFactory.java
index df0fdd5..ad393d6 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfigurationFactory.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfigurationFactory.java
@@ -18,15 +18,17 @@ package org.apache.logging.log4j.core.net.ssl;
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.LazyValue;
 import org.apache.logging.log4j.util.PropertiesUtil;
 
+import java.util.function.Supplier;
+
 /**
  * Creates an SSL configuration from Log4j properties.
  */
 public class SslConfigurationFactory {
 
     private static final Logger LOGGER = StatusLogger.getLogger();
-    private static SslConfiguration sslConfiguration = null;
 
     private static final String trustStorelocation = "log4j2.trustStore.location";
     private static final String trustStorePassword = "log4j2.trustStore.password";
@@ -42,7 +44,7 @@ public class SslConfigurationFactory {
     private static final String keyStoreKeyManagerFactoryAlgorithm = "log4j2.keyStore.keyManagerFactoryAlgorithm";
     private static final String verifyHostName = "log4j2.ssl.verifyHostName";
 
-    static {
+    private static final Supplier<SslConfiguration> SSL_CONFIGURATION = LazyValue.from(() -> {
         final PropertiesUtil props = PropertiesUtil.getProperties();
         KeyStoreConfiguration keyStoreConfiguration = null;
         TrustStoreConfiguration trustStoreConfiguration = null;
@@ -55,11 +57,11 @@ public class SslConfigurationFactory {
             }
             try {
                 trustStoreConfiguration = TrustStoreConfiguration.createKeyStoreConfiguration(location, passwordChars,
-                    props.getStringProperty(trustStorePasswordEnvVar), props.getStringProperty(trustStorePasswordFile),
-                    props.getStringProperty(trustStoreKeyStoreType), props.getStringProperty(trustStoreKeyManagerFactoryAlgorithm));
+                        props.getStringProperty(trustStorePasswordEnvVar), props.getStringProperty(trustStorePasswordFile),
+                        props.getStringProperty(trustStoreKeyStoreType), props.getStringProperty(trustStoreKeyManagerFactoryAlgorithm));
             } catch (final Exception ex) {
                 LOGGER.warn("Unable to create trust store configuration due to: {} {}", ex.getClass().getName(),
-                    ex.getMessage());
+                        ex.getMessage());
             }
         }
         location = props.getStringProperty(keyStoreLocation);
@@ -71,21 +73,22 @@ public class SslConfigurationFactory {
             }
             try {
                 keyStoreConfiguration = KeyStoreConfiguration.createKeyStoreConfiguration(location, passwordChars,
-                    props.getStringProperty(keyStorePasswordEnvVar), props.getStringProperty(keyStorePasswordFile),
-                    props.getStringProperty(keyStoreType), props.getStringProperty(keyStoreKeyManagerFactoryAlgorithm));
+                        props.getStringProperty(keyStorePasswordEnvVar), props.getStringProperty(keyStorePasswordFile),
+                        props.getStringProperty(keyStoreType), props.getStringProperty(keyStoreKeyManagerFactoryAlgorithm));
             } catch (final Exception ex) {
                 LOGGER.warn("Unable to create key store configuration due to: {} {}", ex.getClass().getName(),
-                    ex.getMessage());
+                        ex.getMessage());
             }
         }
         if (trustStoreConfiguration != null || keyStoreConfiguration != null) {
             final boolean isVerifyHostName = props.getBooleanProperty(verifyHostName, false);
-            sslConfiguration = SslConfiguration.createSSLConfiguration("https", keyStoreConfiguration,
-                trustStoreConfiguration, isVerifyHostName);
+            return SslConfiguration.createSSLConfiguration("https", keyStoreConfiguration,
+                    trustStoreConfiguration, isVerifyHostName);
         }
-    }
+        return null;
+    });
 
     public static SslConfiguration getSslConfiguration() {
-        return sslConfiguration;
+        return SSL_CONFIGURATION.get();
     }
 }

[logging-log4j2] 01/07: Modernize syntax

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

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

commit 510e090ab9243878716dc93710cbffc5d4d89f3f
Author: Matt Sicker <ma...@apache.org>
AuthorDate: Wed Mar 30 21:49:26 2022 -0500

    Modernize syntax
    
    Signed-off-by: Matt Sicker <ma...@apache.org>
---
 .../logging/log4j/spi/DefaultThreadContextMap.java | 24 +++++----
 .../log4j/core/pattern/HighlightConverter.java     | 57 ++++++++++------------
 2 files changed, 38 insertions(+), 43 deletions(-)

diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/DefaultThreadContextMap.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/DefaultThreadContextMap.java
index c3feac0..2b5c618 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/DefaultThreadContextMap.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/DefaultThreadContextMap.java
@@ -16,16 +16,16 @@
  */
 package org.apache.logging.log4j.spi;
 
+import org.apache.logging.log4j.util.BiConsumer;
+import org.apache.logging.log4j.util.PropertiesUtil;
+import org.apache.logging.log4j.util.ReadOnlyStringMap;
+import org.apache.logging.log4j.util.TriConsumer;
+
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
 
-import org.apache.logging.log4j.util.BiConsumer;
-import org.apache.logging.log4j.util.ReadOnlyStringMap;
-import org.apache.logging.log4j.util.PropertiesUtil;
-import org.apache.logging.log4j.util.TriConsumer;
-
 /**
  * The actual ThreadContext Map. A new ThreadContext Map is created each time it is updated and the Map stored is always
  * immutable. This means the Map can be passed to other threads without concern that it will be updated. Since it is
@@ -54,11 +54,11 @@ public class DefaultThreadContextMap implements ThreadContextMap, ReadOnlyString
     // (This method is package protected for JUnit tests.)
     static ThreadLocal<Map<String, String>> createThreadLocalMap(final boolean isMapEnabled) {
         if (inheritableMap) {
-            return new InheritableThreadLocal<Map<String, String>>() {
+            return new InheritableThreadLocal<>() {
                 @Override
                 protected Map<String, String> childValue(final Map<String, String> parentValue) {
                     return parentValue != null && isMapEnabled //
-                    ? Collections.unmodifiableMap(new HashMap<>(parentValue)) //
+                            ? Map.copyOf(parentValue) //
                             : null;
                 }
             };
@@ -86,7 +86,7 @@ public class DefaultThreadContextMap implements ThreadContextMap, ReadOnlyString
             return;
         }
         Map<String, String> map = localMap.get();
-        map = map == null ? new HashMap<String, String>(1) : new HashMap<>(map);
+        map = map == null ? new HashMap<>(1) : new HashMap<>(map);
         map.put(key, value);
         localMap.set(Collections.unmodifiableMap(map));
     }
@@ -96,10 +96,8 @@ public class DefaultThreadContextMap implements ThreadContextMap, ReadOnlyString
             return;
         }
         Map<String, String> map = localMap.get();
-        map = map == null ? new HashMap<String, String>(m.size()) : new HashMap<>(map);
-        for (final Map.Entry<String, String> e : m.entrySet()) {
-            map.put(e.getKey(), e.getValue());
-        }
+        map = map == null ? new HashMap<>(m.size()) : new HashMap<>(map);
+        map.putAll(m);
         localMap.set(Collections.unmodifiableMap(map));
     }
 
@@ -182,7 +180,7 @@ public class DefaultThreadContextMap implements ThreadContextMap, ReadOnlyString
     @Override
     public Map<String, String> getCopy() {
         final Map<String, String> map = localMap.get();
-        return map == null ? new HashMap<String, String>() : new HashMap<>(map);
+        return map == null ? new HashMap<>() : new HashMap<>(map);
     }
 
     @Override
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/HighlightConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/HighlightConverter.java
index cc925ad..1ae9019 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/HighlightConverter.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/HighlightConverter.java
@@ -16,20 +16,20 @@
  */
 package org.apache.logging.log4j.core.pattern;
 
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.Configuration;
-import org.apache.logging.log4j.plugins.Plugin;
 import org.apache.logging.log4j.core.layout.PatternLayout;
+import org.apache.logging.log4j.plugins.Plugin;
 import org.apache.logging.log4j.util.PerformanceSensitive;
 import org.apache.logging.log4j.util.Strings;
 
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
 /**
  * Highlight pattern converter. Formats the result of a pattern using a color appropriate for the Level in the LogEvent.
  * <p>
@@ -80,9 +80,23 @@ import org.apache.logging.log4j.util.Strings;
 @PerformanceSensitive("allocation")
 public final class HighlightConverter extends LogEventPatternConverter implements AnsiConverter {
 
-    private static final Map<String, String> DEFAULT_STYLES = new HashMap<>();
+    private static final Map<String, String> DEFAULT_STYLES = Map.of(
+            Level.FATAL.name(), AnsiEscape.createSequence("BRIGHT", "RED"),
+            Level.ERROR.name(), AnsiEscape.createSequence("BRIGHT", "RED"),
+            Level.WARN.name(), AnsiEscape.createSequence("YELLOW"),
+            Level.INFO.name(), AnsiEscape.createSequence("GREEN"),
+            Level.DEBUG.name(), AnsiEscape.createSequence("CYAN"),
+            Level.TRACE.name(), AnsiEscape.createSequence("BLACK")
+    );
 
-    private static final Map<String, String> LOGBACK_STYLES = new HashMap<>();
+    private static final Map<String, String> LOGBACK_STYLES = Map.of(
+            Level.FATAL.name(), AnsiEscape.createSequence("BLINK", "BRIGHT", "RED"),
+            Level.ERROR.name(), AnsiEscape.createSequence("BRIGHT", "RED"),
+            Level.WARN.name(), AnsiEscape.createSequence("RED"),
+            Level.INFO.name(), AnsiEscape.createSequence("BLUE"),
+            Level.DEBUG.name(), AnsiEscape.createSequence((String[]) null),
+            Level.TRACE.name(), AnsiEscape.createSequence((String[]) null)
+    );
 
     private static final String STYLE_KEY = "STYLE";
 
@@ -90,27 +104,10 @@ public final class HighlightConverter extends LogEventPatternConverter implement
 
     private static final String STYLE_KEY_LOGBACK = "LOGBACK";
 
-    private static final Map<String, Map<String, String>> STYLES = new HashMap<>();
-
-    static {
-        // Default styles:
-        DEFAULT_STYLES.put(Level.FATAL.name(), AnsiEscape.createSequence("BRIGHT", "RED"));
-        DEFAULT_STYLES.put(Level.ERROR.name(), AnsiEscape.createSequence("BRIGHT", "RED"));
-        DEFAULT_STYLES.put(Level.WARN.name(), AnsiEscape.createSequence("YELLOW"));
-        DEFAULT_STYLES.put(Level.INFO.name(), AnsiEscape.createSequence("GREEN"));
-        DEFAULT_STYLES.put(Level.DEBUG.name(), AnsiEscape.createSequence("CYAN"));
-        DEFAULT_STYLES.put(Level.TRACE.name(), AnsiEscape.createSequence("BLACK"));
-        // Logback styles:
-        LOGBACK_STYLES.put(Level.FATAL.name(), AnsiEscape.createSequence("BLINK", "BRIGHT", "RED"));
-        LOGBACK_STYLES.put(Level.ERROR.name(), AnsiEscape.createSequence("BRIGHT", "RED"));
-        LOGBACK_STYLES.put(Level.WARN.name(), AnsiEscape.createSequence("RED"));
-        LOGBACK_STYLES.put(Level.INFO.name(), AnsiEscape.createSequence("BLUE"));
-        LOGBACK_STYLES.put(Level.DEBUG.name(), AnsiEscape.createSequence((String[]) null));
-        LOGBACK_STYLES.put(Level.TRACE.name(), AnsiEscape.createSequence((String[]) null));
-        // Style map:
-        STYLES.put(STYLE_KEY_DEFAULT, DEFAULT_STYLES);
-        STYLES.put(STYLE_KEY_LOGBACK, LOGBACK_STYLES);
-    }
+    private static final Map<String, Map<String, String>> STYLES = Map.of(
+            STYLE_KEY_DEFAULT, DEFAULT_STYLES,
+            STYLE_KEY_LOGBACK, LOGBACK_STYLES
+    );
 
     /**
      * Creates a level style map where values are ANSI escape sequences given configuration options in {@code option[1]}

[logging-log4j2] 05/07: Lazy init of escape code tables

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

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

commit 5997cd8d410690bd65e1f7c549da8d59cf4742a8
Author: Matt Sicker <ma...@apache.org>
AuthorDate: Wed Mar 30 21:53:49 2022 -0500

    Lazy init of escape code tables
    
    Signed-off-by: Matt Sicker <ma...@apache.org>
---
 .../org/apache/logging/log4j/core/util/JsonUtils.java | 18 +++++++++++-------
 .../log4j/layout/template/json/util/JsonWriter.java   | 19 +++++++++++--------
 2 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/JsonUtils.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/JsonUtils.java
index c23f4b3..92957cc 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/JsonUtils.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/JsonUtils.java
@@ -16,6 +16,10 @@
  */
 package org.apache.logging.log4j.core.util;
 
+import org.apache.logging.log4j.util.LazyValue;
+
+import java.util.function.Supplier;
+
 /**
  * This class is borrowed from <a href="https://github.com/FasterXML/jackson-core">Jackson</a>.
  */
@@ -29,8 +33,7 @@ public final class JsonUtils {
      * to use after backslash; and negative values that generic (backslash - u)
      * escaping is to be used.
      */
-    private static final int[] ESC_CODES;
-    static {
+    private static final Supplier<int[]> ESC_CODES = LazyValue.from(() -> {
         final int[] table = new int[128];
         // Control chars need generic escape sequence
         for (int i = 0; i < 32; ++i) {
@@ -48,8 +51,8 @@ public final class JsonUtils {
         table[0x0C] = 'f';
         table[0x0A] = 'n';
         table[0x0D] = 'r';
-        ESC_CODES = table;
-    }
+        return table;
+    });
 
     /**
      * Temporary buffer used for composing quote/escape sequences
@@ -74,7 +77,8 @@ public final class JsonUtils {
      */
     public static void quoteAsString(final CharSequence input, final StringBuilder output) {
         final char[] qbuf = getQBuf();
-        final int escCodeCount = ESC_CODES.length;
+        final int[] escCodes = ESC_CODES.get();
+        final int escCodeCount = escCodes.length;
         int inPtr = 0;
         final int inputLen = input.length();
 
@@ -83,7 +87,7 @@ public final class JsonUtils {
             tight_loop:
             while (true) {
                 final char c = input.charAt(inPtr);
-                if (c < escCodeCount && ESC_CODES[c] != 0) {
+                if (c < escCodeCount && escCodes[c] != 0) {
                     break tight_loop;
                 }
                 output.append(c);
@@ -93,7 +97,7 @@ public final class JsonUtils {
             }
             // something to escape; 2 or 6-char variant?
             final char d = input.charAt(inPtr++);
-            final int escCode = ESC_CODES[d];
+            final int escCode = escCodes[d];
             final int length = (escCode < 0)
                     ? _appendNumeric(d, qbuf)
                     : _appendNamed(escCode, qbuf);
diff --git a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/util/JsonWriter.java b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/util/JsonWriter.java
index 82d0a7e..ce136ed 100644
--- a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/util/JsonWriter.java
+++ b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/util/JsonWriter.java
@@ -17,6 +17,7 @@
 package org.apache.logging.log4j.layout.template.json.util;
 
 import org.apache.logging.log4j.util.IndexedReadOnlyStringMap;
+import org.apache.logging.log4j.util.LazyValue;
 import org.apache.logging.log4j.util.StringBuilderFormattable;
 import org.apache.logging.log4j.util.StringMap;
 
@@ -27,6 +28,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.function.BiConsumer;
+import java.util.function.Supplier;
 
 /**
  * A simple JSON writer with support for common Java data types.
@@ -66,8 +68,7 @@ public final class JsonWriter implements AutoCloseable, Cloneable {
      * character to use after backslash; and negative values, that generic
      * (backslash - u) escaping is to be used.
      */
-    private final static int[] ESC_CODES;
-    static {
+    private static final Supplier<int[]> ESC_CODES = LazyValue.from(() -> {
         final int[] table = new int[128];
         // Control chars need generic escape sequence
         for (int i = 0; i < 32; ++i) {
@@ -83,8 +84,8 @@ public final class JsonWriter implements AutoCloseable, Cloneable {
         table[0x0C] = 'f';
         table[0x0A] = 'n';
         table[0x0D] = 'r';
-        ESC_CODES = table;
-    }
+        return table;
+    });
 
     private final char[] quoteBuffer;
 
@@ -599,11 +600,12 @@ public final class JsonWriter implements AutoCloseable, Cloneable {
                         : 0;
         final int limit = offset + length + surrogateCorrection;
         int i = offset;
+        final int[] escCodes = ESC_CODES.get();
         outer:
         while (i < limit) {
             while (true) {
                 final char c = seq.charAt(i);
-                if (c < ESC_CODES.length && ESC_CODES[c] != 0) {
+                if (c < escCodes.length && escCodes[c] != 0) {
                     break;
                 }
                 stringBuilder.append(c);
@@ -612,7 +614,7 @@ public final class JsonWriter implements AutoCloseable, Cloneable {
                 }
             }
             final char d = seq.charAt(i++);
-            final int escCode = ESC_CODES[d];
+            final int escCode = escCodes[d];
             final int quoteBufferLength = escCode < 0
                     ? quoteNumeric(d)
                     : quoteNamed(escCode);
@@ -676,11 +678,12 @@ public final class JsonWriter implements AutoCloseable, Cloneable {
                         : 0;
         final int limit = offset + length + surrogateCorrection;
         int i = offset;
+        final int[] escCodes = ESC_CODES.get();
         outer:
         while (i < limit) {
             while (true) {
                 final char c = buffer[i];
-                if (c < ESC_CODES.length && ESC_CODES[c] != 0) {
+                if (c < escCodes.length && escCodes[c] != 0) {
                     break;
                 }
                 stringBuilder.append(c);
@@ -689,7 +692,7 @@ public final class JsonWriter implements AutoCloseable, Cloneable {
                 }
             }
             final char d = buffer[i++];
-            final int escCode = ESC_CODES[d];
+            final int escCode = escCodes[d];
             final int quoteBufferLength = escCode < 0
                     ? quoteNumeric(d)
                     : quoteNamed(escCode);