From ae2029fae55e08ebf0cd3826c3c1b78342b6e4ae Mon Sep 17 00:00:00 2001 From: Matt Bishop Date: Tue, 1 Dec 2015 15:09:29 -0800 Subject: [PATCH 01/11] Replaced maven-bundle-plugin with jar manifest template. Picks up build-helper-maven-plugin config correctly. --- osgi-over-slf4j/pom.xml | 18 +----------------- .../src/main/resources/META-INF/MANIFEST.MF | 8 ++++++++ 2 files changed, 9 insertions(+), 17 deletions(-) create mode 100644 osgi-over-slf4j/src/main/resources/META-INF/MANIFEST.MF diff --git a/osgi-over-slf4j/pom.xml b/osgi-over-slf4j/pom.xml index 7c38b36d..b7129043 100755 --- a/osgi-over-slf4j/pom.xml +++ b/osgi-over-slf4j/pom.xml @@ -12,7 +12,7 @@ osgi-over-slf4j - bundle + jar OSGi LogService implemented over SLF4J http://www.slf4j.org @@ -41,20 +41,4 @@ provided - - - - org.apache.felix - maven-bundle-plugin - 2.3.7 - true - - - org.osgi.service.log - org.slf4j.osgi.logservice.impl.Activator - - - - - diff --git a/osgi-over-slf4j/src/main/resources/META-INF/MANIFEST.MF b/osgi-over-slf4j/src/main/resources/META-INF/MANIFEST.MF new file mode 100644 index 00000000..3f9f8b18 --- /dev/null +++ b/osgi-over-slf4j/src/main/resources/META-INF/MANIFEST.MF @@ -0,0 +1,8 @@ +Implementation-Title: osgi-over-slf4j +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: org.slf4j.osgi-over-slf4j +Bundle-Name: OSGi LogService implemented over SLF4J +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-Activator: org.slf4j.osgi.logservice.impl.Activator +Export-Package: org.osgi.service.log;uses:="org.osgi.framework";version=${parsedVersion.osgiVersion} +Import-Package: org.osgi.framework;"[1.5,2)",org.osgi.service.log;version="[1.3,2)",org.slf4j;version=${parsedVersion.osgiVersion} From a4c645d18874ae7568a7ca8788ddd43bcfa67e27 Mon Sep 17 00:00:00 2001 From: Ceki Gulcu Date: Thu, 3 Dec 2015 19:31:23 +0100 Subject: [PATCH 02/11] revert REQUESTED_API_VERSION to 1.6.99 --- .../src/main/java/org/slf4j/impl/StaticLoggerBinder.java | 2 +- slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java | 2 +- slf4j-jcl/src/main/java/org/slf4j/impl/StaticLoggerBinder.java | 2 +- .../src/main/java/org/slf4j/impl/StaticLoggerBinder.java | 2 +- .../src/main/java/org/slf4j/impl/StaticLoggerBinder.java | 2 +- slf4j-nop/src/main/java/org/slf4j/impl/StaticLoggerBinder.java | 2 +- .../src/main/java/org/slf4j/impl/StaticLoggerBinder.java | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/slf4j-android/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/slf4j-android/src/main/java/org/slf4j/impl/StaticLoggerBinder.java index de74d1f0..89d4addc 100644 --- a/slf4j-android/src/main/java/org/slf4j/impl/StaticLoggerBinder.java +++ b/slf4j-android/src/main/java/org/slf4j/impl/StaticLoggerBinder.java @@ -56,7 +56,7 @@ public class StaticLoggerBinder implements LoggerFactoryBinder { * The value of this field is modified with each major release. */ // to avoid constant folding by the compiler, this field must *not* be final - public static String REQUESTED_API_VERSION = "1.7.x"; // !final + public static String REQUESTED_API_VERSION = "1.6.99"; // !final diff --git a/slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java index c60018cc..55d54813 100644 --- a/slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java +++ b/slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java @@ -57,7 +57,7 @@ public class StaticLoggerBinder { * The value of this field is modified with each major release. */ // to avoid constant folding by the compiler, this field must *not* be final - public static String REQUESTED_API_VERSION = "1.7.x"; // !final + public static String REQUESTED_API_VERSION = "1.6.99"; // !final private StaticLoggerBinder() { throw new UnsupportedOperationException("This code should have never made it into slf4j-api.jar"); diff --git a/slf4j-jcl/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/slf4j-jcl/src/main/java/org/slf4j/impl/StaticLoggerBinder.java index 011a9437..84074cad 100644 --- a/slf4j-jcl/src/main/java/org/slf4j/impl/StaticLoggerBinder.java +++ b/slf4j-jcl/src/main/java/org/slf4j/impl/StaticLoggerBinder.java @@ -55,7 +55,7 @@ public class StaticLoggerBinder implements LoggerFactoryBinder { * The value of this field is modified with each major release. */ // to avoid constant folding by the compiler, this field must *not* be final - public static String REQUESTED_API_VERSION = "1.7.x"; // !final + public static String REQUESTED_API_VERSION = "1.6.99"; // !final // Binding specific code: diff --git a/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticLoggerBinder.java index c7375cd1..74c18936 100644 --- a/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticLoggerBinder.java +++ b/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticLoggerBinder.java @@ -56,7 +56,7 @@ public class StaticLoggerBinder implements LoggerFactoryBinder { * The value of this field is modified with each major release. */ // to avoid constant folding by the compiler, this field must *not* be final - public static String REQUESTED_API_VERSION = "1.7.x"; // !final + public static String REQUESTED_API_VERSION = "1.6.99"; // !final private static final String loggerFactoryClassStr = org.slf4j.impl.JDK14LoggerFactory.class.getName(); diff --git a/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticLoggerBinder.java index a14ca119..2ed8c6ef 100644 --- a/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticLoggerBinder.java +++ b/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticLoggerBinder.java @@ -58,7 +58,7 @@ public class StaticLoggerBinder implements LoggerFactoryBinder { * The value of this field is modified with each major release. */ // to avoid constant folding by the compiler, this field must *not* be final - public static String REQUESTED_API_VERSION = "1.7.x"; // !final + public static String REQUESTED_API_VERSION = "1.6.99"; // !final private static final String loggerFactoryClassStr = Log4jLoggerFactory.class.getName(); diff --git a/slf4j-nop/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/slf4j-nop/src/main/java/org/slf4j/impl/StaticLoggerBinder.java index 90b13c7f..35fc464d 100644 --- a/slf4j-nop/src/main/java/org/slf4j/impl/StaticLoggerBinder.java +++ b/slf4j-nop/src/main/java/org/slf4j/impl/StaticLoggerBinder.java @@ -57,7 +57,7 @@ public class StaticLoggerBinder implements LoggerFactoryBinder { * The value of this field is modified with each major release. */ // to avoid constant folding by the compiler, this field must *not* be final - public static String REQUESTED_API_VERSION = "1.7.x"; // !final + public static String REQUESTED_API_VERSION = "1.6.99"; // !final private static final String loggerFactoryClassStr = NOPLoggerFactory.class.getName(); diff --git a/slf4j-simple/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/slf4j-simple/src/main/java/org/slf4j/impl/StaticLoggerBinder.java index e3859f34..23b6c874 100644 --- a/slf4j-simple/src/main/java/org/slf4j/impl/StaticLoggerBinder.java +++ b/slf4j-simple/src/main/java/org/slf4j/impl/StaticLoggerBinder.java @@ -57,7 +57,7 @@ public class StaticLoggerBinder implements LoggerFactoryBinder { * The value of this field is modified with each major release. */ // to avoid constant folding by the compiler, this field must *not* be final - public static String REQUESTED_API_VERSION = "1.7.x"; // !final + public static String REQUESTED_API_VERSION = "1.6.99"; // !final private static final String loggerFactoryClassStr = SimpleLoggerFactory.class.getName(); From 6c461383d568611c27be92eb2e0167dc3b50e9bf Mon Sep 17 00:00:00 2001 From: Matt Bishop Date: Sat, 5 Dec 2015 21:13:41 -0800 Subject: [PATCH 03/11] Add Bundle-Category entry. Remove unnecessary Export-Package entry. --- osgi-over-slf4j/src/main/resources/META-INF/MANIFEST.MF | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osgi-over-slf4j/src/main/resources/META-INF/MANIFEST.MF b/osgi-over-slf4j/src/main/resources/META-INF/MANIFEST.MF index 3f9f8b18..2df03c0b 100644 --- a/osgi-over-slf4j/src/main/resources/META-INF/MANIFEST.MF +++ b/osgi-over-slf4j/src/main/resources/META-INF/MANIFEST.MF @@ -4,5 +4,5 @@ Bundle-SymbolicName: org.slf4j.osgi-over-slf4j Bundle-Name: OSGi LogService implemented over SLF4J Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-Activator: org.slf4j.osgi.logservice.impl.Activator -Export-Package: org.osgi.service.log;uses:="org.osgi.framework";version=${parsedVersion.osgiVersion} +Bundle-Category: osgi Import-Package: org.osgi.framework;"[1.5,2)",org.osgi.service.log;version="[1.3,2)",org.slf4j;version=${parsedVersion.osgiVersion} From 3e749c3d6f5a4d74e31f49bd50956f3dbe3add76 Mon Sep 17 00:00:00 2001 From: Matt Bishop Date: Tue, 8 Dec 2015 15:29:27 -0800 Subject: [PATCH 04/11] Set framework version requirement --- osgi-over-slf4j/src/main/resources/META-INF/MANIFEST.MF | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osgi-over-slf4j/src/main/resources/META-INF/MANIFEST.MF b/osgi-over-slf4j/src/main/resources/META-INF/MANIFEST.MF index 2df03c0b..73cebcfc 100644 --- a/osgi-over-slf4j/src/main/resources/META-INF/MANIFEST.MF +++ b/osgi-over-slf4j/src/main/resources/META-INF/MANIFEST.MF @@ -5,4 +5,4 @@ Bundle-Name: OSGi LogService implemented over SLF4J Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-Activator: org.slf4j.osgi.logservice.impl.Activator Bundle-Category: osgi -Import-Package: org.osgi.framework;"[1.5,2)",org.osgi.service.log;version="[1.3,2)",org.slf4j;version=${parsedVersion.osgiVersion} +Import-Package: org.osgi.framework;version="[1.5,2)",org.osgi.service.log;version="[1.3,2)",org.slf4j;version=${parsedVersion.osgiVersion} From 7a23ca74ae94f87675b25414d6c67a9e9ba9d98f Mon Sep 17 00:00:00 2001 From: Frans Orsel Date: Tue, 15 Dec 2015 17:11:48 +0100 Subject: [PATCH 05/11] Move delegation loop check from log4j-over-slf4j.jar to slf4j-log4j12.jar, see also SLF4J-345 --- .../org/apache/log4j/Log4jLoggerFactory.java | 18 ------------------ .../java/org/slf4j/impl/JCLLoggerFactory.java | 2 +- .../org/slf4j/impl/Log4jLoggerFactory.java | 18 ++++++++++++++++++ 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/log4j-over-slf4j/src/main/java/org/apache/log4j/Log4jLoggerFactory.java b/log4j-over-slf4j/src/main/java/org/apache/log4j/Log4jLoggerFactory.java index 738b6a6c..30b35221 100644 --- a/log4j-over-slf4j/src/main/java/org/apache/log4j/Log4jLoggerFactory.java +++ b/log4j-over-slf4j/src/main/java/org/apache/log4j/Log4jLoggerFactory.java @@ -17,7 +17,6 @@ package org.apache.log4j; import org.apache.log4j.spi.LoggerFactory; -import org.slf4j.helpers.Util; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -36,23 +35,6 @@ class Log4jLoggerFactory { // String, Logger private static ConcurrentMap log4jLoggers = new ConcurrentHashMap(); - private static final String LOG4J_DELEGATION_LOOP_URL = "http://www.slf4j.org/codes.html#log4jDelegationLoop"; - - // check for delegation loops - static { - try { - Class.forName("org.slf4j.impl.Log4jLoggerFactory"); - String part1 = "Detected both log4j-over-slf4j.jar AND slf4j-log4j12.jar on the class path, preempting StackOverflowError. "; - String part2 = "See also " + LOG4J_DELEGATION_LOOP_URL + " for more details."; - - Util.report(part1); - Util.report(part2); - throw new IllegalStateException(part1 + part2); - } catch (ClassNotFoundException e) { - // this is the good case - } - } - public static Logger getLogger(String name) { org.apache.log4j.Logger instance = log4jLoggers.get(name); if (instance != null) { diff --git a/slf4j-jcl/src/main/java/org/slf4j/impl/JCLLoggerFactory.java b/slf4j-jcl/src/main/java/org/slf4j/impl/JCLLoggerFactory.java index 77ea88ec..db1014b0 100644 --- a/slf4j-jcl/src/main/java/org/slf4j/impl/JCLLoggerFactory.java +++ b/slf4j-jcl/src/main/java/org/slf4j/impl/JCLLoggerFactory.java @@ -46,7 +46,7 @@ public class JCLLoggerFactory implements ILoggerFactory { static { try { Class.forName("org.apache.commons.logging.impl.SLF4JLogFactory"); - String part1 = "Detected both jcl-over-slf4j.jar AND slf4j-jcl.jar on the class path, preempting StackOverflowError. "; + String part1 = "Detected both jcl-over-slf4j.jar AND bound slf4j-jcl.jar on the class path, preempting StackOverflowError. "; String part2 = "See also " + JCL_DELEGATION_LOOP_URL + " for more details."; Util.report(part1); diff --git a/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerFactory.java b/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerFactory.java index e801f9cc..991bddbe 100644 --- a/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerFactory.java +++ b/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerFactory.java @@ -30,6 +30,7 @@ import java.util.concurrent.ConcurrentMap; import org.apache.log4j.LogManager; import org.slf4j.ILoggerFactory; import org.slf4j.Logger; +import org.slf4j.helpers.Util; /** * Log4jLoggerFactory is an implementation of {@link ILoggerFactory} returning @@ -42,6 +43,23 @@ public class Log4jLoggerFactory implements ILoggerFactory { // key: name (String), value: a Log4jLoggerAdapter; ConcurrentMap loggerMap; + private static final String LOG4J_DELEGATION_LOOP_URL = "http://www.slf4j.org/codes.html#log4jDelegationLoop"; + + // check for delegation loops + static { + try { + Class.forName("org.apache.log4j.Log4jLoggerFactory"); + String part1 = "Detected both log4j-over-slf4j.jar AND bound slf4j-log4j12.jar on the class path, preempting StackOverflowError. "; + String part2 = "See also " + LOG4J_DELEGATION_LOOP_URL + " for more details."; + + Util.report(part1); + Util.report(part2); + throw new IllegalStateException(part1 + part2); + } catch (ClassNotFoundException e) { + // this is the good case + } + } + public Log4jLoggerFactory() { loggerMap = new ConcurrentHashMap(); } From dbe2d7271939a2e7f3197fd4ca5ce399e563dd31 Mon Sep 17 00:00:00 2001 From: Frans Orsel Date: Tue, 15 Dec 2015 17:26:35 +0100 Subject: [PATCH 06/11] Fix ordering of import and static variable/method --- .../src/main/java/org/slf4j/impl/Log4jLoggerFactory.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerFactory.java b/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerFactory.java index 991bddbe..6194bb7b 100644 --- a/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerFactory.java +++ b/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerFactory.java @@ -28,9 +28,9 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.log4j.LogManager; +import org.slf4j.helpers.Util; import org.slf4j.ILoggerFactory; import org.slf4j.Logger; -import org.slf4j.helpers.Util; /** * Log4jLoggerFactory is an implementation of {@link ILoggerFactory} returning @@ -40,9 +40,6 @@ import org.slf4j.helpers.Util; */ public class Log4jLoggerFactory implements ILoggerFactory { - // key: name (String), value: a Log4jLoggerAdapter; - ConcurrentMap loggerMap; - private static final String LOG4J_DELEGATION_LOOP_URL = "http://www.slf4j.org/codes.html#log4jDelegationLoop"; // check for delegation loops @@ -60,6 +57,9 @@ public class Log4jLoggerFactory implements ILoggerFactory { } } + // key: name (String), value: a Log4jLoggerAdapter; + ConcurrentMap loggerMap; + public Log4jLoggerFactory() { loggerMap = new ConcurrentHashMap(); } From dac5171d96256f6033913e4263590ef289604928 Mon Sep 17 00:00:00 2001 From: Ceki Gulcu Date: Tue, 15 Dec 2015 20:59:26 +0100 Subject: [PATCH 07/11] better docs, minor changes --- .../java/org/slf4j/impl/JCLLoggerFactory.java | 2 +- slf4j-site/src/site/pages/codes.html | 19 ++++++++++--------- slf4j-site/src/site/pages/news.html | 11 +++++++++++ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/slf4j-jcl/src/main/java/org/slf4j/impl/JCLLoggerFactory.java b/slf4j-jcl/src/main/java/org/slf4j/impl/JCLLoggerFactory.java index db1014b0..79be1048 100644 --- a/slf4j-jcl/src/main/java/org/slf4j/impl/JCLLoggerFactory.java +++ b/slf4j-jcl/src/main/java/org/slf4j/impl/JCLLoggerFactory.java @@ -58,7 +58,7 @@ public class JCLLoggerFactory implements ILoggerFactory { } // key: name (String), value: a JCLLoggerAdapter; - ConcurrentMap loggerMap; + final ConcurrentMap loggerMap; public JCLLoggerFactory() { loggerMap = new ConcurrentHashMap(); diff --git a/slf4j-site/src/site/pages/codes.html b/slf4j-site/src/site/pages/codes.html index f331be3b..766dd0a5 100755 --- a/slf4j-site/src/site/pages/codes.html +++ b/slf4j-site/src/site/pages/codes.html @@ -323,10 +323,11 @@ class B extends A {

The purpose of slf4j-log4j12 module is to delegate or redirect calls made to an SLF4J logger to log4j. The purpose of the log4j-over-slf4j module is to redirect calls made to a log4j - logger to SLF4J. If both slf4j-log4j12.jar and - log4j-over-slf4j.jar are present on the class path, a - StackOverflowError will inevitably occur immediately - after the first invocation of an SLF4J or a log4j logger. + logger to SLF4J. If SLF4J is bound withslf4j-log4j12.jar + and log4j-over-slf4j.jar is also present on the class + path, a StackOverflowError will inevitably occur + immediately after the first invocation of an SLF4J or a log4j + logger.

Here is how the exception might look like:

@@ -371,11 +372,11 @@ class B extends A {

The purpose of slf4j-jcl module is to delegate or redirect calls made to an SLF4J logger to jakarta commons logging (JCL). The purpose of the jcl-over-slf4j module is to redirect - calls made to a JCL logger to SLF4J. If both - slf4j-jcl.jar and jcl-over-slf4j.jar are present - on the class path, then a StackOverflowError will - inevitably occur immediately after the first invocation of an - SLF4J or a JCL logger. + calls made to a JCL logger to SLF4J. If SLF4J is bound with + slf4j-jcl.jar and jcl-over-slf4j.jar is also + present on the class path, then a StackOverflowError + will inevitably occur immediately after the first invocation of an + SLF4J or a JCL logger.

Here is how the exception might look like:

diff --git a/slf4j-site/src/site/pages/news.html b/slf4j-site/src/site/pages/news.html index 8f4de96e..fe416237 100755 --- a/slf4j-site/src/site/pages/news.html +++ b/slf4j-site/src/site/pages/news.html @@ -29,6 +29,17 @@
+

xxx December, 2015 - Release of SLF4J 1.7.14

+ +

Moved delegation check loop from log4j-over-slf4j.jar + to slf4j-log4j12.jar for better targeted loop checks. The + rationale behind the change is explained by Frans Orsel in SLF4J-345 who also + provided the relevant pull request. +

+ +
+

10th of November, 2015 - Release of SLF4J 1.7.13

From ea3cca72cd5a9329a06b788317a17e806ee8acd0 Mon Sep 17 00:00:00 2001 From: Ceki Gulcu Date: Thu, 21 Jan 2016 19:37:07 +0100 Subject: [PATCH 08/11] fix SLF4J-347 --- .../java/org/slf4j/impl/StaticMDCBinder.java | 9 ++++++++ .../org/slf4j/impl/StaticMarkerBinder.java | 10 +++++++++ slf4j-api/src/main/java/org/slf4j/MDC.java | 18 +++++++++++++++- .../main/java/org/slf4j/MarkerFactory.java | 21 ++++++++++++++++++- .../java/org/slf4j/impl/StaticMDCBinder.java | 10 +++++++++ .../org/slf4j/impl/StaticMarkerBinder.java | 10 +++++++++ .../java/org/slf4j/impl/StaticMDCBinder.java | 11 ++++++++++ .../org/slf4j/impl/StaticMarkerBinder.java | 10 +++++++++ .../java/org/slf4j/impl/StaticMDCBinder.java | 12 ++++++++++- .../org/slf4j/impl/StaticMarkerBinder.java | 10 +++++++++ .../java/org/slf4j/impl/StaticMDCBinder.java | 12 ++++++++++- .../org/slf4j/impl/StaticMarkerBinder.java | 10 +++++++++ .../java/org/slf4j/impl/StaticMDCBinder.java | 10 +++++++++ .../org/slf4j/impl/StaticMarkerBinder.java | 10 +++++++++ .../java/org/slf4j/impl/StaticMDCBinder.java | 10 +++++++++ .../org/slf4j/impl/StaticMarkerBinder.java | 12 ++++++++++- slf4j-site/src/site/pages/news.html | 9 +++++++- 17 files changed, 188 insertions(+), 6 deletions(-) diff --git a/slf4j-android/src/main/java/org/slf4j/impl/StaticMDCBinder.java b/slf4j-android/src/main/java/org/slf4j/impl/StaticMDCBinder.java index a484c525..aa61bfa5 100644 --- a/slf4j-android/src/main/java/org/slf4j/impl/StaticMDCBinder.java +++ b/slf4j-android/src/main/java/org/slf4j/impl/StaticMDCBinder.java @@ -44,6 +44,15 @@ public class StaticMDCBinder { private StaticMDCBinder() { } + /** + * Return the singleton of this class. + * + * @return the StaticMDCBinder singleton + * @since 1.7.14 + */ + public static final StaticMDCBinder getSingleton() { + return SINGLETON; + } /** * Currently this method always returns an instance of * {@link NOPMDCAdapter}. diff --git a/slf4j-android/src/main/java/org/slf4j/impl/StaticMarkerBinder.java b/slf4j-android/src/main/java/org/slf4j/impl/StaticMarkerBinder.java index 52b05bac..a25d3976 100644 --- a/slf4j-android/src/main/java/org/slf4j/impl/StaticMarkerBinder.java +++ b/slf4j-android/src/main/java/org/slf4j/impl/StaticMarkerBinder.java @@ -49,6 +49,16 @@ public class StaticMarkerBinder implements MarkerFactoryBinder { private StaticMarkerBinder() { } + /** + * Return the singleton of this class. + * + * @return the StaticMarkerBinder singleton + * @since 1.7.14 + */ + public static StaticMarkerBinder getSingleton() { + return SINGLETON; + } + /** * Currently this method always returns an instance of * {@link BasicMarkerFactory}. diff --git a/slf4j-api/src/main/java/org/slf4j/MDC.java b/slf4j-api/src/main/java/org/slf4j/MDC.java index 117774cf..20a9cdc5 100644 --- a/slf4j-api/src/main/java/org/slf4j/MDC.java +++ b/slf4j-api/src/main/java/org/slf4j/MDC.java @@ -85,9 +85,25 @@ public class MDC { private MDC() { } + /** + * As of SLF4J version 1.7.14, StaticMDCBinder classes shipping in various bindings + * come with a getSingleton() method. Previously only a field called SINGLETON was available. + * + * @return MDCAdapter + * @throws NoClassDefFoundError in case no binding is available + * @since 1.7.14 + */ + private static MDCAdapter bwCompatibleGetMDCAdapterFromBinder() throws NoClassDefFoundError { + try { + return StaticMDCBinder.getSingleton().getMDCA(); + } catch (NoSuchMethodError nsme) { + return StaticMDCBinder.SINGLETON.getMDCA(); + } + } + static { try { - mdcAdapter = StaticMDCBinder.SINGLETON.getMDCA(); + mdcAdapter = bwCompatibleGetMDCAdapterFromBinder(); } catch (NoClassDefFoundError ncde) { mdcAdapter = new NOPMDCAdapter(); String msg = ncde.getMessage(); diff --git a/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java b/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java index 8d50698d..73c65d23 100644 --- a/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java +++ b/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java @@ -26,7 +26,9 @@ package org.slf4j; import org.slf4j.helpers.BasicMarkerFactory; import org.slf4j.helpers.Util; +import org.slf4j.impl.StaticMDCBinder; import org.slf4j.impl.StaticMarkerBinder; +import org.slf4j.spi.MDCAdapter; /** * MarkerFactory is a utility class producing {@link Marker} instances as @@ -47,9 +49,26 @@ public class MarkerFactory { private MarkerFactory() { } + /** + * As of SLF4J version 1.7.14, StaticMDCBinder classes shipping in various bindings + * come with a getSingleton() method. Previously only a field called SINGLETON was available. + * + * @return MDCAdapter + * @throws NoClassDefFoundError in case no binding is available + * @since 1.7.14 + */ + private static IMarkerFactory bwCompatibleGetMarkerFactoryFromBinder() throws NoClassDefFoundError { + try { + return StaticMarkerBinder.getSingleton().getMarkerFactory(); + } catch (NoSuchMethodError nsme) { + return StaticMarkerBinder.SINGLETON.getMarkerFactory(); + } + } + + static { try { - markerFactory = StaticMarkerBinder.SINGLETON.getMarkerFactory(); + markerFactory = bwCompatibleGetMarkerFactoryFromBinder(); } catch (NoClassDefFoundError e) { markerFactory = new BasicMarkerFactory(); diff --git a/slf4j-api/src/main/java/org/slf4j/impl/StaticMDCBinder.java b/slf4j-api/src/main/java/org/slf4j/impl/StaticMDCBinder.java index 4fd65f40..9c8acdb0 100644 --- a/slf4j-api/src/main/java/org/slf4j/impl/StaticMDCBinder.java +++ b/slf4j-api/src/main/java/org/slf4j/impl/StaticMDCBinder.java @@ -42,6 +42,16 @@ public class StaticMDCBinder { private StaticMDCBinder() { throw new UnsupportedOperationException("This code should never make it into the jar"); } + + /** + * Return the singleton of this class. + * + * @return the StaticMDCBinder singleton + * @since 1.7.14 + */ + public static final StaticMDCBinder getSingleton() { + return SINGLETON; + } /** * Currently this method always returns an instance of diff --git a/slf4j-api/src/main/java/org/slf4j/impl/StaticMarkerBinder.java b/slf4j-api/src/main/java/org/slf4j/impl/StaticMarkerBinder.java index 0823b827..24f4a616 100644 --- a/slf4j-api/src/main/java/org/slf4j/impl/StaticMarkerBinder.java +++ b/slf4j-api/src/main/java/org/slf4j/impl/StaticMarkerBinder.java @@ -51,6 +51,16 @@ public class StaticMarkerBinder implements MarkerFactoryBinder { throw new UnsupportedOperationException("This code should never make it into the jar"); } + /** + * Return the singleton of this class. + * + * @return the StaticMarkerBinder singleton + * @since 1.7.14 + */ + public static StaticMarkerBinder getSingleton() { + return SINGLETON; + } + /** * Currently this method always returns an instance of * {@link BasicMarkerFactory}. diff --git a/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMDCBinder.java b/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMDCBinder.java index b35b89b0..d9945eb5 100644 --- a/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMDCBinder.java +++ b/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMDCBinder.java @@ -42,11 +42,22 @@ public class StaticMDCBinder { private StaticMDCBinder() { } + /** + * Return the singleton of this class. + * + * @return the StaticMDCBinder singleton + * @since 1.7.14 + */ + public static final StaticMDCBinder getSingleton() { + return SINGLETON; + } + /** * Currently this method always returns an instance of * {@link NOPMDCAdapter}. * * @return instance of NOPMDCAdapter + * @since 1.7.14 */ public MDCAdapter getMDCA() { return new NOPMDCAdapter(); diff --git a/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMarkerBinder.java b/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMarkerBinder.java index 1d255230..97935cb1 100644 --- a/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMarkerBinder.java +++ b/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMarkerBinder.java @@ -48,6 +48,16 @@ public class StaticMarkerBinder implements MarkerFactoryBinder { private StaticMarkerBinder() { } + /** + * Return the singleton of this class. + * + * @return the StaticMarkerBinder singleton + * @since 1.7.14 + */ + public static StaticMarkerBinder getSingleton() { + return SINGLETON; + } + /** * Currently this method always returns an instance of * {@link BasicMarkerFactory}. diff --git a/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMDCBinder.java b/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMDCBinder.java index bff523db..753e83f2 100644 --- a/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMDCBinder.java +++ b/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMDCBinder.java @@ -41,7 +41,17 @@ public class StaticMDCBinder { private StaticMDCBinder() { } - + + /** + * Return the singleton of this class. + * + * @return the StaticMDCBinder singleton + * @since 1.7.14 + */ + public static final StaticMDCBinder getSingleton() { + return SINGLETON; + } + /** * Currently this method always returns an instance of * {@link BasicMDCAdapter}. diff --git a/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMarkerBinder.java b/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMarkerBinder.java index 1d255230..97935cb1 100644 --- a/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMarkerBinder.java +++ b/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMarkerBinder.java @@ -48,6 +48,16 @@ public class StaticMarkerBinder implements MarkerFactoryBinder { private StaticMarkerBinder() { } + /** + * Return the singleton of this class. + * + * @return the StaticMarkerBinder singleton + * @since 1.7.14 + */ + public static StaticMarkerBinder getSingleton() { + return SINGLETON; + } + /** * Currently this method always returns an instance of * {@link BasicMarkerFactory}. diff --git a/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMDCBinder.java b/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMDCBinder.java index 77742309..a0e815fd 100644 --- a/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMDCBinder.java +++ b/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMDCBinder.java @@ -40,7 +40,17 @@ public class StaticMDCBinder { private StaticMDCBinder() { } - + + /** + * Return the singleton of this class. + * + * @return the StaticMDCBinder singleton + * @since 1.7.14 + */ + public static final StaticMDCBinder getSingleton() { + return SINGLETON; + } + /** * Currently this method always returns an instance of * {@link StaticMDCBinder}. diff --git a/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMarkerBinder.java b/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMarkerBinder.java index 1d255230..97935cb1 100644 --- a/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMarkerBinder.java +++ b/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMarkerBinder.java @@ -48,6 +48,16 @@ public class StaticMarkerBinder implements MarkerFactoryBinder { private StaticMarkerBinder() { } + /** + * Return the singleton of this class. + * + * @return the StaticMarkerBinder singleton + * @since 1.7.14 + */ + public static StaticMarkerBinder getSingleton() { + return SINGLETON; + } + /** * Currently this method always returns an instance of * {@link BasicMarkerFactory}. diff --git a/slf4j-nop/src/main/java/org/slf4j/impl/StaticMDCBinder.java b/slf4j-nop/src/main/java/org/slf4j/impl/StaticMDCBinder.java index 086b0169..35dc8d80 100644 --- a/slf4j-nop/src/main/java/org/slf4j/impl/StaticMDCBinder.java +++ b/slf4j-nop/src/main/java/org/slf4j/impl/StaticMDCBinder.java @@ -42,6 +42,16 @@ public class StaticMDCBinder { private StaticMDCBinder() { } + /** + * Return the singleton of this class. + * + * @return the StaticMDCBinder singleton + * @since 1.7.14 + */ + public static final StaticMDCBinder getSingleton() { + return SINGLETON; + } + /** * Currently this method always returns an instance of * {@link StaticMDCBinder}. diff --git a/slf4j-nop/src/main/java/org/slf4j/impl/StaticMarkerBinder.java b/slf4j-nop/src/main/java/org/slf4j/impl/StaticMarkerBinder.java index 1d255230..97935cb1 100644 --- a/slf4j-nop/src/main/java/org/slf4j/impl/StaticMarkerBinder.java +++ b/slf4j-nop/src/main/java/org/slf4j/impl/StaticMarkerBinder.java @@ -48,6 +48,16 @@ public class StaticMarkerBinder implements MarkerFactoryBinder { private StaticMarkerBinder() { } + /** + * Return the singleton of this class. + * + * @return the StaticMarkerBinder singleton + * @since 1.7.14 + */ + public static StaticMarkerBinder getSingleton() { + return SINGLETON; + } + /** * Currently this method always returns an instance of * {@link BasicMarkerFactory}. diff --git a/slf4j-simple/src/main/java/org/slf4j/impl/StaticMDCBinder.java b/slf4j-simple/src/main/java/org/slf4j/impl/StaticMDCBinder.java index 086b0169..a88f2bfc 100644 --- a/slf4j-simple/src/main/java/org/slf4j/impl/StaticMDCBinder.java +++ b/slf4j-simple/src/main/java/org/slf4j/impl/StaticMDCBinder.java @@ -42,6 +42,16 @@ public class StaticMDCBinder { private StaticMDCBinder() { } + /** + * Return the singleton of this class. + * + * @return the StaticMDCBinder singleton + * @since 1.7.14 + */ + public static final StaticMDCBinder getSingleton() { + return SINGLETON; + } + /** * Currently this method always returns an instance of * {@link StaticMDCBinder}. diff --git a/slf4j-simple/src/main/java/org/slf4j/impl/StaticMarkerBinder.java b/slf4j-simple/src/main/java/org/slf4j/impl/StaticMarkerBinder.java index 435a924b..ef1a9d90 100644 --- a/slf4j-simple/src/main/java/org/slf4j/impl/StaticMarkerBinder.java +++ b/slf4j-simple/src/main/java/org/slf4j/impl/StaticMarkerBinder.java @@ -48,7 +48,17 @@ public class StaticMarkerBinder implements MarkerFactoryBinder { private StaticMarkerBinder() { } - + + /** + * Return the singleton of this class. + * + * @return the StaticMarkerBinder singleton + * @since 1.7.14 + */ + public static StaticMarkerBinder getSingleton() { + return SINGLETON; + } + /** * Currently this method always returns an instance of * {@link BasicMarkerFactory}. diff --git a/slf4j-site/src/site/pages/news.html b/slf4j-site/src/site/pages/news.html index fe416237..de75cc82 100755 --- a/slf4j-site/src/site/pages/news.html +++ b/slf4j-site/src/site/pages/news.html @@ -29,7 +29,7 @@
-

xxx December, 2015 - Release of SLF4J 1.7.14

+

xxx January, 2016 - Release of SLF4J 1.7.14

Moved delegation check loop from log4j-over-slf4j.jar to slf4j-log4j12.jar for better targeted loop checks. The @@ -38,6 +38,13 @@ provided the relevant pull request.

+

The StaticMarkerBinder and StaticMDCBinder classes shipping in + various slf4j bindings now offer a getSingletion() method. This + change was requested by rufoa SLF4J-347 for + implementing an SLF4J binding in Clojure. +

+

10th of November, 2015 - Release of SLF4J 1.7.13

From 039df718381c45a0bd454c875b20b5b638e8741c Mon Sep 17 00:00:00 2001 From: Ceki Gulcu Date: Fri, 22 Jan 2016 11:02:52 +0100 Subject: [PATCH 09/11] minnor edits and improvements --- slf4j-api/src/main/java/org/slf4j/MDC.java | 4 ++- .../main/java/org/slf4j/MarkerFactory.java | 25 +++++++++---------- slf4j-site/src/site/pages/news.html | 16 ++++++++---- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/slf4j-api/src/main/java/org/slf4j/MDC.java b/slf4j-api/src/main/java/org/slf4j/MDC.java index 20a9cdc5..08e6d0a9 100644 --- a/slf4j-api/src/main/java/org/slf4j/MDC.java +++ b/slf4j-api/src/main/java/org/slf4j/MDC.java @@ -87,7 +87,8 @@ public class MDC { /** * As of SLF4J version 1.7.14, StaticMDCBinder classes shipping in various bindings - * come with a getSingleton() method. Previously only a field called SINGLETON was available. + * come with a getSingleton() method. Previously only a public field called SINGLETON + * was available. * * @return MDCAdapter * @throws NoClassDefFoundError in case no binding is available @@ -97,6 +98,7 @@ public class MDC { try { return StaticMDCBinder.getSingleton().getMDCA(); } catch (NoSuchMethodError nsme) { + // binding is probably a version of SLF4J older than 1.7.14 return StaticMDCBinder.SINGLETON.getMDCA(); } } diff --git a/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java b/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java index 73c65d23..7eff41f6 100644 --- a/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java +++ b/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java @@ -26,9 +26,7 @@ package org.slf4j; import org.slf4j.helpers.BasicMarkerFactory; import org.slf4j.helpers.Util; -import org.slf4j.impl.StaticMDCBinder; import org.slf4j.impl.StaticMarkerBinder; -import org.slf4j.spi.MDCAdapter; /** * MarkerFactory is a utility class producing {@link Marker} instances as @@ -44,16 +42,17 @@ import org.slf4j.spi.MDCAdapter; * @author Ceki Gülcü */ public class MarkerFactory { - static IMarkerFactory markerFactory; + static IMarkerFactory MARKER_FACTORY; private MarkerFactory() { } /** - * As of SLF4J version 1.7.14, StaticMDCBinder classes shipping in various bindings - * come with a getSingleton() method. Previously only a field called SINGLETON was available. + * As of SLF4J version 1.7.14, StaticMarkerBinder classes shipping in various bindings + * come with a getSingleton() method. Previously only a public field called SINGLETON + * was available. * - * @return MDCAdapter + * @return IMarkerFactory * @throws NoClassDefFoundError in case no binding is available * @since 1.7.14 */ @@ -61,17 +60,17 @@ public class MarkerFactory { try { return StaticMarkerBinder.getSingleton().getMarkerFactory(); } catch (NoSuchMethodError nsme) { + // binding is probably a version of SLF4J older than 1.7.14 return StaticMarkerBinder.SINGLETON.getMarkerFactory(); } } - + // this is where the binding happens static { try { - markerFactory = bwCompatibleGetMarkerFactoryFromBinder(); + MARKER_FACTORY = bwCompatibleGetMarkerFactoryFromBinder(); } catch (NoClassDefFoundError e) { - markerFactory = new BasicMarkerFactory(); - + MARKER_FACTORY = new BasicMarkerFactory(); } catch (Exception e) { // we should never get here Util.report("Unexpected failure while binding MarkerFactory", e); @@ -87,7 +86,7 @@ public class MarkerFactory { * @return marker */ public static Marker getMarker(String name) { - return markerFactory.getMarker(name); + return MARKER_FACTORY.getMarker(name); } /** @@ -98,7 +97,7 @@ public class MarkerFactory { * @since 1.5.1 */ public static Marker getDetachedMarker(String name) { - return markerFactory.getDetachedMarker(name); + return MARKER_FACTORY.getDetachedMarker(name); } /** @@ -110,6 +109,6 @@ public class MarkerFactory { * @return the IMarkerFactory instance in use */ public static IMarkerFactory getIMarkerFactory() { - return markerFactory; + return MARKER_FACTORY; } } \ No newline at end of file diff --git a/slf4j-site/src/site/pages/news.html b/slf4j-site/src/site/pages/news.html index de75cc82..8ed12784 100755 --- a/slf4j-site/src/site/pages/news.html +++ b/slf4j-site/src/site/pages/news.html @@ -38,11 +38,17 @@ provided the relevant pull request.

-

The StaticMarkerBinder and StaticMDCBinder classes shipping in - various slf4j bindings now offer a getSingletion() method. This - change was requested by rufoa SLF4J-347 for - implementing an SLF4J binding in Clojure. +

The StaticMarkerBinder and + StaticMDCBinder classes shipping in various SLF4J + bindings now offer a getSingletion() method. The + org.slf4j.MDC and MarkerFactory classes + now perform binding by invoking the getSingleton() + method first and if in the presence of an older version of SLF4J + with said method missing, then by accessing the SINGLETON + field. This bacward compatible change was requested by Rufus + Alexander in SLF4J-347 in order + to implement an SLF4J binding in Clojure.


From 638d74d2b31591bd5d9d7a0cb1297a1120ec86c6 Mon Sep 17 00:00:00 2001 From: Ceki Gulcu Date: Fri, 22 Jan 2016 12:51:10 +0100 Subject: [PATCH 10/11] blurb about SLF4J-167 --- .../test/java/org/slf4j/DoubleCheckedInt.java | 141 ++++++++++++++++++ slf4j-site/src/site/pages/news.html | 21 ++- 2 files changed, 160 insertions(+), 2 deletions(-) create mode 100755 slf4j-api/src/test/java/org/slf4j/DoubleCheckedInt.java diff --git a/slf4j-api/src/test/java/org/slf4j/DoubleCheckedInt.java b/slf4j-api/src/test/java/org/slf4j/DoubleCheckedInt.java new file mode 100755 index 00000000..9aa86b07 --- /dev/null +++ b/slf4j-api/src/test/java/org/slf4j/DoubleCheckedInt.java @@ -0,0 +1,141 @@ +package org.slf4j; + +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +/** + * This class demonstrates that threads accessing the STATE variable always see a consistent value. + * + * During ongoing initialization the observed value is either ONGOING_INITIALIZATION + * or one of {SUCCESS, FAILURE}. + * + * Post initialization the observed value is always one of {SUCCESS, FAILURE}. + * + * See also http://jira.qos.ch/browse/SLF4J-167 + * + * @author ceki + * + */ +public class DoubleCheckedInt { + + final static int THREAD_COUNT = 10 + Runtime.getRuntime().availableProcessors() * 2; + final static int UNINITIALIZED_STATE = 0; + final static int ONGOING_INITIALIZATION = 1; + final static int SUCCESS = 2; + final static int FAILURE = 3; + final static int NUMBER_OF_STATES = FAILURE + 1; + + private static int STATE = UNINITIALIZED_STATE; + + public static int getState() { + if (STATE == 0) { + synchronized (DoubleCheckedInt.class) { + if (STATE == UNINITIALIZED_STATE) { + STATE = ONGOING_INITIALIZATION; + long r = System.nanoTime(); + try { + Thread.sleep(10); + } catch (InterruptedException e) { + } + if (r % 2 == 0) { + STATE = SUCCESS; + } else { + STATE = FAILURE; + } + } + } + } + return STATE; + } + + static public void main(String[] args) throws InterruptedException, BrokenBarrierException { + StateAccessingThread[] preInitializationThreads = harness(); + check(preInitializationThreads, false); + + System.out.println("============"); + StateAccessingThread[] postInitializationThreads = harness(); + check(postInitializationThreads, true); + } + + private static StateAccessingThread[] harness() throws InterruptedException, BrokenBarrierException { + StateAccessingThread[] threads = new StateAccessingThread[THREAD_COUNT]; + final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1); + for (int i = 0; i < THREAD_COUNT; i++) { + threads[i] = new StateAccessingThread(barrier); + threads[i].start(); + } + + barrier.await(); + for (int i = 0; i < THREAD_COUNT; i++) { + threads[i].join(); + } + return threads; + } + + private static void check(StateAccessingThread[] threads, boolean postInit) { + + int[] stateCount = getStateCount(threads); + printStateCount(stateCount); + + if (stateCount[UNINITIALIZED_STATE] != 0) { + throw new IllegalStateException("getState() should never return a zero value"); + } + + if (stateCount[SUCCESS] != 0 && stateCount[FAILURE] != 0) { + throw new IllegalStateException("getState() should return consistent values"); + } + + if (postInit) { + if (stateCount[SUCCESS] != THREAD_COUNT && stateCount[FAILURE] != THREAD_COUNT) { + throw new IllegalStateException("getState() should return consistent values"); + } + } + + } + + private static void printStateCount(int[] stateCount) { + for (int i = 0; i < NUMBER_OF_STATES; i++) { + switch (i) { + case UNINITIALIZED_STATE: + System.out.println("UNINITIALIZED_STATE count: " + stateCount[i]); + break; + case ONGOING_INITIALIZATION: + System.out.println("ONGOING_INITIALIZATION count: " + stateCount[i]); + break; + case SUCCESS: + System.out.println("SUCCESS count: " + stateCount[i]); + break; + case FAILURE: + System.out.println("FAILURE count: " + stateCount[i]); + break; + } + } + } + + private static int[] getStateCount(StateAccessingThread[] threads) { + int[] valCount = new int[NUMBER_OF_STATES]; + for (int i = 0; i < threads.length; i++) { + int val = threads[i].state; + valCount[val] = valCount[val] + 1; + } + return valCount; + } + + static class StateAccessingThread extends Thread { + public int state = -1; + final CyclicBarrier barrier; + + StateAccessingThread(CyclicBarrier barrier) { + this.barrier = barrier; + } + + public void run() { + try { + barrier.await(); + } catch (Exception e) { + e.printStackTrace(); + } + state = DoubleCheckedInt.getState(); + } + }; +} diff --git a/slf4j-site/src/site/pages/news.html b/slf4j-site/src/site/pages/news.html index 8ed12784..5ad9bca5 100755 --- a/slf4j-site/src/site/pages/news.html +++ b/slf4j-site/src/site/pages/news.html @@ -31,6 +31,20 @@

xxx January, 2016 - Release of SLF4J 1.7.14

+ +

The assignment of the INITIALIZATION_STATE variable in + LoggerFactory is now guaranteed to be consistent for + multi-thread initializations. More specifically, only one thread + will see INITIALIZATION_STATE as UNINITIALIZED with all other + threads observing either ONGOING_INITIALIZATION or the final result + of the initialization. However, SLF4J initialization is still + non-blocking and re-entrant, in the sense that if some thread tries + to obtain loggers during ongoing initialization by another (or + same) thread, instances of SubstituteLogger are + returned. This fixes SLF4J-167

. + +

Moved delegation check loop from log4j-over-slf4j.jar to slf4j-log4j12.jar for better targeted loop checks. The rationale behind the change is explained by Frans Orsel in + +

The StaticMarkerBinder and StaticMDCBinder classes shipping in various SLF4J bindings now offer a getSingletion() method. The @@ -45,10 +61,11 @@ now perform binding by invoking the getSingleton() method first and if in the presence of an older version of SLF4J with said method missing, then by accessing the SINGLETON - field. This bacward compatible change was requested by Rufus + field. This backward compatible change was requested by Rufus Alexander in SLF4J-347 in order - to implement an SLF4J binding in Clojure. + to implement an SLF4J binding in Clojure, namely slf4j-timbre.


From fc0ad8652b8485175a6295648c05425284b8619a Mon Sep 17 00:00:00 2001 From: Ceki Gulcu Date: Fri, 22 Jan 2016 13:20:35 +0100 Subject: [PATCH 11/11] fix SLF4J-328 --- .../src/main/java/org/slf4j/LoggerFactory.java | 14 ++++++++++++++ slf4j-site/src/site/pages/news.html | 7 ++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/slf4j-api/src/main/java/org/slf4j/LoggerFactory.java b/slf4j-api/src/main/java/org/slf4j/LoggerFactory.java index 65b9de08..0af5ce44 100755 --- a/slf4j-api/src/main/java/org/slf4j/LoggerFactory.java +++ b/slf4j-api/src/main/java/org/slf4j/LoggerFactory.java @@ -84,6 +84,8 @@ public final class LoggerFactory { // Support for detecting mismatched logger names. static final String DETECT_LOGGER_NAME_MISMATCH_PROPERTY = "slf4j.detectLoggerNameMismatch"; + static final String JAVA_VENDOR_PROPERTY = "java.vendor.url"; + static boolean DETECT_LOGGER_NAME_MISMATCH = Util.safeGetBooleanSystemProperty(DETECT_LOGGER_NAME_MISMATCH_PROPERTY); /** @@ -254,6 +256,11 @@ public final class LoggerFactory { * */ private static void reportMultipleBindingAmbiguity(Set staticLoggerBinderPathSet) { + if(isAndroid()) { + // skip check under android, see also http://jira.qos.ch/browse/SLF4J-328 + return; + } + if (isAmbiguousStaticLoggerBinderPathSet(staticLoggerBinderPathSet)) { Util.report("Class path contains multiple SLF4J bindings."); for (URL path : staticLoggerBinderPathSet) { @@ -263,6 +270,13 @@ public final class LoggerFactory { } } + private static boolean isAndroid() { + String vendor = Util.safeGetSystemProperty(JAVA_VENDOR_PROPERTY); + if(vendor == null) + return false; + return vendor.toLowerCase().contains("android"); + } + private static void reportActualBinding(Set staticLoggerBinderPathSet) { if (isAmbiguousStaticLoggerBinderPathSet(staticLoggerBinderPathSet)) { Util.report("Actual binding is of type [" + StaticLoggerBinder.getSingleton().getLoggerFactoryClassStr() + "]"); diff --git a/slf4j-site/src/site/pages/news.html b/slf4j-site/src/site/pages/news.html index 5ad9bca5..dcc4feac 100755 --- a/slf4j-site/src/site/pages/news.html +++ b/slf4j-site/src/site/pages/news.html @@ -52,7 +52,12 @@ provided the relevant pull request.

- +

During initialization the binding ambiguity check is skipped + under Android in order to improve performance. This change was + requested by Nitin Verma in SLF4J-328 who also + provided the relevant patch. +

The StaticMarkerBinder and StaticMDCBinder classes shipping in various SLF4J