diff --git a/integration/pom.xml b/integration/pom.xml index c0b12c9..7ce6fc0 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.19 + 1.7.20 integration diff --git a/jcl-over-slf4j/pom.xml b/jcl-over-slf4j/pom.xml index 1f01ded..8064060 100644 --- a/jcl-over-slf4j/pom.xml +++ b/jcl-over-slf4j/pom.xml @@ -5,7 +5,7 @@ org.slf4j slf4j-parent - 1.7.19 + 1.7.20 4.0.0 diff --git a/jul-to-slf4j/pom.xml b/jul-to-slf4j/pom.xml index 951a587..90593bc 100644 --- a/jul-to-slf4j/pom.xml +++ b/jul-to-slf4j/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.19 + 1.7.20 jul-to-slf4j diff --git a/log4j-over-slf4j/pom.xml b/log4j-over-slf4j/pom.xml index 37d3c2d..03a3c34 100644 --- a/log4j-over-slf4j/pom.xml +++ b/log4j-over-slf4j/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.19 + 1.7.20 diff --git a/osgi-over-slf4j/pom.xml b/osgi-over-slf4j/pom.xml index bb8ac68..fa7a5ac 100644 --- a/osgi-over-slf4j/pom.xml +++ b/osgi-over-slf4j/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.19 + 1.7.20 osgi-over-slf4j diff --git a/pom.xml b/pom.xml index 928bbd5..4e4f51e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.slf4j slf4j-parent - 1.7.19 + 1.7.20 pom SLF4J diff --git a/slf4j-android/pom.xml b/slf4j-android/pom.xml index fd78b04..8b0303d 100644 --- a/slf4j-android/pom.xml +++ b/slf4j-android/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.19 + 1.7.20 slf4j-android diff --git a/slf4j-api/pom.xml b/slf4j-api/pom.xml index e90bd8c..a7fcea9 100644 --- a/slf4j-api/pom.xml +++ b/slf4j-api/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.19 + 1.7.20 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 3587810..ce76f1e 100644 --- a/slf4j-api/src/main/java/org/slf4j/LoggerFactory.java +++ b/slf4j-api/src/main/java/org/slf4j/LoggerFactory.java @@ -240,7 +240,7 @@ private static void emitReplayWarning(int eventCount) { Util.report("A number (" + eventCount + ") of logging calls during the initialization phase have been intercepted and are"); - Util.report("now being replayed. These are suject to the filtering rules of the underlying logging system."); + Util.report("now being replayed. These are subject to the filtering rules of the underlying logging system."); Util.report("See also " + REPLAY_URL); } diff --git a/slf4j-api/src/test/java/org/slf4j/LoggerAccessingThread.java b/slf4j-api/src/test/java/org/slf4j/LoggerAccessingThread.java new file mode 100644 index 0000000..383e7e5 --- /dev/null +++ b/slf4j-api/src/test/java/org/slf4j/LoggerAccessingThread.java @@ -0,0 +1,57 @@ +/** + * 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; + +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.atomic.AtomicLong; + +public class LoggerAccessingThread extends Thread { + private static int LOOP_LEN = 64; + + final CyclicBarrier barrier; + final int count; + final AtomicLong eventCount; + + public LoggerAccessingThread(final CyclicBarrier barrier, final int count, final AtomicLong eventCount) { + this.barrier = barrier; + 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); + logger.info("in run method"); + eventCount.getAndIncrement(); + } + } +} diff --git a/slf4j-ext/pom.xml b/slf4j-ext/pom.xml index 0d0ec4f..946f662 100644 --- a/slf4j-ext/pom.xml +++ b/slf4j-ext/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.19 + 1.7.20 slf4j-ext diff --git a/slf4j-jcl/pom.xml b/slf4j-jcl/pom.xml index 63a4227..7385e08 100644 --- a/slf4j-jcl/pom.xml +++ b/slf4j-jcl/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.19 + 1.7.20 slf4j-jcl diff --git a/slf4j-jdk14/pom.xml b/slf4j-jdk14/pom.xml index 032a21b..ad34db0 100644 --- a/slf4j-jdk14/pom.xml +++ b/slf4j-jdk14/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.19 + 1.7.20 slf4j-jdk14 diff --git a/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerFactory.java b/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerFactory.java index ba6c179..59c6755 100644 --- a/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerFactory.java +++ b/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerFactory.java @@ -43,8 +43,9 @@ public JDK14LoggerFactory() { loggerMap = new ConcurrentHashMap(); - // ensure jul initialization. see also SLF4J-359 - java.util.logging.LogManager.getLogManager(); + // ensure jul initialization. see SLF4J-359 + // note that call to java.util.logging.LogManager.getLogManager() fails on the Google App Engine platform. See SLF4J-363 + java.util.logging.Logger.getLogger(""); } /* diff --git a/slf4j-jdk14/src/test/java/org/slf4j/impl/CountingHandler.java b/slf4j-jdk14/src/test/java/org/slf4j/impl/CountingHandler.java new file mode 100644 index 0000000..1d56090 --- /dev/null +++ b/slf4j-jdk14/src/test/java/org/slf4j/impl/CountingHandler.java @@ -0,0 +1,24 @@ +package org.slf4j.impl; + +import java.util.concurrent.atomic.AtomicLong; +import java.util.logging.Handler; +import java.util.logging.LogRecord; + +public class CountingHandler extends Handler { + + final AtomicLong eventCount = new AtomicLong(0); + + @Override + public void publish(LogRecord record) { + eventCount.getAndIncrement(); + } + + @Override + public void flush() { + } + + @Override + public void close() throws SecurityException { + } + +} diff --git a/slf4j-jdk14/src/test/java/org/slf4j/impl/JDK14MultithreadedInitializationTest.java b/slf4j-jdk14/src/test/java/org/slf4j/impl/JDK14MultithreadedInitializationTest.java new file mode 100644 index 0000000..dfad51f --- /dev/null +++ b/slf4j-jdk14/src/test/java/org/slf4j/impl/JDK14MultithreadedInitializationTest.java @@ -0,0 +1,123 @@ +/** + * 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.impl; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Random; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.atomic.AtomicLong; +import java.util.logging.Handler; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerAccessingThread; +import org.slf4j.LoggerFactory; + +public class JDK14MultithreadedInitializationTest { + + final static int THREAD_COUNT = 4 + Runtime.getRuntime().availableProcessors() * 2; + + final private AtomicLong eventCount = new AtomicLong(0); + final private CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1); + + int diff = new Random().nextInt(10000); + + java.util.logging.Logger julRootLogger = java.util.logging.Logger.getLogger(""); + java.util.logging.Logger julOrgLogger = java.util.logging.Logger.getLogger("org"); + + @Before + public void addRecordingHandler() { + System.out.println("THREAD_COUNT=" + THREAD_COUNT); + removeAllHandlers(julRootLogger); + removeAllHandlers(julOrgLogger); + julOrgLogger.addHandler(new CountingHandler()); + } + + private void removeAllHandlers(java.util.logging.Logger logger) { + Handler[] handlers = logger.getHandlers(); + for (int i = 0; i < handlers.length; i++) { + logger.removeHandler(handlers[i]); + } + } + + @After + public void tearDown() throws Exception { + removeAllHandlers(julOrgLogger); + } + + @Test + public void multiThreadedInitialization() throws InterruptedException, BrokenBarrierException { + @SuppressWarnings("unused") + LoggerAccessingThread[] accessors = harness(); + + Logger logger = LoggerFactory.getLogger(getClass().getName()); + logger.info("hello"); + eventCount.getAndIncrement(); + + long recordedEventCount = getRecordedEventCount(); + assertTrue(eventCount.get() + " >= " + recordedEventCount, eventCount.get() >= recordedEventCount); + assertTrue(eventCount.get() + " < " + recordedEventCount + "+10", eventCount.get() < recordedEventCount + 10); + } + + private long getRecordedEventCount() { + CountingHandler ra = findRecordingHandler(); + if (ra == null) { + fail("failed to fing RecordingHandler"); + } + return ra.eventCount.get(); + } + + private CountingHandler findRecordingHandler() { + Handler[] handlers = julOrgLogger.getHandlers(); + for (Handler h : handlers) { + if (h instanceof CountingHandler) + return (CountingHandler) h; + } + return null; + } + + private LoggerAccessingThread[] harness() throws InterruptedException, BrokenBarrierException { + LoggerAccessingThread[] threads = new LoggerAccessingThread[THREAD_COUNT]; + for (int i = 0; i < THREAD_COUNT; i++) { + threads[i] = new LoggerAccessingThread(barrier, i, eventCount); + threads[i].start(); + } + + // trigger barrier + barrier.await(); + + for (int i = 0; i < THREAD_COUNT; i++) { + threads[i].join(); + } + + return threads; + } + +} diff --git a/slf4j-jdk14/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java b/slf4j-jdk14/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java deleted file mode 100644 index 16a7647..0000000 --- a/slf4j-jdk14/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java +++ /dev/null @@ -1,153 +0,0 @@ -/** - * 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.impl; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -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 java.util.logging.Handler; -import java.util.logging.LogRecord; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MultithreadedInitializationTest { - - final static int THREAD_COUNT = 4 + Runtime.getRuntime().availableProcessors() * 2; - - private static AtomicLong EVENT_COUNT = new AtomicLong(0); - - final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1); - - int diff = new Random().nextInt(10000); - String packagePrefix = "org.slf4j.impl.MultithreadedInitializationTest" + diff; - - java.util.logging.Logger julLogger = java.util.logging.Logger.getLogger(packagePrefix); - - @Before - public void addRecordingHandler() { - julLogger.addHandler(new RecordingHandler()); - } - - @After - public void tearDown() throws Exception { - Handler[] handlers = julLogger.getHandlers(); - for (int i = 0; i < handlers.length; i++) { - if (handlers[i] instanceof RecordingHandler) { - julLogger.removeHandler(handlers[i]); - } - } - } - - @Test - public void multiThreadedInitialization() throws InterruptedException, BrokenBarrierException { - System.out.println("THREAD_COUNT=" + THREAD_COUNT); - LoggerAccessingThread[] accessors = harness(); - - for (int i = 0; i < accessors.length; i++) { - LoggerAccessingThread accessor = accessors[i]; - EVENT_COUNT.getAndIncrement(); - if (accessor.logger == null) { - fail("logger for LoggerAccessingThread " + i + " is not set"); - } - accessor.logger.info("post harness"); - } - - Logger logger = LoggerFactory.getLogger(packagePrefix + ".test"); - logger.info("hello"); - EVENT_COUNT.getAndIncrement(); - - List records = getRecordedEvents(); - assertEquals(EVENT_COUNT.get(), records.size()); - } - - private List getRecordedEvents() { - RecordingHandler ra = findRecordingHandler(); - if (ra == null) { - fail("failed to fing RecordingHandler"); - } - return ra.records; - } - - private RecordingHandler findRecordingHandler() { - Handler[] handlers = julLogger.getHandlers(); - for (Handler h : handlers) { - if (h instanceof RecordingHandler) - return (RecordingHandler) h; - } - return null; - } - - private LoggerAccessingThread[] harness() throws InterruptedException, BrokenBarrierException { - LoggerAccessingThread[] threads = new LoggerAccessingThread[THREAD_COUNT]; - final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1); - for (int i = 0; i < THREAD_COUNT; i++) { - threads[i] = new LoggerAccessingThread(barrier, i); - threads[i].start(); - } - - // trigger barrier - barrier.await(); - - for (int i = 0; i < THREAD_COUNT; i++) { - threads[i].join(); - } - - return threads; - } - - class LoggerAccessingThread extends Thread { - final CyclicBarrier barrier; - volatile Logger logger; - final int count; - - LoggerAccessingThread(CyclicBarrier barrier, int count) { - this.barrier = barrier; - this.count = count; - } - - public void run() { - try { - barrier.await(); - } catch (Exception e) { - e.printStackTrace(); - } - for (int i = 0; i < 64; i++) { - logger = LoggerFactory.getLogger(packagePrefix + ".LoggerAccessingThread" + count + "-" + i); - logger.info("in run method"); - EVENT_COUNT.getAndIncrement(); - } - } - }; - -} diff --git a/slf4j-jdk14/src/test/java/org/slf4j/impl/RecordingHandler.java b/slf4j-jdk14/src/test/java/org/slf4j/impl/RecordingHandler.java deleted file mode 100644 index 118ccd7..0000000 --- a/slf4j-jdk14/src/test/java/org/slf4j/impl/RecordingHandler.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.slf4j.impl; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.logging.Handler; -import java.util.logging.LogRecord; - -public class RecordingHandler extends Handler { - - List records = Collections.synchronizedList(new ArrayList()); - - @Override - public void publish(LogRecord record) { - records.add(record); - } - - @Override - public void flush() { - } - - @Override - public void close() throws SecurityException { - } - -} diff --git a/slf4j-log4j12/pom.xml b/slf4j-log4j12/pom.xml index f724e09..48c2150 100644 --- a/slf4j-log4j12/pom.xml +++ b/slf4j-log4j12/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.19 + 1.7.20 slf4j-log4j12 @@ -27,6 +27,14 @@ log4j log4j + + + org.slf4j + slf4j-api + test-jar + ${project.version} + test + diff --git a/slf4j-log4j12/src/test/java/org/slf4j/impl/Log4j12MultithreadedInitializationTest.java b/slf4j-log4j12/src/test/java/org/slf4j/impl/Log4j12MultithreadedInitializationTest.java new file mode 100644 index 0000000..b81b66f --- /dev/null +++ b/slf4j-log4j12/src/test/java/org/slf4j/impl/Log4j12MultithreadedInitializationTest.java @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2004-2011 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.impl; + +import static org.junit.Assert.assertEquals; + +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.apache.log4j.LogManager; +import org.apache.log4j.spi.LoggingEvent; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerAccessingThread; +import org.slf4j.LoggerFactory; + +public class Log4j12MultithreadedInitializationTest { + + // value of LogManager.DEFAULT_CONFIGURATION_KEY; + static String CONFIG_FILE_KEY = "log4j.configuration"; + + final static int THREAD_COUNT = 4 + Runtime.getRuntime().availableProcessors() * 2; + + private final AtomicLong eventCount = new AtomicLong(0); + + private final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1); + + final int diff = new Random().nextInt(10000); + final String loggerName = this.getClass().getName(); + + @Before + public void setup() { + System.out.println("THREAD_COUNT=" + THREAD_COUNT); + } + + @After + public void tearDown() throws Exception { + System.clearProperty(CONFIG_FILE_KEY); + } + + @Test + public void multiThreadedInitialization() throws InterruptedException, BrokenBarrierException { + + System.setProperty(CONFIG_FILE_KEY, "recursiveInitWithActivationDelay.properties"); + + @SuppressWarnings("unused") + LoggerAccessingThread[] accessors = harness(); + + Logger logger = LoggerFactory.getLogger(loggerName + ".slowInitialization-" + diff); + logger.info("hello"); + eventCount.getAndIncrement(); + + List events = getRecordedEvents(); + int NUM_LINES_BY_RECURSIVE_APPENDER = 3; + assertEquals(eventCount.get() + NUM_LINES_BY_RECURSIVE_APPENDER, events.size()); + } + + private List getRecordedEvents() { + org.apache.log4j.Logger root = LogManager.getRootLogger(); + + RecursiveAppender ra = (RecursiveAppender) root.getAppender("RECURSIVE"); + return ra.events; + } + + private LoggerAccessingThread[] harness() throws InterruptedException, BrokenBarrierException { + LoggerAccessingThread[] threads = new LoggerAccessingThread[THREAD_COUNT]; + for (int i = 0; i < THREAD_COUNT; i++) { + threads[i] = new LoggerAccessingThread(barrier, i, eventCount); + threads[i].start(); + } + + barrier.await(); + for (int i = 0; i < THREAD_COUNT; i++) { + threads[i].join(); + } + return threads; + } + +} diff --git a/slf4j-log4j12/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java b/slf4j-log4j12/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java deleted file mode 100644 index c9fde1d..0000000 --- a/slf4j-log4j12/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java +++ /dev/null @@ -1,127 +0,0 @@ -/** - * Copyright (c) 2004-2011 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.impl; - -import static org.junit.Assert.assertEquals; - -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.apache.log4j.LogManager; -import org.apache.log4j.spi.LoggingEvent; -import org.junit.After; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MultithreadedInitializationTest { - - // value of LogManager.DEFAULT_CONFIGURATION_KEY; - static String CONFIG_FILE_KEY = "log4j.configuration"; - - final static int THREAD_COUNT = 4 + Runtime.getRuntime().availableProcessors() * 2; - - private static AtomicLong EVENT_COUNT = new AtomicLong(0); - - final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1); - - int diff = new Random().nextInt(10000); - String loggerName = "org.slf4j.impl.RecursiveInitializationTest"; - - @After - public void tearDown() throws Exception { - System.clearProperty(CONFIG_FILE_KEY); - } - - @Test - public void multiThreadedInitialization() throws InterruptedException, BrokenBarrierException { - System.out.println("THREAD_COUNT=" + THREAD_COUNT); - System.setProperty(CONFIG_FILE_KEY, "recursiveInitWithActivationDelay.properties"); - LoggerAccessingThread[] accessors = harness(); - - for (LoggerAccessingThread accessor : accessors) { - EVENT_COUNT.getAndIncrement(); - accessor.logger.info("post harness"); - } - - Logger logger = LoggerFactory.getLogger(loggerName + ".slowInitialization-" + diff); - logger.info("hello"); - EVENT_COUNT.getAndIncrement(); - - List events = getRecordedEvents(); - // 3 evetns generated by RecursiveAppender - assertEquals(EVENT_COUNT.get() + 3, events.size()); - } - - private List getRecordedEvents() { - org.apache.log4j.Logger root = LogManager.getRootLogger(); - - RecursiveAppender ra = (RecursiveAppender) root.getAppender("RECURSIVE"); - return ra.events; - } - - private static LoggerAccessingThread[] harness() throws InterruptedException, BrokenBarrierException { - LoggerAccessingThread[] threads = new LoggerAccessingThread[THREAD_COUNT]; - final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1); - for (int i = 0; i < THREAD_COUNT; i++) { - threads[i] = new LoggerAccessingThread(barrier, i); - threads[i].start(); - } - - barrier.await(); - for (int i = 0; i < THREAD_COUNT; i++) { - threads[i].join(); - } - return threads; - } - - static class LoggerAccessingThread extends Thread { - final CyclicBarrier barrier; - Logger logger; - int count; - - LoggerAccessingThread(CyclicBarrier barrier, int count) { - this.barrier = barrier; - this.count = count; - } - - public void run() { - try { - barrier.await(); - } catch (Exception e) { - e.printStackTrace(); - } - for (int i = 0; i < 64; i++) { - logger = LoggerFactory.getLogger(this.getClass().getName() + "-" + count + "-" + i); - logger.info("in run method"); - EVENT_COUNT.getAndIncrement(); - } - } - }; - -} diff --git a/slf4j-migrator/pom.xml b/slf4j-migrator/pom.xml index d25152f..9375772 100644 --- a/slf4j-migrator/pom.xml +++ b/slf4j-migrator/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.19 + 1.7.20 slf4j-migrator diff --git a/slf4j-nop/pom.xml b/slf4j-nop/pom.xml index 31408cb..a1fff90 100644 --- a/slf4j-nop/pom.xml +++ b/slf4j-nop/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.19 + 1.7.20 slf4j-nop diff --git a/slf4j-simple/pom.xml b/slf4j-simple/pom.xml index 94bdd41..15b309f 100644 --- a/slf4j-simple/pom.xml +++ b/slf4j-simple/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.19 + 1.7.20 slf4j-simple @@ -21,6 +21,14 @@ org.slf4j slf4j-api + + + org.slf4j + slf4j-api + test-jar + ${project.version} + test + diff --git a/slf4j-simple/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java b/slf4j-simple/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java deleted file mode 100644 index 54719c5..0000000 --- a/slf4j-simple/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java +++ /dev/null @@ -1,154 +0,0 @@ -/** - * 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.impl; - -import static org.junit.Assert.assertEquals; - -import java.io.PrintStream; -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.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.slf4j.LoggerFactoryFriend; - -public class MultithreadedInitializationTest { - - final static int THREAD_COUNT = 4 + Runtime.getRuntime().availableProcessors() * 2; - - private static AtomicLong EVENT_COUNT = new AtomicLong(0); - - private final PrintStream oldErr = System.err; - final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1); - - int diff = new Random().nextInt(10000); - String loggerName = "org.slf4j.impl.MultithreadedInitializationTest"; - StringPrintStream sps = new StringPrintStream(oldErr); - - @Before - public void setup() { - LoggerFactoryFriend.reset(); - System.setErr(sps); - } - - @After - public void tearDown() throws Exception { - LoggerFactoryFriend.reset(); - System.setErr(oldErr); - } - - @Test - public void multiThreadedInitialization() throws InterruptedException, BrokenBarrierException { - System.out.println("THREAD_COUNT=" + THREAD_COUNT); - LoggerAccessingThread[] accessors = harness(); - - for (LoggerAccessingThread accessor : accessors) { - EVENT_COUNT.getAndIncrement(); - accessor.logger.info("post harness"); - } - - Logger logger = LoggerFactory.getLogger(loggerName + ".slowInitialization-" + diff); - logger.info("hello"); - EVENT_COUNT.getAndIncrement(); - - int NUM_LINES_IN_SLF4J_REPLAY_WARNING = 3; - assertEquals(EVENT_COUNT.get() + NUM_LINES_IN_SLF4J_REPLAY_WARNING, sps.stringList.size()); - } - - private static LoggerAccessingThread[] harness() throws InterruptedException, BrokenBarrierException { - LoggerAccessingThread[] threads = new LoggerAccessingThread[THREAD_COUNT]; - final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1); - for (int i = 0; i < THREAD_COUNT; i++) { - threads[i] = new LoggerAccessingThread(barrier, i); - threads[i].start(); - } - - barrier.await(); - for (int i = 0; i < THREAD_COUNT; i++) { - threads[i].join(); - } - return threads; - } - - static class LoggerAccessingThread extends Thread { - final CyclicBarrier barrier; - Logger logger; - int count; - - LoggerAccessingThread(CyclicBarrier barrier, int count) { - this.barrier = barrier; - this.count = count; - } - - public void run() { - try { - barrier.await(); - } catch (Exception e) { - e.printStackTrace(); - } - for (int i = 0; i < 64; i++) { - logger = LoggerFactory.getLogger(this.getClass().getName() + "-" + count+"-"+i); - logger.info("in run method"); - EVENT_COUNT.getAndIncrement(); - } - } - }; - - public static class StringPrintStream extends PrintStream { - - public static final String LINE_SEP = System.getProperty("line.separator"); - PrintStream other; - List stringList = Collections.synchronizedList(new ArrayList()); - - public StringPrintStream(PrintStream ps) { - super(ps); - other = ps; - } - - public void print(String s) { - other.print(s); - stringList.add(s); - } - - public void println(String s) { - other.println(s); - stringList.add(s); - } - - public void println(Object o) { - other.println(o); - stringList.add(o.toString()); - } - }; - -} diff --git a/slf4j-simple/src/test/java/org/slf4j/impl/SimpleLoggerMultithreadedInitializationTest.java b/slf4j-simple/src/test/java/org/slf4j/impl/SimpleLoggerMultithreadedInitializationTest.java new file mode 100644 index 0000000..17aa97d --- /dev/null +++ b/slf4j-simple/src/test/java/org/slf4j/impl/SimpleLoggerMultithreadedInitializationTest.java @@ -0,0 +1,144 @@ +/** + * 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.impl; + +import static org.junit.Assert.assertTrue; + +import java.io.PrintStream; +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.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerAccessingThread; +import org.slf4j.LoggerFactory; +import org.slf4j.LoggerFactoryFriend; + +public class SimpleLoggerMultithreadedInitializationTest { + + final static int THREAD_COUNT = 4 + Runtime.getRuntime().availableProcessors() * 2; + + private final AtomicLong eventCount = new AtomicLong(0); + private final PrintStream oldErr = System.err; + private final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1); + + final int diff = new Random().nextInt(10000); + final String loggerName = this.getClass().getName(); + StringPrintStream sps = new StringPrintStream(oldErr, true); + + @Before + public void setup() { + System.out.println("THREAD_COUNT=" + THREAD_COUNT); + System.setErr(sps); + System.setProperty(SimpleLogger.LOG_FILE_KEY, "System.err"); + LoggerFactoryFriend.reset(); + } + + @After + public void tearDown() throws Exception { + LoggerFactoryFriend.reset(); + System.clearProperty(SimpleLogger.LOG_FILE_KEY); + System.setErr(oldErr); + } + + @Test + public void multiThreadedInitialization() throws InterruptedException, BrokenBarrierException { + + @SuppressWarnings("unused") + LoggerAccessingThread[] accessors = harness(); + + Logger logger = LoggerFactory.getLogger(loggerName + diff); + logger.info("hello"); + eventCount.getAndIncrement(); + + int NUM_LINES_IN_SLF4J_REPLAY_WARNING = 3; + + long expected = eventCount.get() + NUM_LINES_IN_SLF4J_REPLAY_WARNING; + int actual = sps.stringList.size(); + assertTrue(expected + " >= " + actual, expected >= actual); + assertTrue(expected + " < " + actual + " + 16", expected < actual + 16); + } + + private LoggerAccessingThread[] harness() throws InterruptedException, BrokenBarrierException { + final LoggerAccessingThread[] threads = new LoggerAccessingThread[THREAD_COUNT]; + for (int i = 0; i < THREAD_COUNT; i++) { + LoggerAccessingThread simpleLoggerThread = new LoggerAccessingThread(barrier, i, eventCount); + threads[i] = simpleLoggerThread; + simpleLoggerThread.start(); + } + + barrier.await(); + for (int i = 0; i < THREAD_COUNT; i++) { + threads[i].join(); + } + return threads; + } + + + static class StringPrintStream extends PrintStream { + + public static final String LINE_SEP = System.getProperty("line.separator"); + PrintStream other; + boolean duplicate = false; + + List stringList = Collections.synchronizedList(new ArrayList()); + + public StringPrintStream(PrintStream ps, boolean duplicate) { + super(ps); + other = ps; + this.duplicate = duplicate; + } + + public StringPrintStream(PrintStream ps) { + this(ps, false); + } + + public void print(String s) { + if (duplicate) + other.print(s); + stringList.add(s); + } + + public void println(String s) { + if (duplicate) + other.println(s); + stringList.add(s); + } + + public void println(Object o) { + if (duplicate) + other.println(o); + stringList.add(o.toString()); + } + }; + +} diff --git a/slf4j-site/pom.xml b/slf4j-site/pom.xml index fd57623..467645c 100644 --- a/slf4j-site/pom.xml +++ b/slf4j-site/pom.xml @@ -7,7 +7,7 @@ org.slf4j slf4j-parent - 1.7.19 + 1.7.20 slf4j-site