diff --git a/integration/pom.xml b/integration/pom.xml index 2998e50..02af7f9 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.13 + 1.7.14 integration diff --git a/jcl-over-slf4j/pom.xml b/jcl-over-slf4j/pom.xml index e372332..fdadd29 100644 --- a/jcl-over-slf4j/pom.xml +++ b/jcl-over-slf4j/pom.xml @@ -5,7 +5,7 @@ org.slf4j slf4j-parent - 1.7.13 + 1.7.14 4.0.0 diff --git a/jul-to-slf4j/pom.xml b/jul-to-slf4j/pom.xml index dc4bfe2..4fba41f 100644 --- a/jul-to-slf4j/pom.xml +++ b/jul-to-slf4j/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.13 + 1.7.14 jul-to-slf4j diff --git a/log4j-over-slf4j/pom.xml b/log4j-over-slf4j/pom.xml index a55e01b..1b21134 100644 --- a/log4j-over-slf4j/pom.xml +++ b/log4j-over-slf4j/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.13 + 1.7.14 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 707f935..4bf7e77 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; @@ -35,23 +34,6 @@ // 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); diff --git a/osgi-over-slf4j/pom.xml b/osgi-over-slf4j/pom.xml index ce5f9d4..7c71d60 100644 --- a/osgi-over-slf4j/pom.xml +++ b/osgi-over-slf4j/pom.xml @@ -7,12 +7,12 @@ org.slf4j slf4j-parent - 1.7.13 + 1.7.14 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 0000000..97b13da --- /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 +Bundle-Category: osgi +Import-Package: org.osgi.framework;version="[1.5,2)",org.osgi.service.log;version="[1.3,2)",org.slf4j;version=${parsedVersion.osgiVersion} diff --git a/pom.xml b/pom.xml index bb1dd26..771eec4 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.slf4j slf4j-parent - 1.7.13 + 1.7.14 pom SLF4J @@ -407,8 +407,8 @@ - pixie - scp://pixie.qos.ch/var/www/www.slf4j.org/htdocs/ + tao + scp://tao.qos.ch/var/www/www.slf4j.org/htdocs/ diff --git a/slf4j-android/pom.xml b/slf4j-android/pom.xml index 3696b41..6a66ab4 100644 --- a/slf4j-android/pom.xml +++ b/slf4j-android/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.13 + 1.7.14 slf4j-android 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 e3b51fe..0ab2246 100644 --- a/slf4j-android/src/main/java/org/slf4j/impl/StaticLoggerBinder.java +++ b/slf4j-android/src/main/java/org/slf4j/impl/StaticLoggerBinder.java @@ -52,11 +52,12 @@ } /** - * Declare the version of the SLF4J API this implementation is compiled against. - * The value of this field is usually modified with each release. + * Declare the version of the SLF4J API this implementation is compiled against. + * 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.6.99"; // !final + public static String REQUESTED_API_VERSION = "1.6.99"; // !final + private static final String loggerFactoryClassStr = AndroidLoggerFactory.class.getName(); 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 05c8934..9480c64 100644 --- a/slf4j-android/src/main/java/org/slf4j/impl/StaticMDCBinder.java +++ b/slf4j-android/src/main/java/org/slf4j/impl/StaticMDCBinder.java @@ -45,6 +45,15 @@ } /** + * 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 049e67f..e744bd9 100644 --- a/slf4j-android/src/main/java/org/slf4j/impl/StaticMarkerBinder.java +++ b/slf4j-android/src/main/java/org/slf4j/impl/StaticMarkerBinder.java @@ -50,6 +50,16 @@ } /** + * 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/pom.xml b/slf4j-api/pom.xml index 5b9c1b3..6e79940 100644 --- a/slf4j-api/pom.xml +++ b/slf4j-api/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.13 + 1.7.14 slf4j-api diff --git a/slf4j-api/src/main/java/org/slf4j/LoggerFactory.java b/slf4j-api/src/main/java/org/slf4j/LoggerFactory.java index 3c8c482..4bc830b 100644 --- a/slf4j-api/src/main/java/org/slf4j/LoggerFactory.java +++ b/slf4j-api/src/main/java/org/slf4j/LoggerFactory.java @@ -84,6 +84,8 @@ // 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); /** @@ -222,7 +224,7 @@ // the class itself. private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class"; - private static Set findPossibleStaticLoggerBinderPathSet() { + static Set findPossibleStaticLoggerBinderPathSet() { // use Set instead of list in order to deal with bug #138 // LinkedHashSet appropriate here because it preserves insertion order during iteration Set staticLoggerBinderPathSet = new LinkedHashSet(); @@ -254,6 +256,11 @@ * */ 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) { @@ -261,6 +268,13 @@ } Util.report("See " + MULTIPLE_BINDINGS_URL + " for an explanation."); } + } + + 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) { @@ -324,8 +338,12 @@ */ public static ILoggerFactory getILoggerFactory() { if (INITIALIZATION_STATE == UNINITIALIZED) { - INITIALIZATION_STATE = ONGOING_INITIALIZATION; - performInitialization(); + synchronized (LoggerFactory.class) { + if (INITIALIZATION_STATE == UNINITIALIZED) { + INITIALIZATION_STATE = ONGOING_INITIALIZATION; + performInitialization(); + } + } } switch (INITIALIZATION_STATE) { case SUCCESSFUL_INITIALIZATION: diff --git a/slf4j-api/src/main/java/org/slf4j/MDC.java b/slf4j-api/src/main/java/org/slf4j/MDC.java index 7eadaee..49ce2b7 100644 --- a/slf4j-api/src/main/java/org/slf4j/MDC.java +++ b/slf4j-api/src/main/java/org/slf4j/MDC.java @@ -85,9 +85,27 @@ private MDC() { } + /** + * As of SLF4J version 1.7.14, StaticMDCBinder classes shipping in various bindings + * come with a getSingleton() method. Previously only a public 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) { + // binding is probably a version of SLF4J older than 1.7.14 + 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 2d0aad7..8c309a1 100644 --- a/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java +++ b/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java @@ -42,17 +42,35 @@ * @author Ceki Gülcü */ public class MarkerFactory { - static IMarkerFactory markerFactory; + static IMarkerFactory MARKER_FACTORY; private MarkerFactory() { } + /** + * 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 IMarkerFactory + * @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) { + // 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 = StaticMarkerBinder.SINGLETON.getMarkerFactory(); + 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); @@ -68,7 +86,7 @@ * @return marker */ public static Marker getMarker(String name) { - return markerFactory.getMarker(name); + return MARKER_FACTORY.getMarker(name); } /** @@ -79,7 +97,7 @@ * @since 1.5.1 */ public static Marker getDetachedMarker(String name) { - return markerFactory.getDetachedMarker(name); + return MARKER_FACTORY.getDetachedMarker(name); } /** @@ -91,6 +109,6 @@ * @return the IMarkerFactory instance in use */ public static IMarkerFactory getIMarkerFactory() { - return markerFactory; + return MARKER_FACTORY; } }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 f075571..e044d53 100644 --- a/slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java +++ b/slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java @@ -54,7 +54,7 @@ /** * Declare the version of the SLF4J API this implementation is compiled against. - * The value of this field is usually modified with each release. + * 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.6.99"; // !final 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 90e3274..fc26bf5 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 @@ 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 173b68c..211f78d 100644 --- a/slf4j-api/src/main/java/org/slf4j/impl/StaticMarkerBinder.java +++ b/slf4j-api/src/main/java/org/slf4j/impl/StaticMarkerBinder.java @@ -52,6 +52,16 @@ } /** + * 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/test/java/org/slf4j/DoubleCheckedInt.java b/slf4j-api/src/test/java/org/slf4j/DoubleCheckedInt.java new file mode 100644 index 0000000..2978ee0 --- /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-api/src/test/java/org/slf4j/FindStaticLoggerBinderPathsPerfTest.java b/slf4j-api/src/test/java/org/slf4j/FindStaticLoggerBinderPathsPerfTest.java new file mode 100644 index 0000000..9c3fdd2 --- /dev/null +++ b/slf4j-api/src/test/java/org/slf4j/FindStaticLoggerBinderPathsPerfTest.java @@ -0,0 +1,55 @@ +package org.slf4j; + +import org.junit.Ignore; +import org.junit.Test; + +public class FindStaticLoggerBinderPathsPerfTest { + + @Test + @Ignore + public void test() { + long duration = timeFindBindingSetCall(); + System.out.println(duration / (1000) + " microseconds"); + + int count = 10; + long sum = 0; + for (int i = 0; i < count; i++) { + sum += timeFindBindingSetCall(); + } + System.out.println(sum / (count * 1000) + " microseconds in average"); + } + + @Test + public void testAsync() throws InterruptedException { + long start = System.nanoTime(); + FindPathSetThread thread = new FindPathSetThread(); + thread.start(); + long end = System.nanoTime(); + + long duration = end - start; + System.out.println(duration / (1000) + " microseconds"); + + thread.join(); + } + + long timeFindBindingSetCall() { + long start = System.nanoTime(); + + LoggerFactory.findPossibleStaticLoggerBinderPathSet(); + long end = System.nanoTime(); + return end - start; + + } + + static class FindPathSetThread extends Thread { + + public void run() { + long start = System.nanoTime(); + LoggerFactory.findPossibleStaticLoggerBinderPathSet(); + long end = System.nanoTime(); + + System.out.println("Found set in " + (end - start)/1000 + " microseconds"); + + } + } +} diff --git a/slf4j-ext/pom.xml b/slf4j-ext/pom.xml index 38fb357..23c39ef 100644 --- a/slf4j-ext/pom.xml +++ b/slf4j-ext/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.13 + 1.7.14 slf4j-ext diff --git a/slf4j-jcl/pom.xml b/slf4j-jcl/pom.xml index 1d17a62..3bb0aff 100644 --- a/slf4j-jcl/pom.xml +++ b/slf4j-jcl/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.13 + 1.7.14 slf4j-jcl 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 016089c..024e80a 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 @@ 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); @@ -58,7 +58,7 @@ } // key: name (String), value: a JCLLoggerAdapter; - ConcurrentMap loggerMap; + final ConcurrentMap loggerMap; public JCLLoggerFactory() { loggerMap = new ConcurrentHashMap(); 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 f843c5c..67a81f4 100644 --- a/slf4j-jcl/src/main/java/org/slf4j/impl/StaticLoggerBinder.java +++ b/slf4j-jcl/src/main/java/org/slf4j/impl/StaticLoggerBinder.java @@ -51,13 +51,13 @@ } /** - * Version tag used to check compatibility. The value of this field is - * modified with each release. + * Declare the version of the SLF4J API this implementation is compiled against. + * 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.6.99"; // !final - // to avoid constant folding by the compiler, this field must *not* be final - public static String REQUESTED_API_VERSION = "1.6.99"; - + // Binding specific code: private static final String loggerFactoryClassStr = JCLLoggerFactory.class.getName(); 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 280b9ef..3a63ba8 100644 --- a/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMDCBinder.java +++ b/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMDCBinder.java @@ -43,10 +43,21 @@ } /** + * 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 2857ef0..98218ed 100644 --- a/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMarkerBinder.java +++ b/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMarkerBinder.java @@ -49,6 +49,16 @@ } /** + * 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/pom.xml b/slf4j-jdk14/pom.xml index f22250e..0faf805 100644 --- a/slf4j-jdk14/pom.xml +++ b/slf4j-jdk14/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.13 + 1.7.14 slf4j-jdk14 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 13fe9d2..ebf8ae1 100644 --- a/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticLoggerBinder.java +++ b/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticLoggerBinder.java @@ -53,7 +53,7 @@ /** * Declare the version of the SLF4J API this implementation is compiled against. - * The value of this field is usually modified with each release. + * 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.6.99"; // !final 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 328a012..4948a69 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 @@ 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 2857ef0..98218ed 100644 --- a/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMarkerBinder.java +++ b/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMarkerBinder.java @@ -49,6 +49,16 @@ } /** + * 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/pom.xml b/slf4j-log4j12/pom.xml index b1930b6..bf180c4 100644 --- a/slf4j-log4j12/pom.xml +++ b/slf4j-log4j12/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.13 + 1.7.14 slf4j-log4j12 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 5530c23..fa1b292 100644 --- a/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerFactory.java +++ b/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerFactory.java @@ -28,6 +28,7 @@ import java.util.concurrent.ConcurrentMap; import org.apache.log4j.LogManager; +import org.slf4j.helpers.Util; import org.slf4j.ILoggerFactory; import org.slf4j.Logger; @@ -38,6 +39,23 @@ * @author Ceki Gülcü */ public class Log4jLoggerFactory implements ILoggerFactory { + + 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 + } + } // key: name (String), value: a Log4jLoggerAdapter; ConcurrentMap loggerMap; 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 c8b2df4..c2da612 100644 --- a/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticLoggerBinder.java +++ b/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticLoggerBinder.java @@ -54,8 +54,8 @@ } /** - * Declare the version of the SLF4J API this implementation is compiled - * against. The value of this field is usually modified with each release. + * Declare the version of the SLF4J API this implementation is compiled against. + * 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.6.99"; // !final 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 15c5d2c..78c8bcd 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 @@ 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 2857ef0..98218ed 100644 --- a/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMarkerBinder.java +++ b/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMarkerBinder.java @@ -49,6 +49,16 @@ } /** + * 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-migrator/pom.xml b/slf4j-migrator/pom.xml index 3ae6c11..3d67e10 100644 --- a/slf4j-migrator/pom.xml +++ b/slf4j-migrator/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.13 + 1.7.14 slf4j-migrator diff --git a/slf4j-nop/pom.xml b/slf4j-nop/pom.xml index 1602c26..073ea4c 100644 --- a/slf4j-nop/pom.xml +++ b/slf4j-nop/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.13 + 1.7.14 slf4j-nop 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 f8d611e..243cbfe 100644 --- a/slf4j-nop/src/main/java/org/slf4j/impl/StaticLoggerBinder.java +++ b/slf4j-nop/src/main/java/org/slf4j/impl/StaticLoggerBinder.java @@ -54,7 +54,7 @@ /** * Declare the version of the SLF4J API this implementation is compiled against. - * The value of this field is usually modified with each release. + * 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.6.99"; // !final 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 e46c063..c570b46 100644 --- a/slf4j-nop/src/main/java/org/slf4j/impl/StaticMDCBinder.java +++ b/slf4j-nop/src/main/java/org/slf4j/impl/StaticMDCBinder.java @@ -43,6 +43,16 @@ } /** + * 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 2857ef0..98218ed 100644 --- a/slf4j-nop/src/main/java/org/slf4j/impl/StaticMarkerBinder.java +++ b/slf4j-nop/src/main/java/org/slf4j/impl/StaticMarkerBinder.java @@ -49,6 +49,16 @@ } /** + * 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/pom.xml b/slf4j-simple/pom.xml index 544a3fa..6217d65 100644 --- a/slf4j-simple/pom.xml +++ b/slf4j-simple/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.13 + 1.7.14 slf4j-simple 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 1666677..ae1ad27 100644 --- a/slf4j-simple/src/main/java/org/slf4j/impl/StaticLoggerBinder.java +++ b/slf4j-simple/src/main/java/org/slf4j/impl/StaticLoggerBinder.java @@ -53,8 +53,8 @@ } /** - * Declare the version of the SLF4J API this implementation is compiled - * against. The value of this field is usually modified with each release. + * Declare the version of the SLF4J API this implementation is compiled against. + * 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.6.99"; // !final 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 e46c063..dccb05a 100644 --- a/slf4j-simple/src/main/java/org/slf4j/impl/StaticMDCBinder.java +++ b/slf4j-simple/src/main/java/org/slf4j/impl/StaticMDCBinder.java @@ -43,6 +43,16 @@ } /** + * 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 8dd2537..1172cd3 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 @@ 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/pom.xml b/slf4j-site/pom.xml new file mode 100644 index 0000000..8813e9b --- /dev/null +++ b/slf4j-site/pom.xml @@ -0,0 +1,44 @@ + + + + 4.0.0 + + + org.slf4j + slf4j-parent + 1.7.14 + + + slf4j-site + + jar + SLF4J Site + SLF4J Site + http://www.slf4j.org + + + + + ${project.basedir}/src/site/pages + + ../../../target/site + true + + + ${project.basedir}/src/main/resources + + + + + org.apache.maven.plugins + maven-site-plugin + ${maven-site-plugin.version} + + ${project.parent.basedir}/target/site + + + + + + \ No newline at end of file diff --git a/slf4j-site/src/main/resources/META-INF/MANIFEST.MF b/slf4j-site/src/main/resources/META-INF/MANIFEST.MF new file mode 100644 index 0000000..e69de29