expectedMethodSignatures = determineMethodSignatures(Logger.class);
LoggerInvocationHandler ih = new LoggerInvocationHandler();
diff --git a/slf4j-api/src/test/java/org/slf4j/helpers/SubstituteLoggerFactoryTest.java b/slf4j-api/src/test/java/org/slf4j/helpers/SubstituteLoggerFactoryTest.java
index 246f9c4..620af1b 100644
--- a/slf4j-api/src/test/java/org/slf4j/helpers/SubstituteLoggerFactoryTest.java
+++ b/slf4j-api/src/test/java/org/slf4j/helpers/SubstituteLoggerFactoryTest.java
@@ -35,7 +35,7 @@
import java.util.HashSet;
import java.util.Set;
-public class SubstituteLoggerFactoryTest {
+public class SubstituteLoggerFactoryTest {
private SubstituteLoggerFactory factory = new SubstituteLoggerFactory();
@Test
diff --git a/slf4j-ext/pom.xml b/slf4j-ext/pom.xml
index 23c39ef..0d0ec4f 100644
--- a/slf4j-ext/pom.xml
+++ b/slf4j-ext/pom.xml
@@ -7,7 +7,7 @@
org.slf4j
slf4j-parent
- 1.7.14
+ 1.7.19
slf4j-ext
diff --git a/slf4j-ext/src/main/java/org/slf4j/agent/AgentPremain.java b/slf4j-ext/src/main/java/org/slf4j/agent/AgentPremain.java
index f8fea78..80ecebf 100644
--- a/slf4j-ext/src/main/java/org/slf4j/agent/AgentPremain.java
+++ b/slf4j-ext/src/main/java/org/slf4j/agent/AgentPremain.java
@@ -34,16 +34,14 @@
/**
* Entry point for slf4j-ext when used as a Java agent.
- *
+ *
*/
public class AgentPremain {
/**
* JavaAgent premain entry point as specified in the MANIFEST.MF file. See
- * {@link http
- * ://java.sun.com/javase/6/docs/api/java/lang/instrument/package-
- * summary.html} for details.
- *
+ * http://java.sun.com/javase/6/docs/api/java/lang/instrument/package-summary.html for details.
+ *
* @param agentArgument
* string provided after "=" up to first space
* @param instrumentation
@@ -85,8 +83,8 @@
* Consider the argument string to be a property file (by converting the
* splitter character to line feeds), and then reading it like any other
* property file.
- *
- *
+ *
+ *
* @param agentArgument
* string given by instrumentation framework
* @param separator
@@ -109,7 +107,7 @@
* Print the start message to System.err with the time NOW, and register a
* shutdown hook which will print the stop message to System.err with the
* time then and the number of milliseconds passed since.
- *
+ *
*/
private static void printStartStopTimes() {
final long start = System.currentTimeMillis();
@@ -125,4 +123,4 @@
};
Runtime.getRuntime().addShutdownHook(hook);
}
-}
\ No newline at end of file
+}
diff --git a/slf4j-ext/src/main/java/org/slf4j/cal10n/LocLoggerFactory.java b/slf4j-ext/src/main/java/org/slf4j/cal10n/LocLoggerFactory.java
index 126f98e..4ddff60 100644
--- a/slf4j-ext/src/main/java/org/slf4j/cal10n/LocLoggerFactory.java
+++ b/slf4j-ext/src/main/java/org/slf4j/cal10n/LocLoggerFactory.java
@@ -30,19 +30,19 @@
import ch.qos.cal10n.IMessageConveyor;
/**
- *
+ *
* This class is essentially a wrapper around an {@link LoggerFactory} producing
* {@link LocLogger} instances.
- *
+ *
*
* Contrary to {@link LoggerFactory#getLogger(String)} method of
- * {@link LoggerFactory}, each call to {@link getLocLogger} produces a new
+ * {@link LoggerFactory}, each call to {@link #getLocLogger(String)} produces a new
* instance of {@link LocLogger}. This should not matter because a LocLogger
- * instance does have any state beyond that of the {@link Logger} in stance it
+ * instance does have any state beyond that of the {@link Logger} instance it
* wraps and its message conveyor.
- *
+ *
* @author Ceki Gücü
- *
+ *
*/
public class LocLoggerFactory {
@@ -54,7 +54,7 @@
/**
* Get an LocLogger instance by name.
- *
+ *
* @param name
* @return LocLogger instance by name.
*/
@@ -65,7 +65,7 @@
/**
* Get a new LocLogger instance by class. The returned LocLogger will be named
* after the class.
- *
+ *
* @param clazz
* @return LocLogger instance by class
*/
diff --git a/slf4j-ext/src/main/java/org/slf4j/instrumentation/LogTransformer.java b/slf4j-ext/src/main/java/org/slf4j/instrumentation/LogTransformer.java
index f9a4c82..050084e 100644
--- a/slf4j-ext/src/main/java/org/slf4j/instrumentation/LogTransformer.java
+++ b/slf4j-ext/src/main/java/org/slf4j/instrumentation/LogTransformer.java
@@ -23,7 +23,7 @@
*
*/
/**
- *
+ *
*/
package org.slf4j.instrumentation;
@@ -57,17 +57,16 @@
/**
* Builder provides a flexible way of configuring some of many options on the
* parent class instead of providing many constructors.
- *
- * {@link http
- * ://rwhansen.blogspot.com/2007/07/theres-builder-pattern-that-joshua.html}
- *
+ *
+ * http://rwhansen.blogspot.com/2007/07/theres-builder-pattern-that-joshua.html
+ *
*/
public static class Builder {
/**
* Build and return the LogTransformer corresponding to the options set in
* this Builder.
- *
+ *
* @return
*/
public LogTransformer build() {
@@ -82,7 +81,7 @@
/**
* Should each method log entry (with parameters) and exit (with parameters
* and returnvalue)?
- *
+ *
* @param b
* value of flag
* @return
@@ -105,7 +104,7 @@
/**
* Should LogTransformer be verbose in what it does? This currently list the
* names of the classes being processed.
- *
+ *
* @param b
* @return
*/
@@ -177,7 +176,7 @@
* transform0 sees if the className starts with any of the namespaces to
* ignore, if so it is returned unchanged. Otherwise it is processed by
* doClass(...)
- *
+ *
* @param className
* @param clazz
* @param domain
@@ -227,7 +226,7 @@
* defined have bodies, and a static final logger object is added with the
* name of this class as an argument, and each method then gets processed with
* doMethod(...) to have logger calls added.
- *
+ *
* @param name
* class name (slashes separate, not dots)
* @param clazz
@@ -285,7 +284,7 @@
/**
* process a single method - this means add entry/exit logging if requested.
* It is only called for methods with a body.
- *
+ *
* @param method
* method to work on
* @throws NotFoundException
@@ -310,4 +309,4 @@
method.insertAfter(after);
}
}
-}
\ No newline at end of file
+}
diff --git a/slf4j-ext/src/test/java/org/slf4j/NDCTest.java b/slf4j-ext/src/test/java/org/slf4j/NDCTest.java
index f919a4b..4adfd31 100644
--- a/slf4j-ext/src/test/java/org/slf4j/NDCTest.java
+++ b/slf4j-ext/src/test/java/org/slf4j/NDCTest.java
@@ -41,14 +41,12 @@
assertEquals("", NDC.pop());
}
-
@Test
public void testSmoke() {
NDC.push("a");
String result = NDC.pop();
assertEquals("a", result);
}
-
@Test
public void testSmoke2() {
diff --git a/slf4j-ext/src/test/java/org/slf4j/cal10n_dummy/LocLoggerTest.java b/slf4j-ext/src/test/java/org/slf4j/cal10n_dummy/LocLoggerTest.java
index c6c6e00..d80a7de 100644
--- a/slf4j-ext/src/test/java/org/slf4j/cal10n_dummy/LocLoggerTest.java
+++ b/slf4j-ext/src/test/java/org/slf4j/cal10n_dummy/LocLoggerTest.java
@@ -37,7 +37,8 @@
import ch.qos.cal10n.IMessageConveyor;
import ch.qos.cal10n.MessageConveyor;
-public class LocLoggerTest {
+
+public class LocLoggerTest {
ListAppender listAppender;
org.apache.log4j.Logger log4jRoot;
@@ -46,7 +47,6 @@
LocLoggerFactory llFactory_uk = new LocLoggerFactory(imc);
final static String EXPECTED_FILE_NAME = "LocLoggerTest.java";
-
@Before
public void setUp() throws Exception {
@@ -64,7 +64,6 @@
assertEquals(EXPECTED_FILE_NAME, le.getLocationInformation().getFileName());
}
-
@Test
public void testSmoke() {
LocLogger locLogger = llFactory_uk.getLocLogger(this.getClass());
diff --git a/slf4j-ext/src/test/java/org/slf4j/dummyExt/EventLoggerTest.java b/slf4j-ext/src/test/java/org/slf4j/dummyExt/EventLoggerTest.java
index 40d5976..b65b33f 100644
--- a/slf4j-ext/src/test/java/org/slf4j/dummyExt/EventLoggerTest.java
+++ b/slf4j-ext/src/test/java/org/slf4j/dummyExt/EventLoggerTest.java
@@ -38,13 +38,13 @@
import org.slf4j.MDC;
import org.slf4j.ext.EventData;
import org.slf4j.ext.EventLogger;
-public class EventLoggerTest {
+
+public class EventLoggerTest {
ListAppender listAppender;
org.apache.log4j.Logger log4;
final static String EXPECTED_FILE_NAME = "EventLoggerTest.java";
-
@Before
public void setUp() throws Exception {
@@ -76,7 +76,7 @@
assertEquals(expectedMsg, le.getMessage());
assertEquals(EXPECTED_FILE_NAME, le.getLocationInformation().getFileName());
}
-
+
@Test
public void testEventLogger() {
EventData data[] = new EventData[2];
diff --git a/slf4j-ext/src/test/java/org/slf4j/dummyExt/MDCStrLookupTest.java b/slf4j-ext/src/test/java/org/slf4j/dummyExt/MDCStrLookupTest.java
index db77298..d5a0a38 100644
--- a/slf4j-ext/src/test/java/org/slf4j/dummyExt/MDCStrLookupTest.java
+++ b/slf4j-ext/src/test/java/org/slf4j/dummyExt/MDCStrLookupTest.java
@@ -29,7 +29,8 @@
import org.junit.Test;
import org.slf4j.MDC;
import org.slf4j.ext.MDCStrLookup;
-public class MDCStrLookupTest {
+
+public class MDCStrLookupTest {
@Test
public void testLookup() throws Exception {
diff --git a/slf4j-ext/src/test/java/org/slf4j/dummyExt/PackageTest.java b/slf4j-ext/src/test/java/org/slf4j/dummyExt/PackageTest.java
index 56fb103..8c9e39e 100644
--- a/slf4j-ext/src/test/java/org/slf4j/dummyExt/PackageTest.java
+++ b/slf4j-ext/src/test/java/org/slf4j/dummyExt/PackageTest.java
@@ -24,8 +24,6 @@
*/
package org.slf4j.dummyExt;
-import junit.framework.*;
-
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
diff --git a/slf4j-ext/src/test/java/org/slf4j/instrumentation/ToStringHelperTest.java b/slf4j-ext/src/test/java/org/slf4j/instrumentation/ToStringHelperTest.java
index 7c41a74..9e8a63e 100644
--- a/slf4j-ext/src/test/java/org/slf4j/instrumentation/ToStringHelperTest.java
+++ b/slf4j-ext/src/test/java/org/slf4j/instrumentation/ToStringHelperTest.java
@@ -28,7 +28,7 @@
import org.junit.Test;
-public class ToStringHelperTest {
+public class ToStringHelperTest {
@Test
public void testRenderer() {
diff --git a/slf4j-ext/src/test/java/org/slf4j/profiler/PackageTest.java b/slf4j-ext/src/test/java/org/slf4j/profiler/PackageTest.java
index 1c2b09c..a0963b0 100644
--- a/slf4j-ext/src/test/java/org/slf4j/profiler/PackageTest.java
+++ b/slf4j-ext/src/test/java/org/slf4j/profiler/PackageTest.java
@@ -29,9 +29,7 @@
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
-@SuiteClasses({UtilTest.class,
- ProfilerTest.class})
+@SuiteClasses({ UtilTest.class, ProfilerTest.class })
public class PackageTest {
-
}diff --git a/slf4j-ext/src/test/java/org/slf4j/profiler/ProfilerTest.java b/slf4j-ext/src/test/java/org/slf4j/profiler/ProfilerTest.java
index cd1ec3c..13d557d 100644
--- a/slf4j-ext/src/test/java/org/slf4j/profiler/ProfilerTest.java
+++ b/slf4j-ext/src/test/java/org/slf4j/profiler/ProfilerTest.java
@@ -31,6 +31,7 @@
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
public class ProfilerTest {
Logger logger = LoggerFactory.getLogger(ProfilerTest.class);
diff --git a/slf4j-jcl/pom.xml b/slf4j-jcl/pom.xml
index 3bb0aff..63a4227 100644
--- a/slf4j-jcl/pom.xml
+++ b/slf4j-jcl/pom.xml
@@ -7,7 +7,7 @@
org.slf4j
slf4j-parent
- 1.7.14
+ 1.7.19
slf4j-jcl
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 67a81f4..70ef3c4 100644
--- a/slf4j-jcl/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
+++ b/slf4j-jcl/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
@@ -57,7 +57,6 @@
// to avoid constant folding by the compiler, this field must *not* be final
public static String REQUESTED_API_VERSION = "1.6.99"; // !final
-
// Binding specific code:
private static final String loggerFactoryClassStr = JCLLoggerFactory.class.getName();
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 98218ed..21a48df 100644
--- a/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
+++ b/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
@@ -57,7 +57,7 @@
public static StaticMarkerBinder getSingleton() {
return SINGLETON;
}
-
+
/**
* Currently this method always returns an instance of
* {@link BasicMarkerFactory}.
diff --git a/slf4j-jcl/src/test/java/org/slf4j/InvocationTest.java b/slf4j-jcl/src/test/java/org/slf4j/InvocationTest.java
index dcc294f..50b74d7 100644
--- a/slf4j-jcl/src/test/java/org/slf4j/InvocationTest.java
+++ b/slf4j-jcl/src/test/java/org/slf4j/InvocationTest.java
@@ -42,7 +42,6 @@
Level oldLevel;
java.util.logging.Logger root = java.util.logging.Logger.getLogger("");
-
@Before
public void setUp() throws Exception {
diff --git a/slf4j-jdk14/pom.xml b/slf4j-jdk14/pom.xml
index 0faf805..032a21b 100644
--- a/slf4j-jdk14/pom.xml
+++ b/slf4j-jdk14/pom.xml
@@ -7,7 +7,7 @@
org.slf4j
slf4j-parent
- 1.7.14
+ 1.7.19
slf4j-jdk14
diff --git a/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerAdapter.java b/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerAdapter.java
index 6122284..7cfafc8 100644
--- a/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerAdapter.java
+++ b/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerAdapter.java
@@ -29,6 +29,8 @@
import org.slf4j.Logger;
import org.slf4j.Marker;
+import org.slf4j.event.EventConstants;
+import org.slf4j.event.LoggingEvent;
import org.slf4j.helpers.FormattingTuple;
import org.slf4j.helpers.MarkerIgnoringBase;
import org.slf4j.helpers.MessageFormatter;
@@ -574,11 +576,10 @@
LogRecord record = new LogRecord(level, msg);
record.setLoggerName(getName());
record.setThrown(t);
- // Note: parameters in record are not set because SLF4J only
+ // Note: parameters in record are not set because SLF4J only
// supports a single formatting style
fillCallerData(callerFQCN, record);
logger.log(record);
-
}
static String SELF = JDK14LoggerAdapter.class.getName();
@@ -621,8 +622,20 @@
}
public void log(Marker marker, String callerFQCN, int level, String message, Object[] argArray, Throwable t) {
+ Level julLevel = slf4jLevelIntToJULLevel(level);
+ // the logger.isLoggable check avoids the unconditional
+ // construction of location data for disabled log
+ // statements. As of 2008-07-31, callers of this method
+ // do not perform this check. See also
+ // http://jira.qos.ch/browse/SLF4J-81
+ if (logger.isLoggable(julLevel)) {
+ log(callerFQCN, julLevel, message, t);
+ }
+ }
+
+ private Level slf4jLevelIntToJULLevel(int slf4jLevelInt) {
Level julLevel;
- switch (level) {
+ switch (slf4jLevelInt) {
case LocationAwareLogger.TRACE_INT:
julLevel = Level.FINEST;
break;
@@ -639,15 +652,43 @@
julLevel = Level.SEVERE;
break;
default:
- throw new IllegalStateException("Level number " + level + " is not recognized.");
- }
- // the logger.isLoggable check avoids the unconditional
- // construction of location data for disabled log
- // statements. As of 2008-07-31, callers of this method
- // do not perform this check. See also
- // http://jira.qos.ch/browse/SLF4J-81
+ throw new IllegalStateException("Level number " + slf4jLevelInt + " is not recognized.");
+ }
+ return julLevel;
+ }
+
+ /**
+ * @since 1.7.15
+ */
+ public void log(LoggingEvent event) {
+ Level julLevel = slf4jLevelIntToJULLevel(event.getLevel().toInt());
if (logger.isLoggable(julLevel)) {
- log(callerFQCN, julLevel, message, t);
- }
+ LogRecord record = eventToRecord(event, julLevel);
+ logger.log(record);
+ }
+ }
+
+ private LogRecord eventToRecord(LoggingEvent event, Level julLevel) {
+ String format = event.getMessage();
+ Object[] arguments = event.getArgumentArray();
+ FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
+ if (ft.getThrowable() != null && event.getThrowable() != null) {
+ throw new IllegalArgumentException("both last element in argument array and last argument are of type Throwable");
+ }
+
+ Throwable t = event.getThrowable();
+ if (ft.getThrowable() != null) {
+ t = ft.getThrowable();
+ throw new IllegalStateException("fix above code");
+ }
+
+ LogRecord record = new LogRecord(julLevel, ft.getMessage());
+ record.setLoggerName(event.getLoggerName());
+ record.setMillis(event.getTimeStamp());
+ record.setSourceClassName(EventConstants.NA_SUBST);
+ record.setSourceMethodName(EventConstants.NA_SUBST);
+
+ record.setThrown(t);
+ return record;
}
}
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 f8f794e..ba6c179 100644
--- a/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerFactory.java
+++ b/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerFactory.java
@@ -43,6 +43,8 @@
public JDK14LoggerFactory() {
loggerMap = new ConcurrentHashMap();
+ // ensure jul initialization. see also SLF4J-359
+ java.util.logging.LogManager.getLogManager();
}
/*
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 4948a69..0a1dcb4 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,7 @@
private StaticMDCBinder() {
}
-
+
/**
* Return the singleton of this class.
*
@@ -51,7 +51,7 @@
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 98218ed..21a48df 100644
--- a/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
+++ b/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
@@ -57,7 +57,7 @@
public static StaticMarkerBinder getSingleton() {
return SINGLETON;
}
-
+
/**
* Currently this method always returns an instance of
* {@link BasicMarkerFactory}.
diff --git a/slf4j-jdk14/src/main/resources/META-INF/MANIFEST.MF b/slf4j-jdk14/src/main/resources/META-INF/MANIFEST.MF
index 6249cfc..f7334d1 100644
--- a/slf4j-jdk14/src/main/resources/META-INF/MANIFEST.MF
+++ b/slf4j-jdk14/src/main/resources/META-INF/MANIFEST.MF
@@ -5,5 +5,8 @@
Bundle-Vendor: SLF4J.ORG
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Export-Package: org.slf4j.impl;version=${parsedVersion.osgiVersion}
-Import-Package: org.slf4j;version=${parsedVersion.osgiVersion}, org.slf4j.spi;version=${parsedVersion.osgiVersion}, org.slf4j.helpers;version=${parsedVersion.osgiVersion}
+Import-Package: org.slf4j;version=${parsedVersion.osgiVersion},
+ org.slf4j.spi;version=${parsedVersion.osgiVersion},
+ org.slf4j.helpers;version=${parsedVersion.osgiVersion},
+ org.slf4j.event;version=${parsedVersion.osgiVersion}
Fragment-Host: slf4j.apidiff --git a/slf4j-jdk14/src/test/java/org/slf4j/LoggerFactoryFriend.java b/slf4j-jdk14/src/test/java/org/slf4j/LoggerFactoryFriend.java
new file mode 100644
index 0000000..edf5fcf
--- /dev/null
+++ b/slf4j-jdk14/src/test/java/org/slf4j/LoggerFactoryFriend.java
@@ -0,0 +1,7 @@
+package org.slf4j;
+
+public class LoggerFactoryFriend {
+ static public void reset() {
+ LoggerFactory.reset();
+ }
+}
diff --git a/slf4j-jdk14/src/test/java/org/slf4j/impl/JDK14AdapterLoggerNameTest.java b/slf4j-jdk14/src/test/java/org/slf4j/impl/JDK14AdapterLoggerNameTest.java
index 17651d5..4e5273b 100644
--- a/slf4j-jdk14/src/test/java/org/slf4j/impl/JDK14AdapterLoggerNameTest.java
+++ b/slf4j-jdk14/src/test/java/org/slf4j/impl/JDK14AdapterLoggerNameTest.java
@@ -26,6 +26,7 @@
import static org.junit.Assert.assertNotNull;
+import java.util.Random;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
@@ -36,35 +37,45 @@
public class JDK14AdapterLoggerNameTest {
private MockHandler mockHandler;
-
+ static Random random = new Random(System.currentTimeMillis());
+ long diff = random.nextInt(10000);
+ String loggerName = "JDK14AdapterLoggerNameTest"+diff;
+
+ Logger logger = Logger.getLogger(loggerName);
+
@Before
public void setUp() throws Exception {
- Logger logger = Logger.getLogger("TEST");
- mockHandler = new MockHandler();
- removeHandlers(logger);
- logger.addHandler(mockHandler);
+ Logger logger = Logger.getLogger(loggerName);
+ addMockHandler(logger);
}
+
+
@After
public void tearDown() throws Exception {
- removeHandlers(Logger.getLogger("TEST"));
+ removeHandlers(Logger.getLogger(loggerName));
}
@Test
- public void testLoggerNameusingJdkLogging() throws Exception {
- Logger.getLogger("TEST").info("test message");
+ public void testLoggerNameUsingJdkLogging() throws Exception {
+ logger.info("test message");
assertCorrectLoggerName();
-
}
@Test
public void testLoggerNameUsingSlf4j() throws Exception {
JDK14LoggerFactory factory = new JDK14LoggerFactory();
- org.slf4j.Logger logger = factory.getLogger("TEST");
+ org.slf4j.Logger logger = factory.getLogger(loggerName);
logger.info("test message");
assertCorrectLoggerName();
}
+ private void addMockHandler(Logger logger) {
+ mockHandler = new MockHandler();
+ removeHandlers(logger);
+ logger.addHandler(mockHandler);
+ }
+
private void removeHandlers(Logger logger) {
logger.setUseParentHandlers(false);
Handler[] handlers = logger.getHandlers();
diff --git a/slf4j-jdk14/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java b/slf4j-jdk14/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java
new file mode 100644
index 0000000..16a7647
--- /dev/null
+++ b/slf4j-jdk14/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java
@@ -0,0 +1,153 @@
+/**
+ * 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/PerfTest.java b/slf4j-jdk14/src/test/java/org/slf4j/impl/PerfTest.java
index 269ffaf..77635f7 100644
--- a/slf4j-jdk14/src/test/java/org/slf4j/impl/PerfTest.java
+++ b/slf4j-jdk14/src/test/java/org/slf4j/impl/PerfTest.java
@@ -24,17 +24,19 @@
*/
package org.slf4j.impl;
+import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.helpers.BogoPerf;
+@Ignore
public class PerfTest {
static long REFERENCE_BIPS = 9000;
@Test
- public void testBug72() {
+ public void issue63() {
int LEN = 1000 * 1000 * 10;
debugLoop(LEN); // warm up
diff --git a/slf4j-jdk14/src/test/java/org/slf4j/impl/RecordingHandler.java b/slf4j-jdk14/src/test/java/org/slf4j/impl/RecordingHandler.java
new file mode 100644
index 0000000..118ccd7
--- /dev/null
+++ b/slf4j-jdk14/src/test/java/org/slf4j/impl/RecordingHandler.java
@@ -0,0 +1,26 @@
+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-jdk14/src/test/java/org/slf4j/issue/LoggerSerializationTest.java b/slf4j-jdk14/src/test/java/org/slf4j/issue/LoggerSerializationTest.java
index 73314fe..41ed758 100644
--- a/slf4j-jdk14/src/test/java/org/slf4j/issue/LoggerSerializationTest.java
+++ b/slf4j-jdk14/src/test/java/org/slf4j/issue/LoggerSerializationTest.java
@@ -42,7 +42,7 @@
* See http://jira.qos.ch/browse/SLF4J-252
* @author Thorbjorn Ravn Andersen
*/
-public class LoggerSerializationTest {
+public class LoggerSerializationTest {
static class LoggerHolder implements Serializable {
private static final long serialVersionUID = 1L;
diff --git a/slf4j-log4j12/pom.xml b/slf4j-log4j12/pom.xml
index bf180c4..f724e09 100644
--- a/slf4j-log4j12/pom.xml
+++ b/slf4j-log4j12/pom.xml
@@ -7,7 +7,7 @@
org.slf4j
slf4j-parent
- 1.7.14
+ 1.7.19
slf4j-log4j12
diff --git a/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerAdapter.java b/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerAdapter.java
index 0685a4e..ebd568e 100644
--- a/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerAdapter.java
+++ b/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerAdapter.java
@@ -24,11 +24,16 @@
*/
package org.slf4j.impl;
+import static org.slf4j.event.EventConstants.NA_SUBST;
+
import java.io.Serializable;
import org.apache.log4j.Level;
+import org.apache.log4j.spi.LocationInfo;
+import org.apache.log4j.spi.ThrowableInformation;
import org.slf4j.Logger;
import org.slf4j.Marker;
+import org.slf4j.event.LoggingEvent;
import org.slf4j.helpers.FormattingTuple;
import org.slf4j.helpers.MarkerIgnoringBase;
import org.slf4j.helpers.MessageFormatter;
@@ -572,6 +577,11 @@
}
public void log(Marker marker, String callerFQCN, int level, String msg, Object[] argArray, Throwable t) {
+ Level log4jLevel = toLog4jLevel(level);
+ logger.log(callerFQCN, log4jLevel, msg, t);
+ }
+
+ private Level toLog4jLevel(int level) {
Level log4jLevel;
switch (level) {
case LocationAwareLogger.TRACE_INT:
@@ -592,7 +602,34 @@
default:
throw new IllegalStateException("Level number " + level + " is not recognized.");
}
- logger.log(callerFQCN, log4jLevel, msg, t);
+ return log4jLevel;
+ }
+
+ public void log(LoggingEvent event) {
+ Level log4jLevel = toLog4jLevel(event.getLevel().toInt());
+ if (!logger.isEnabledFor(log4jLevel))
+ return;
+
+ org.apache.log4j.spi.LoggingEvent log4jevent = toLog4jEvent(event, log4jLevel);
+ logger.callAppenders(log4jevent);
+
+ }
+
+ private org.apache.log4j.spi.LoggingEvent toLog4jEvent(LoggingEvent event, Level log4jLevel) {
+
+ FormattingTuple ft = MessageFormatter.format(event.getMessage(), event.getArgumentArray(), event.getThrowable());
+
+ LocationInfo locationInfo = new LocationInfo(NA_SUBST, NA_SUBST, NA_SUBST, "0");
+
+ ThrowableInformation ti = null;
+ Throwable t = ft.getThrowable();
+ if (t != null)
+ ti = new ThrowableInformation(t);
+
+ org.apache.log4j.spi.LoggingEvent log4jEvent = new org.apache.log4j.spi.LoggingEvent(FQCN, logger, event.getTimeStamp(), log4jLevel, ft.getMessage(),
+ event.getThreadName(), ti, null, locationInfo, null);
+
+ return log4jEvent;
}
}
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 fa1b292..686db90 100644
--- a/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerFactory.java
+++ b/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerFactory.java
@@ -41,7 +41,7 @@
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 {
@@ -62,6 +62,8 @@
public Log4jLoggerFactory() {
loggerMap = new ConcurrentHashMap();
+ // force log4j to initialize
+ org.apache.log4j.LogManager.getRootLogger();
}
/*
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 78c8bcd..bb0f065 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,7 @@
private StaticMDCBinder() {
}
-
+
/**
* Return the singleton of this class.
*
@@ -50,7 +50,7 @@
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 98218ed..21a48df 100644
--- a/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
+++ b/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
@@ -57,7 +57,7 @@
public static StaticMarkerBinder getSingleton() {
return SINGLETON;
}
-
+
/**
* Currently this method always returns an instance of
* {@link BasicMarkerFactory}.
diff --git a/slf4j-log4j12/src/main/resources/META-INF/MANIFEST.MF b/slf4j-log4j12/src/main/resources/META-INF/MANIFEST.MF
index b5be4ce..148ff62 100644
--- a/slf4j-log4j12/src/main/resources/META-INF/MANIFEST.MF
+++ b/slf4j-log4j12/src/main/resources/META-INF/MANIFEST.MF
@@ -5,5 +5,9 @@
Bundle-Vendor: SLF4J.ORG
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Export-Package: org.slf4j.impl;version=${parsedVersion.osgiVersion}
-Import-Package: org.slf4j;version=${parsedVersion.osgiVersion}, org.slf4j.spi;version=${parsedVersion.osgiVersion}, org.slf4j.helpers;version=${parsedVersion.osgiVersion}, org.apache.log4j
+Import-Package: org.slf4j;version=${parsedVersion.osgiVersion},
+ org.slf4j.spi;version=${parsedVersion.osgiVersion},
+ org.slf4j.helpers;version=${parsedVersion.osgiVersion},
+ org.slf4j.event;version=${parsedVersion.osgiVersion},
+ org.apache.log4j
Fragment-Host: slf4j.apidiff --git a/slf4j-log4j12/src/test/java/org/slf4j/InvocationTest.java b/slf4j-log4j12/src/test/java/org/slf4j/InvocationTest.java
index 8bf3453..d687383 100644
--- a/slf4j-log4j12/src/test/java/org/slf4j/InvocationTest.java
+++ b/slf4j-log4j12/src/test/java/org/slf4j/InvocationTest.java
@@ -48,7 +48,6 @@
ListAppender listAppender = new ListAppender();
org.apache.log4j.Logger root;
-
@Before
public void setUp() throws Exception {
root = org.apache.log4j.Logger.getRootLogger();
@@ -59,7 +58,7 @@
public void tearDown() throws Exception {
root.getLoggerRepository().resetConfiguration();
}
-
+
@Test
public void test1() {
Logger logger = LoggerFactory.getLogger("test1");
@@ -119,8 +118,8 @@
String[] parameters = null;
String msg = "hello {}";
- logger.debug(msg, (Object[]) parameters);
-
+ logger.debug(msg, (Object[]) parameters);
+
assertEquals(1, listAppender.list.size());
LoggingEvent e = (LoggingEvent) listAppender.list.get(0);
assertEquals(msg, e.getMessage());
diff --git a/slf4j-log4j12/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java b/slf4j-log4j12/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java
new file mode 100644
index 0000000..c9fde1d
--- /dev/null
+++ b/slf4j-log4j12/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java
@@ -0,0 +1,127 @@
+/**
+ * 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-log4j12/src/test/java/org/slf4j/impl/RecursiveAppender.java b/slf4j-log4j12/src/test/java/org/slf4j/impl/RecursiveAppender.java
index 3f1ff5f..267e2b2 100644
--- a/slf4j-log4j12/src/test/java/org/slf4j/impl/RecursiveAppender.java
+++ b/slf4j-log4j12/src/test/java/org/slf4j/impl/RecursiveAppender.java
@@ -24,6 +24,8 @@
*/
package org.slf4j.impl;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Random;
import org.apache.log4j.AppenderSkeleton;
@@ -34,15 +36,20 @@
public class RecursiveAppender extends AppenderSkeleton {
int diff = new Random().nextInt();
+ int activationDelay = 0;
+ String loggerName = "org.slf4j.impl.RecursiveAppender" + diff;
+
+ List events = new ArrayList();
public RecursiveAppender() {
- System.out.println("in RecursiveAppender constructor");
- Logger logger = LoggerFactory.getLogger("RecursiveAppender" + diff);
- System.out.println("logger class=" + logger.getClass().getName());
+ System.out.println("entering RecursiveAppender constructor");
+ Logger logger = LoggerFactory.getLogger(loggerName);
logger.info("Calling a logger in the constructor");
+ System.out.println("exiting RecursiveAppender constructor");
}
- protected void append(LoggingEvent arg0) {
+ protected void append(LoggingEvent e) {
+ events.add(e);
}
public void close() {
@@ -51,4 +58,31 @@
public boolean requiresLayout() {
return false;
}
+
+ @Override
+ public void activateOptions() {
+ System.out.println("entering RecursiveAppender.activateOptions");
+ if (activationDelay > 0) {
+ Logger logger = LoggerFactory.getLogger(loggerName);
+ logger.info("About to wait {} millis", activationDelay);
+ try {
+ Thread.sleep(activationDelay);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ logger.info("Done waiting {} millis", activationDelay);
+ }
+ super.activateOptions();
+
+ System.out.println("exiting RecursiveAppender.activateOptions");
+ }
+
+ public int getActivationDelay() {
+ return activationDelay;
+ }
+
+ public void setActivationDelay(int activationDelay) {
+ this.activationDelay = activationDelay;
+ }
+
}
diff --git a/slf4j-log4j12/src/test/java/org/slf4j/impl/RecursiveInitializationTest.java b/slf4j-log4j12/src/test/java/org/slf4j/impl/RecursiveInitializationTest.java
index 9a3fa5d..3e02043 100644
--- a/slf4j-log4j12/src/test/java/org/slf4j/impl/RecursiveInitializationTest.java
+++ b/slf4j-log4j12/src/test/java/org/slf4j/impl/RecursiveInitializationTest.java
@@ -27,21 +27,17 @@
import java.util.Random;
import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
public class RecursiveInitializationTest {
// value of LogManager.DEFAULT_CONFIGURATION_KEY;
static String CONFIG_FILE_KEY = "log4j.configuration";
int diff = new Random().nextInt(10000);
-
- @Before
- public void setUp() throws Exception {
- System.setProperty(CONFIG_FILE_KEY, "recursiveInit.properties");
- }
+ String loggerName = "org.slf4j.impl.RecursiveInitializationTest";
@After
public void tearDown() throws Exception {
@@ -49,9 +45,9 @@
}
@Test
- public void testLog4j() {
- Logger logger = LoggerFactory.getLogger("x" + diff);
- System.out.println("logger class=" + logger.getClass().getName());
+ public void loggingDuringInitialization() {
+ System.setProperty(CONFIG_FILE_KEY, "recursiveInit.properties");
+ Logger logger = LoggerFactory.getLogger(loggerName + ".loggingDuringInitialization-" + diff);
logger.info("hello");
}
diff --git a/slf4j-log4j12/src/test/resources/recursiveInitWithActivationDelay.properties b/slf4j-log4j12/src/test/resources/recursiveInitWithActivationDelay.properties
new file mode 100644
index 0000000..91e93f6
--- /dev/null
+++ b/slf4j-log4j12/src/test/resources/recursiveInitWithActivationDelay.properties
@@ -0,0 +1,9 @@
+log4j.debug=true
+log4j.rootLogger=DEBUG, CONSOLE, RECURSIVE
+
+log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
+log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE.layout.ConversionPattern=CON %d [%t] %c - %m%n
+
+log4j.appender.RECURSIVE=org.slf4j.impl.RecursiveAppender
+log4j.appender.RECURSIVE.activationDelay=10
\ No newline at end of file
diff --git a/slf4j-migrator/pom.xml b/slf4j-migrator/pom.xml
index 3d67e10..d25152f 100644
--- a/slf4j-migrator/pom.xml
+++ b/slf4j-migrator/pom.xml
@@ -7,7 +7,7 @@
org.slf4j
slf4j-parent
- 1.7.14
+ 1.7.19
slf4j-migrator
diff --git a/slf4j-migrator/src/main/java/org/slf4j/migrator/internal/MigratorFrame.java b/slf4j-migrator/src/main/java/org/slf4j/migrator/internal/MigratorFrame.java
index 1625515..aa37d40 100644
--- a/slf4j-migrator/src/main/java/org/slf4j/migrator/internal/MigratorFrame.java
+++ b/slf4j-migrator/src/main/java/org/slf4j/migrator/internal/MigratorFrame.java
@@ -46,16 +46,6 @@
import org.slf4j.migrator.Constant;
import org.slf4j.migrator.helper.SpringLayoutHelper;
-/**
- * This code was edited or generated using CloudGarden's Jigloo SWT/Swing GUI
- * Builder, which is free for non-commercial use. If Jigloo is being used
- * commercially (ie, by a corporation, company or business for any purpose
- * whatever) then you should purchase a license for each developer using Jigloo.
- * Please visit www.cloudgarden.com for details. Use of Jigloo implies
- * acceptance of these licensing terms. A COMMERCIAL LICENSE HAS NOT BEEN
- * PURCHASED FOR THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED LEGALLY FOR
- * ANY CORPORATE OR COMMERCIAL PURPOSE.
- */
public class MigratorFrame extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
diff --git a/slf4j-migrator/src/test/java/org/slf4j/migrator/FileConverterTest.java b/slf4j-migrator/src/test/java/org/slf4j/migrator/FileConverterTest.java
index a2b5bc4..4db2002 100644
--- a/slf4j-migrator/src/test/java/org/slf4j/migrator/FileConverterTest.java
+++ b/slf4j-migrator/src/test/java/org/slf4j/migrator/FileConverterTest.java
@@ -31,8 +31,8 @@
import org.junit.Test;
import org.slf4j.migrator.internal.NopProgressListener;
import org.slf4j.migrator.line.EmptyRuleSet;
-public class FileConverterTest {
+public class FileConverterTest {
@Test
@Ignore
diff --git a/slf4j-migrator/src/test/java/org/slf4j/migrator/ProjectConverterTest.java b/slf4j-migrator/src/test/java/org/slf4j/migrator/ProjectConverterTest.java
index 975355d..1bf1905 100644
--- a/slf4j-migrator/src/test/java/org/slf4j/migrator/ProjectConverterTest.java
+++ b/slf4j-migrator/src/test/java/org/slf4j/migrator/ProjectConverterTest.java
@@ -30,7 +30,7 @@
import org.junit.Test;
import org.slf4j.migrator.internal.NopProgressListener;
-public class ProjectConverterTest {
+public class ProjectConverterTest {
public void test() {
}
diff --git a/slf4j-migrator/src/test/java/org/slf4j/migrator/helper/AbbreviatorTest.java b/slf4j-migrator/src/test/java/org/slf4j/migrator/helper/AbbreviatorTest.java
index 106aaf9..9f24df5 100644
--- a/slf4j-migrator/src/test/java/org/slf4j/migrator/helper/AbbreviatorTest.java
+++ b/slf4j-migrator/src/test/java/org/slf4j/migrator/helper/AbbreviatorTest.java
@@ -28,6 +28,7 @@
import static org.junit.Assert.assertTrue;
import org.junit.Test;
+
public class AbbreviatorTest {
static final char FS = '/';
diff --git a/slf4j-migrator/src/test/java/org/slf4j/migrator/line/JCLRuleSetTest.java b/slf4j-migrator/src/test/java/org/slf4j/migrator/line/JCLRuleSetTest.java
index a1f28e9..6282b91 100644
--- a/slf4j-migrator/src/test/java/org/slf4j/migrator/line/JCLRuleSetTest.java
+++ b/slf4j-migrator/src/test/java/org/slf4j/migrator/line/JCLRuleSetTest.java
@@ -27,6 +27,7 @@
import static org.junit.Assert.assertEquals;
import org.junit.Test;
+
public class JCLRuleSetTest {
LineConverter jclConverter = new LineConverter(new JCLRuleSet());
@@ -38,7 +39,6 @@
// Log import replacement
assertEquals("import org.slf4j.Logger;", jclConverter.getOneLineReplacement("import org.apache.commons.logging.Log;"));
}
-
@Test
public void testLogFactoryGetLogReplacement() {
@@ -93,7 +93,6 @@
jclConverter.getOneLineReplacement("// myLog = LogFactory.getFactory().getInstance(MyClass.class);//logger instanciation"));
}
-
@Test
public void testLogDeclarationReplacement() {
diff --git a/slf4j-migrator/src/test/java/org/slf4j/migrator/line/NoConversionTest.java b/slf4j-migrator/src/test/java/org/slf4j/migrator/line/NoConversionTest.java
index 616f5df..179b280 100644
--- a/slf4j-migrator/src/test/java/org/slf4j/migrator/line/NoConversionTest.java
+++ b/slf4j-migrator/src/test/java/org/slf4j/migrator/line/NoConversionTest.java
@@ -27,7 +27,8 @@
import static org.junit.Assert.assertEquals;
import org.junit.Test;
-public class NoConversionTest {
+
+public class NoConversionTest {
/**
* This test shows that performing JCL to SLF4J conversion has no impact on
diff --git a/slf4j-nop/pom.xml b/slf4j-nop/pom.xml
index 073ea4c..31408cb 100644
--- a/slf4j-nop/pom.xml
+++ b/slf4j-nop/pom.xml
@@ -7,7 +7,7 @@
org.slf4j
slf4j-parent
- 1.7.14
+ 1.7.19
slf4j-nop
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 c570b46..dccb05a 100644
--- a/slf4j-nop/src/main/java/org/slf4j/impl/StaticMDCBinder.java
+++ b/slf4j-nop/src/main/java/org/slf4j/impl/StaticMDCBinder.java
@@ -51,7 +51,7 @@
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 98218ed..21a48df 100644
--- a/slf4j-nop/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
+++ b/slf4j-nop/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
@@ -57,7 +57,7 @@
public static StaticMarkerBinder getSingleton() {
return SINGLETON;
}
-
+
/**
* Currently this method always returns an instance of
* {@link BasicMarkerFactory}.
diff --git a/slf4j-nop/src/main/resources/META-INF/MANIFEST.MF b/slf4j-nop/src/main/resources/META-INF/MANIFEST.MF
index 0151226..88f1cc9 100644
--- a/slf4j-nop/src/main/resources/META-INF/MANIFEST.MF
+++ b/slf4j-nop/src/main/resources/META-INF/MANIFEST.MF
@@ -5,5 +5,8 @@
Bundle-Vendor: SLF4J.ORG
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Export-Package: org.slf4j.impl;version=${parsedVersion.osgiVersion}
-Import-Package: org.slf4j;version=${parsedVersion.osgiVersion}, org.slf4j.spi;version=${parsedVersion.osgiVersion}, org.slf4j.helpers;version=${parsedVersion.osgiVersion}
+Import-Package: org.slf4j;version=${parsedVersion.osgiVersion},
+ org.slf4j.spi;version=${parsedVersion.osgiVersion},
+ org.slf4j.helpers;version=${parsedVersion.osgiVersion},
+ org.slf4j.event;version=${parsedVersion.osgiVersion}
Fragment-Host: slf4j.apidiff --git a/slf4j-nop/src/test/java/org/slf4j/LoggerFactoryFriend.java b/slf4j-nop/src/test/java/org/slf4j/LoggerFactoryFriend.java
new file mode 100644
index 0000000..edf5fcf
--- /dev/null
+++ b/slf4j-nop/src/test/java/org/slf4j/LoggerFactoryFriend.java
@@ -0,0 +1,7 @@
+package org.slf4j;
+
+public class LoggerFactoryFriend {
+ static public void reset() {
+ LoggerFactory.reset();
+ }
+}
diff --git a/slf4j-nop/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java b/slf4j-nop/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java
new file mode 100644
index 0000000..18a3732
--- /dev/null
+++ b/slf4j-nop/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java
@@ -0,0 +1,150 @@
+/**
+ * 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.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);
+
+ final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1);
+
+ int diff = new Random().nextInt(10000);
+ String loggerName = "org.slf4j.impl.MultithreadedInitializationTest";
+ private final PrintStream oldErr = System.err;
+ 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();
+
+ assertEquals(0, 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();
+ }
+ logger = LoggerFactory.getLogger(this.getClass().getName() + "-" + count);
+ 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 = 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/pom.xml b/slf4j-simple/pom.xml
index 6217d65..94bdd41 100644
--- a/slf4j-simple/pom.xml
+++ b/slf4j-simple/pom.xml
@@ -7,7 +7,7 @@
org.slf4j
slf4j-parent
- 1.7.14
+ 1.7.19
slf4j-simple
diff --git a/slf4j-simple/src/main/java/org/slf4j/impl/SimpleLogger.java b/slf4j-simple/src/main/java/org/slf4j/impl/SimpleLogger.java
index 984c294..4f95260 100644
--- a/slf4j-simple/src/main/java/org/slf4j/impl/SimpleLogger.java
+++ b/slf4j-simple/src/main/java/org/slf4j/impl/SimpleLogger.java
@@ -36,6 +36,7 @@
import java.util.Properties;
import org.slf4j.Logger;
+import org.slf4j.event.LoggingEvent;
import org.slf4j.helpers.FormattingTuple;
import org.slf4j.helpers.MarkerIgnoringBase;
import org.slf4j.helpers.MessageFormatter;
@@ -182,6 +183,9 @@
// Load properties file, if found.
// Override with system properties.
static void init() {
+ if (INITIALIZED) {
+ return;
+ }
INITIALIZED = true;
loadProperties();
@@ -258,9 +262,6 @@
* SimpleLogger instances.
*/
SimpleLogger(String name) {
- if (!INITIALIZED) {
- init();
- }
this.name = name;
String levelString = recursivelyComputeLevelString();
@@ -645,4 +646,15 @@
public void error(String msg, Throwable t) {
log(LOG_LEVEL_ERROR, msg, t);
}
+
+ public void log(LoggingEvent event) {
+ int levelInt = event.getLevel().toInt();
+
+ if (!isLevelEnabled(levelInt)) {
+ return;
+ }
+ FormattingTuple tp = MessageFormatter.arrayFormat(event.getMessage(), event.getArgumentArray(), event.getThrowable());
+ log(levelInt, tp.getMessage(), event.getThrowable());
+ }
+
}
diff --git a/slf4j-simple/src/main/java/org/slf4j/impl/SimpleLoggerFactory.java b/slf4j-simple/src/main/java/org/slf4j/impl/SimpleLoggerFactory.java
index 1ceb815..66f8910 100644
--- a/slf4j-simple/src/main/java/org/slf4j/impl/SimpleLoggerFactory.java
+++ b/slf4j-simple/src/main/java/org/slf4j/impl/SimpleLoggerFactory.java
@@ -42,6 +42,7 @@
public SimpleLoggerFactory() {
loggerMap = new ConcurrentHashMap();
+ SimpleLogger.init();
}
/**
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 1172cd3..cef7875 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,7 @@
private StaticMarkerBinder() {
}
-
+
/**
* Return the singleton of this class.
*
@@ -58,7 +58,7 @@
public static StaticMarkerBinder getSingleton() {
return SINGLETON;
}
-
+
/**
* Currently this method always returns an instance of
* {@link BasicMarkerFactory}.
diff --git a/slf4j-simple/src/main/resources/META-INF/MANIFEST.MF b/slf4j-simple/src/main/resources/META-INF/MANIFEST.MF
index ded9247..081988f 100644
--- a/slf4j-simple/src/main/resources/META-INF/MANIFEST.MF
+++ b/slf4j-simple/src/main/resources/META-INF/MANIFEST.MF
@@ -6,5 +6,8 @@
Require-Bundle: slf4j.api
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Export-Package: org.slf4j.impl;version=${parsedVersion.osgiVersion}
-Import-Package: org.slf4j;version=${parsedVersion.osgiVersion}, org.slf4j.spi;version=${parsedVersion.osgiVersion}, org.slf4j.helpers;version=${parsedVersion.osgiVersion}
+Import-Package: org.slf4j;version=${parsedVersion.osgiVersion},
+ org.slf4j.spi;version=${parsedVersion.osgiVersion},
+ org.slf4j.helpers;version=${parsedVersion.osgiVersion},
+ org.slf4j.event;version=${parsedVersion.osgiVersion}
Fragment-Host: slf4j.apidiff --git a/slf4j-simple/src/test/java/org/slf4j/LoggerFactoryFriend.java b/slf4j-simple/src/test/java/org/slf4j/LoggerFactoryFriend.java
new file mode 100644
index 0000000..edf5fcf
--- /dev/null
+++ b/slf4j-simple/src/test/java/org/slf4j/LoggerFactoryFriend.java
@@ -0,0 +1,7 @@
+package org.slf4j;
+
+public class LoggerFactoryFriend {
+ static public void reset() {
+ LoggerFactory.reset();
+ }
+}
diff --git a/slf4j-simple/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java b/slf4j-simple/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java
new file mode 100644
index 0000000..54719c5
--- /dev/null
+++ b/slf4j-simple/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java
@@ -0,0 +1,154 @@
+/**
+ * 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-site/pom.xml b/slf4j-site/pom.xml
index 8813e9b..fd57623 100644
--- a/slf4j-site/pom.xml
+++ b/slf4j-site/pom.xml
@@ -7,7 +7,7 @@
org.slf4j
slf4j-parent
- 1.7.14
+ 1.7.19
slf4j-site