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