diff --git a/slf4j-api/src/main/java/org/slf4j/LoggerFactory.java b/slf4j-api/src/main/java/org/slf4j/LoggerFactory.java index 995f3eb21..2c6e09706 100755 --- a/slf4j-api/src/main/java/org/slf4j/LoggerFactory.java +++ b/slf4j-api/src/main/java/org/slf4j/LoggerFactory.java @@ -148,6 +148,7 @@ private final static void bind() { reportMultipleBindingAmbiguity(providersList); if (providersList != null && !providersList.isEmpty()) { PROVIDER = providersList.get(0); + // SLF4JServiceProvider.initialize() is intended to be called here and nowhere else. PROVIDER.initialize(); INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION; reportActualBinding(providersList); diff --git a/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java b/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java index 8c344faad..15ab28250 100644 --- a/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java +++ b/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java @@ -52,7 +52,6 @@ private MarkerFactory() { static { SLF4JServiceProvider provider = LoggerFactory.getProvider(); if (provider != null) { - provider.initialize(); MARKER_FACTORY = provider.getMarkerFactory(); } else { Util.report("Failed to find provider"); diff --git a/slf4j-api/src/main/java/org/slf4j/spi/SLF4JServiceProvider.java b/slf4j-api/src/main/java/org/slf4j/spi/SLF4JServiceProvider.java index 60052ef0a..19d7e9a00 100755 --- a/slf4j-api/src/main/java/org/slf4j/spi/SLF4JServiceProvider.java +++ b/slf4j-api/src/main/java/org/slf4j/spi/SLF4JServiceProvider.java @@ -2,7 +2,16 @@ import org.slf4j.ILoggerFactory; import org.slf4j.IMarkerFactory; +import org.slf4j.LoggerFactory; +/** + * This interface based on {@link java.util.ServiceLoader} paradigm. + * + *

It replaces the old static-binding mechanism used in SLF4J versions 1.0.x to 1.7.x. + * + * @author Ceki G¨lc¨ + * @since 1.8 + */ public interface SLF4JServiceProvider { @@ -10,8 +19,7 @@ public interface SLF4JServiceProvider { * Return the instance of {@link ILoggerFactory} that * {@link org.slf4j.LoggerFactory} class should bind to. * - * @return the instance of {@link ILoggerFactory} that - * {@link org.slf4j.LoggerFactory} class should bind to. + * @return instance of {@link ILoggerFactory} */ public ILoggerFactory getLoggerFactory(); @@ -19,15 +27,26 @@ public interface SLF4JServiceProvider { * Return the instance of {@link IMarkerFactory} that * {@link org.slf4j.MarkerFactory} class should bind to. * - * @return the instance of {@link IMarkerFactory} that - * {@link org.slf4j.MarkerFactory} class should bind to. + * @return instance of {@link IMarkerFactory} */ public IMarkerFactory getMarkerFactory(); - + /** + * Return the instnace of {@link MDCAdapter} that + * {@link MDC} should bind to. + * + * @return instance of {@link MDCAdapter} + */ public MDCAdapter getMDCAdapter(); public String getRequesteApiVersion(); + /** + * Initialize the logging back-end. + * + *

WARNING: This method is intended to be called once by + * {@link LoggerFactory} class and from nowhere else. + * + */ public void initialize(); } diff --git a/slf4j-simple/src/main/java/org/slf4j/simple/DoubleInitializationPitfallTest.java b/slf4j-simple/src/main/java/org/slf4j/simple/DoubleInitializationPitfallTest.java new file mode 100644 index 000000000..202f354cb --- /dev/null +++ b/slf4j-simple/src/main/java/org/slf4j/simple/DoubleInitializationPitfallTest.java @@ -0,0 +1,37 @@ +package org.slf4j.simple; + +import static org.junit.Assert.fail; + +import org.junit.Test; +import org.slf4j.ILoggerFactory; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.slf4j.MarkerFactory; + +public class DoubleInitializationPitfallTest { + + + @Test + public void verifyImpactOfMarkerFactory() { + ILoggerFactory firstFactory = LoggerFactory.getILoggerFactory(); + MarkerFactory.getMarker("DOUBLE_INIT"); + ILoggerFactory secondFactory = LoggerFactory.getILoggerFactory(); + + if(firstFactory != secondFactory) { + fail("MarkerFactory.getMarker causes multiple provider initialization"); + } + } + + @Test + public void verifyImpactOfMDC() { + ILoggerFactory firstFactory = LoggerFactory.getILoggerFactory(); + MDC.put("DoubleInitializationPitfallTest", "a"); + ILoggerFactory secondFactory = LoggerFactory.getILoggerFactory(); + + if(firstFactory != secondFactory) { + fail("MarkerFactory.getMarker causes multiple provider initialization"); + } + } + + +} diff --git a/slf4j-site/src/site/pages/news.html b/slf4j-site/src/site/pages/news.html index e34466d4e..9404e73e8 100755 --- a/slf4j-site/src/site/pages/news.html +++ b/slf4j-site/src/site/pages/news.html @@ -37,6 +37,17 @@

SLF4J News

class names in --> + +
+

2019 - Release of SLF4J 2.0.0-alpha1

+ + +

• Fix the double back-end initializatoin problem reported + in SLF4J-463 by + Dan Groves who also provided a test-case to reptoduce the problem + and a relevant fix. +

+

6th of August, 2019 - Release of SLF4J 1.7.27