diff --git a/integration/build.xml b/integration/build.xml index 6f7bb039d..e4ce964c1 100755 --- a/integration/build.xml +++ b/integration/build.xml @@ -56,7 +56,12 @@ + + + + + @@ -102,11 +107,12 @@ @@ -215,7 +221,17 @@ - + + + + + + + + + diff --git a/integration/pom.xml b/integration/pom.xml index 1e8a5df45..a34a9a219 100755 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.29 + 1.7.30 integration diff --git a/integration/src/test/java/org/slf4j/helpers/LoggerAccessingThread2.java b/integration/src/test/java/org/slf4j/helpers/LoggerAccessingThread2.java new file mode 100644 index 000000000..86590b3d6 --- /dev/null +++ b/integration/src/test/java/org/slf4j/helpers/LoggerAccessingThread2.java @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2004-2016 QOS.ch + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ +package org.slf4j.helpers; + +import java.util.List; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.atomic.AtomicLong; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LoggerAccessingThread2 extends Thread { + private static int LOOP_LEN = 64; + + final CyclicBarrier barrier; + final int count; + final AtomicLong eventCount; + List loggerList; + + public LoggerAccessingThread2(final CyclicBarrier barrier, List loggerList, final int count, final AtomicLong eventCount) { + this.barrier = barrier; + this.loggerList = loggerList; + this.count = count; + this.eventCount = eventCount; + } + + public void run() { + try { + barrier.await(); + } catch (Exception e) { + e.printStackTrace(); + } + + String loggerNamePrefix = this.getClass().getName(); + for (int i = 0; i < LOOP_LEN; i++) { + Logger logger = LoggerFactory.getLogger(loggerNamePrefix + "-" + count + "-" + i); + loggerList.add(logger); + Thread.yield(); + logger.info("in run method"); + eventCount.getAndIncrement(); + } + } +} diff --git a/integration/src/test/java/org/slf4j/helpers/NoBindingMultithreadedInitializationTest2.java b/integration/src/test/java/org/slf4j/helpers/NoBindingMultithreadedInitializationTest2.java new file mode 100644 index 000000000..6de0f8ec3 --- /dev/null +++ b/integration/src/test/java/org/slf4j/helpers/NoBindingMultithreadedInitializationTest2.java @@ -0,0 +1,112 @@ +/** + * Copyright (c) 2004-2016 QOS.ch + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ +package org.slf4j.helpers; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.atomic.AtomicLong; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.event.EventRecodingLogger; + +import junit.framework.TestCase; + +public class NoBindingMultithreadedInitializationTest2 extends TestCase { + final protected static int THREAD_COUNT = 4 + Runtime.getRuntime().availableProcessors() * 2; + + private final List createdLoggers = Collections.synchronizedList(new ArrayList()); + + protected final AtomicLong eventCount = new AtomicLong(0); + final private CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1); + + int diff = new Random().nextInt(10000); + + + public NoBindingMultithreadedInitializationTest2(String name) { + super(name); + } + + public void testNoBindingMultiThreadedInitialization() throws InterruptedException, BrokenBarrierException { + @SuppressWarnings("unused") + LoggerAccessingThread2[] accessors = harness(); + + Logger logger = LoggerFactory.getLogger(getClass().getName()); + logger.info("hello"); + eventCount.getAndIncrement(); + + assertAllSubstLoggersAreFixed(); + long recordedEventCount = getRecordedEventCount(); + int LENIENCY_COUNT = 16; + + long expectedEventCount = eventCount.get() + extraLogEvents(); + + assertTrue(expectedEventCount + " >= " + recordedEventCount, expectedEventCount >= recordedEventCount); + assertTrue(expectedEventCount + " < " + recordedEventCount + "+" + LENIENCY_COUNT, + expectedEventCount < recordedEventCount + LENIENCY_COUNT); + } + + protected int extraLogEvents() { + return 0; + } + + private void assertAllSubstLoggersAreFixed() { + for (Logger logger : createdLoggers) { + if (logger instanceof SubstituteLogger) { + SubstituteLogger substLogger = (SubstituteLogger) logger; + if (substLogger.delegate() instanceof EventRecodingLogger) + fail("substLogger " + substLogger.getName() + " has a delegate of type EventRecodingLogger"); + } + } + } + + private LoggerAccessingThread2[] harness() throws InterruptedException, BrokenBarrierException { + LoggerAccessingThread2[] threads = new LoggerAccessingThread2[THREAD_COUNT]; + for (int i = 0; i < THREAD_COUNT; i++) { + threads[i] = new LoggerAccessingThread2(barrier, createdLoggers, i, eventCount); + threads[i].start(); + } + + // trigger barrier + barrier.await(); + + for (int i = 0; i < THREAD_COUNT; i++) { + threads[i].join(); + } + + return threads; + } + + final String loggerName = this.getClass().getName(); + + protected long getRecordedEventCount() { + return eventCount.get(); + } + +} diff --git a/jcl-over-slf4j/pom.xml b/jcl-over-slf4j/pom.xml index c809fafa9..2c3c7a600 100755 --- a/jcl-over-slf4j/pom.xml +++ b/jcl-over-slf4j/pom.xml @@ -5,7 +5,7 @@ org.slf4j slf4j-parent - 1.7.29 + 1.7.30 4.0.0 diff --git a/jul-to-slf4j/pom.xml b/jul-to-slf4j/pom.xml index 619d69694..85ea8d02a 100755 --- a/jul-to-slf4j/pom.xml +++ b/jul-to-slf4j/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.29 + 1.7.30 jul-to-slf4j diff --git a/log4j-over-slf4j/pom.xml b/log4j-over-slf4j/pom.xml index d45be51f0..80226f5c7 100755 --- a/log4j-over-slf4j/pom.xml +++ b/log4j-over-slf4j/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.29 + 1.7.30 diff --git a/osgi-over-slf4j/pom.xml b/osgi-over-slf4j/pom.xml index dc1a0df78..9237dec3c 100755 --- a/osgi-over-slf4j/pom.xml +++ b/osgi-over-slf4j/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.29 + 1.7.30 osgi-over-slf4j diff --git a/pom.xml b/pom.xml index c582aa1b9..8e712839b 100755 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.slf4j slf4j-parent - 1.7.29 + 1.7.30 pom SLF4J diff --git a/slf4j-android/pom.xml b/slf4j-android/pom.xml index ba7043756..1b86e27d6 100644 --- a/slf4j-android/pom.xml +++ b/slf4j-android/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.29 + 1.7.30 slf4j-android diff --git a/slf4j-api/pom.xml b/slf4j-api/pom.xml index db7a40fe9..78e96a962 100755 --- a/slf4j-api/pom.xml +++ b/slf4j-api/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.29 + 1.7.30 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 30b5c7257..9ed2c19e7 100755 --- a/slf4j-api/src/main/java/org/slf4j/LoggerFactory.java +++ b/slf4j-api/src/main/java/org/slf4j/LoggerFactory.java @@ -150,10 +150,6 @@ private final static void bind() { StaticLoggerBinder.getSingleton(); INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION; reportActualBinding(staticLoggerBinderPathSet); - fixSubstituteLoggers(); - replayEvents(); - // release all resources in SUBST_FACTORY - SUBST_FACTORY.clear(); } catch (NoClassDefFoundError ncde) { String msg = ncde.getMessage(); if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) { @@ -177,9 +173,18 @@ private final static void bind() { } catch (Exception e) { failedBinding(e); throw new IllegalStateException("Unexpected initialization failure", e); + } finally { + postBindCleanUp(); } } + private static void postBindCleanUp() { + fixSubstituteLoggers(); + replayEvents(); + // release all resources in SUBST_FACTORY + SUBST_FACTORY.clear(); + } + private static void fixSubstituteLoggers() { synchronized (SUBST_FACTORY) { SUBST_FACTORY.postInitialization(); diff --git a/slf4j-api/src/test/java/org/slf4j/helpers/MultithreadedInitializationTest.java b/slf4j-api/src/test/java/org/slf4j/helpers/MultithreadedInitializationTest.java index 6cf361348..c9e38eae7 100644 --- a/slf4j-api/src/test/java/org/slf4j/helpers/MultithreadedInitializationTest.java +++ b/slf4j-api/src/test/java/org/slf4j/helpers/MultithreadedInitializationTest.java @@ -22,7 +22,7 @@ abstract public class MultithreadedInitializationTest { private final List createdLoggers = Collections.synchronizedList(new ArrayList()); - final private AtomicLong eventCount = new AtomicLong(0); + protected final AtomicLong eventCount = new AtomicLong(0); final private CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1); int diff = new Random().nextInt(10000); diff --git a/slf4j-ext/pom.xml b/slf4j-ext/pom.xml index 31e43dccf..9acc1e291 100755 --- a/slf4j-ext/pom.xml +++ b/slf4j-ext/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.29 + 1.7.30 slf4j-ext diff --git a/slf4j-jcl/pom.xml b/slf4j-jcl/pom.xml index aa8c1dfac..d9fa8c997 100755 --- a/slf4j-jcl/pom.xml +++ b/slf4j-jcl/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.29 + 1.7.30 slf4j-jcl diff --git a/slf4j-jdk14/pom.xml b/slf4j-jdk14/pom.xml index 12479c359..d343309e0 100755 --- a/slf4j-jdk14/pom.xml +++ b/slf4j-jdk14/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.29 + 1.7.30 slf4j-jdk14 diff --git a/slf4j-log4j12/pom.xml b/slf4j-log4j12/pom.xml index 33200a27b..bc40ac892 100755 --- a/slf4j-log4j12/pom.xml +++ b/slf4j-log4j12/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.29 + 1.7.30 slf4j-log4j12 diff --git a/slf4j-migrator/pom.xml b/slf4j-migrator/pom.xml index 3ea1fccc2..2a516a1d3 100755 --- a/slf4j-migrator/pom.xml +++ b/slf4j-migrator/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.29 + 1.7.30 slf4j-migrator diff --git a/slf4j-nop/pom.xml b/slf4j-nop/pom.xml index 3c52f1c79..8f7846205 100755 --- a/slf4j-nop/pom.xml +++ b/slf4j-nop/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.29 + 1.7.30 slf4j-nop diff --git a/slf4j-simple/pom.xml b/slf4j-simple/pom.xml index 8b130ce64..9de2a3168 100755 --- a/slf4j-simple/pom.xml +++ b/slf4j-simple/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.29 + 1.7.30 slf4j-simple diff --git a/slf4j-site/pom.xml b/slf4j-site/pom.xml index 3dea08be4..6869e586a 100755 --- a/slf4j-site/pom.xml +++ b/slf4j-site/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.29 + 1.7.30 slf4j-site