aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-02-28 21:12:22 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-02-28 21:12:22 +0000
commitc99ca7ed9f1365ad353407c6143d440011ded219 (patch)
tree35b7bcaf475fd486f7d1162c23f37171949bb903
parentd68769710ce2c372f8cb04dd43508a664cf27f1d (diff)
parent8079f0abd9d8411dbe2dc08f0cb791644ba0e898 (diff)
downloadslf4j-simpleperf-release.tar.gz
Snap for 11510257 from 8079f0abd9d8411dbe2dc08f0cb791644ba0e898 to simpleperf-releasesimpleperf-release
Change-Id: I0eaad56e42dbb29f00e34ba3cf0637dde5866c5b
-rw-r--r--.github/FUNDING.yml2
-rw-r--r--.github/workflows/main.yml47
-rw-r--r--.github/workflows/toolchains.xml12
-rwxr-xr-x.idea/codeStyleSettings.xml4
-rwxr-xr-x.travis.yml19
-rw-r--r--Android.bp18
-rw-r--r--FUNDING.yml1
-rw-r--r--LICENSE.txt2
-rw-r--r--METADATA12
-rw-r--r--README.md72
-rw-r--r--SECURITY.md69
-rw-r--r--binderVersion.pl42
-rw-r--r--goVersion.sh7
-rwxr-xr-x[-rw-r--r--]integration/build.xml114
-rw-r--r--integration/lib/slf4j-simple-1.5.4-SNAPSHOT.jarbin7472 -> 0 bytes
-rwxr-xr-x[-rw-r--r--]integration/osgi-build.xml36
-rwxr-xr-xintegration/pom.xml54
-rw-r--r--integration/src/IBUNDLE-META-INF/MANIFEST.MF2
-rw-r--r--integration/src/policy/java-eclipse.policy10
-rw-r--r--integration/src/policy/java-under-ant.policy13
-rw-r--r--integration/src/test/java/org/slf4j/CompatibilityAssertionTest.java23
-rw-r--r--integration/src/test/java/org/slf4j/IncompatibleMultiBindingAssertionTest.java24
-rw-r--r--integration/src/test/java/org/slf4j/MissingSingletonMethodAssertionTest.java83
-rw-r--r--integration/src/test/java/org/slf4j/MultiBindingAssertionTest.java30
-rw-r--r--integration/src/test/java/org/slf4j/NoProviderAssertionTest.java (renamed from slf4j-ext/src/test/java/org/slf4j/dummyExt/MDCStrLookupTest.java)41
-rw-r--r--integration/src/test/java/org/slf4j/OldAPIVersionMismatchAssertionTest.java (renamed from integration/src/test/java/org/slf4j/VersionMismatchAssertionTest.java)23
-rwxr-xr-xintegration/src/test/java/org/slf4j/OutputVerifier.java54
-rw-r--r--integration/src/test/java/org/slf4j/StringPrintStream.java2
-rw-r--r--integration/src/test/java/org/slf4j/issues/Issue324Test.java16
-rw-r--r--integration/src/test/java/org/slf4j/test_osgi/CheckingBundleListener.java10
-rw-r--r--integration/src/test/java/org/slf4j/test_osgi/FelixHost.java10
-rw-r--r--integration/src/test/java/org/slf4j/test_osgi/FrameworkErrorListener.java8
-rwxr-xr-xjcl-over-slf4j/pom.xml53
-rw-r--r--jcl-over-slf4j/src/main/java/org/apache/commons/logging/Log.java64
-rw-r--r--jcl-over-slf4j/src/main/java/org/apache/commons/logging/LogConfigurationException.java2
-rw-r--r--jcl-over-slf4j/src/main/java/org/apache/commons/logging/LogFactory.java46
-rw-r--r--jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/NoOpLog.java2
-rw-r--r--jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4JLocationAwareLog.java52
-rw-r--r--jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4JLog.java4
-rw-r--r--jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4JLogFactory.java22
-rw-r--r--jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/SimpleLog.java85
-rwxr-xr-xjcl-over-slf4j/src/main/java/org/apache/commons/logging/package.html2
-rwxr-xr-xjcl-over-slf4j/src/main/java9/module-info.java4
-rw-r--r--jcl-over-slf4j/src/main/resources/META-INF/MANIFEST.MF9
-rw-r--r--jcl-over-slf4j/src/test/java/org/apache/commons/logging/test/InvokeJCLTest.java (renamed from jcl-over-slf4j/src/test/java/org/apache/commons/logging/InvokeJCLTest.java)69
-rw-r--r--jcl-over-slf4j/src/test/java/org/apache/commons/logging/test/SerializationTest.java (renamed from jcl-over-slf4j/src/test/java/org/apache/commons/logging/impl/SerializationTest.java)28
-rw-r--r--jul-to-slf4j/LICENSE.txt (renamed from slf4j-android/LICENSE.txt)2
-rwxr-xr-xjul-to-slf4j/pom.xml38
-rwxr-xr-xjul-to-slf4j/src/main/java/org/slf4j/bridge/SLF4JBridgeHandler.java76
-rw-r--r--jul-to-slf4j/src/main/java/org/slf4j/bridge/package.html2
-rw-r--r--jul-to-slf4j/src/main/java9/module-info.java7
-rw-r--r--jul-to-slf4j/src/main/resources/META-INF/MANIFEST.MF7
-rw-r--r--jul-to-slf4j/src/test/java/org/slf4j/bridge/ListAppender.java2
-rw-r--r--jul-to-slf4j/src/test/java/org/slf4j/bridge/SLF4JBridgeHandlerPerfTest.java28
-rwxr-xr-xjul-to-slf4j/src/test/java/org/slf4j/bridge/SLF4JBridgeHandlerTest.java85
-rw-r--r--log4j-over-slf4j/LICENSE.txt176
-rw-r--r--log4j-over-slf4j/compatibility/build.xml2
-rw-r--r--log4j-over-slf4j/compatibility/readme.txt4
-rwxr-xr-xlog4j-over-slf4j/pom.xml44
-rw-r--r--log4j-over-slf4j/src/main/java/org/apache/log4j/Appender.java9
-rw-r--r--log4j-over-slf4j/src/main/java/org/apache/log4j/Category.java86
-rw-r--r--log4j-over-slf4j/src/main/java/org/apache/log4j/ConsoleAppender.java12
-rw-r--r--log4j-over-slf4j/src/main/java/org/apache/log4j/Layout.java2
-rw-r--r--log4j-over-slf4j/src/main/java/org/apache/log4j/Level.java122
-rw-r--r--log4j-over-slf4j/src/main/java/org/apache/log4j/Log4jLoggerFactory.java20
-rw-r--r--log4j-over-slf4j/src/main/java/org/apache/log4j/LogManager.java9
-rw-r--r--log4j-over-slf4j/src/main/java/org/apache/log4j/Logger.java14
-rw-r--r--log4j-over-slf4j/src/main/java/org/apache/log4j/MDC.java2
-rw-r--r--log4j-over-slf4j/src/main/java/org/apache/log4j/PatternLayout.java2
-rw-r--r--log4j-over-slf4j/src/main/java/org/apache/log4j/Priority.java65
-rw-r--r--log4j-over-slf4j/src/main/java/org/apache/log4j/PropertyConfigurator.java2
-rw-r--r--log4j-over-slf4j/src/main/java/org/apache/log4j/RollingFileAppender.java2
-rw-r--r--log4j-over-slf4j/src/main/java/org/apache/log4j/helpers/LogLog.java18
-rw-r--r--log4j-over-slf4j/src/main/java/org/apache/log4j/spi/Configurator.java5
-rw-r--r--log4j-over-slf4j/src/main/java/org/apache/log4j/spi/HierarchyEventListener.java2
-rw-r--r--log4j-over-slf4j/src/main/java/org/apache/log4j/spi/Layout.java20
-rw-r--r--log4j-over-slf4j/src/main/java/org/apache/log4j/spi/LoggerFactory.java2
-rw-r--r--log4j-over-slf4j/src/main/java/org/apache/log4j/spi/LoggerRepository.java4
-rwxr-xr-xlog4j-over-slf4j/src/main/java9/module-info.java8
-rw-r--r--log4j-over-slf4j/src/main/resources/META-INF/MANIFEST.MF8
-rw-r--r--log4j-over-slf4j/src/test/java/org/apache/log4j/test/NDCTest.java (renamed from log4j-over-slf4j/src/test/java/org/apache/log4j/NDCTest.java)19
-rw-r--r--log4j-over-slf4j/src/test/java/org/apache/log4j/test/Trivial.java (renamed from log4j-over-slf4j/src/test/java/org/apache/log4j/Trivial.java)2
-rw-r--r--log4j-over-slf4j/src/test/java/org/dummy/Bug131.java8
-rw-r--r--log4j-over-slf4j/src/test/java/org/dummy/Bug139.java8
-rw-r--r--log4j-over-slf4j/src/test/java/org/dummy/ListHandler.java2
-rw-r--r--osgi-over-slf4j/LICENSE.txt (renamed from slf4j-jcl/LICENSE.txt)2
-rwxr-xr-xosgi-over-slf4j/pom.xml17
-rw-r--r--parent/pom.xml397
-rwxr-xr-xpom.xml439
-rwxr-xr-xrelease.sh61
-rwxr-xr-xslf4j-android/.gitignore2
-rwxr-xr-xslf4j-android/AndroidManifest.xml7
-rw-r--r--slf4j-android/pom.xml63
-rwxr-xr-xslf4j-android/project.properties14
-rwxr-xr-xslf4j-android/src/main/java/org/slf4j/impl/AndroidLoggerAdapter.java553
-rwxr-xr-xslf4j-android/src/main/java/org/slf4j/impl/AndroidLoggerFactory.java124
-rw-r--r--slf4j-android/src/main/java/org/slf4j/impl/StaticLoggerBinder.java81
-rw-r--r--slf4j-android/src/main/java/org/slf4j/impl/StaticMDCBinder.java58
-rw-r--r--slf4j-android/src/main/java/org/slf4j/impl/StaticMarkerBinder.java67
-rw-r--r--slf4j-android/src/main/resources/META-INF/MANIFEST.MF9
-rw-r--r--slf4j-android/src/test/java/org/slf4j/impl/AndroidLoggerFactoryTest.java79
-rw-r--r--slf4j-api/Android.bp25
-rw-r--r--slf4j-api/LICENSE.txt2
-rwxr-xr-xslf4j-api/pom.xml55
-rw-r--r--slf4j-api/src/main/java/org/slf4j/ILoggerFactory.java2
-rw-r--r--slf4j-api/src/main/java/org/slf4j/Logger.java236
-rwxr-xr-xslf4j-api/src/main/java/org/slf4j/LoggerFactory.java467
-rwxr-xr-x[-rw-r--r--]slf4j-api/src/main/java/org/slf4j/LoggerFactoryFriend.java (renamed from slf4j-jcl/src/main/java/org/slf4j/impl/StaticMDCBinder.java)41
-rw-r--r--slf4j-api/src/main/java/org/slf4j/MDC.java94
-rw-r--r--slf4j-api/src/main/java/org/slf4j/Marker.java25
-rw-r--r--slf4j-api/src/main/java/org/slf4j/MarkerFactory.java27
-rwxr-xr-xslf4j-api/src/main/java/org/slf4j/event/DefaultLoggingEvent.java140
-rwxr-xr-xslf4j-api/src/main/java/org/slf4j/event/EventConstants.java13
-rwxr-xr-xslf4j-api/src/main/java/org/slf4j/event/EventRecordingLogger.java84
-rwxr-xr-xslf4j-api/src/main/java/org/slf4j/event/KeyValuePair.java32
-rwxr-xr-xslf4j-api/src/main/java/org/slf4j/event/Level.java56
-rwxr-xr-xslf4j-api/src/main/java/org/slf4j/event/LoggingEvent.java45
-rwxr-xr-xslf4j-api/src/main/java/org/slf4j/event/SubstituteLoggingEvent.java115
-rw-r--r--slf4j-api/src/main/java/org/slf4j/helpers/AbstractLogger.java423
-rw-r--r--slf4j-api/src/main/java/org/slf4j/helpers/BasicMDCAdapter.java95
-rwxr-xr-xslf4j-api/src/main/java/org/slf4j/helpers/BasicMarker.java61
-rw-r--r--slf4j-api/src/main/java/org/slf4j/helpers/BasicMarkerFactory.java2
-rw-r--r--slf4j-api/src/main/java/org/slf4j/helpers/CheckReturnValue.java30
-rw-r--r--slf4j-api/src/main/java/org/slf4j/helpers/FormattingTuple.java22
-rw-r--r--slf4j-api/src/main/java/org/slf4j/helpers/LegacyAbstractLogger.java39
-rw-r--r--slf4j-api/src/main/java/org/slf4j/helpers/MarkerIgnoringBase.java1
-rwxr-xr-xslf4j-api/src/main/java/org/slf4j/helpers/MessageFormatter.java134
-rw-r--r--slf4j-api/src/main/java/org/slf4j/helpers/NOPLogger.java225
-rw-r--r--slf4j-api/src/main/java/org/slf4j/helpers/NOPLoggerFactory.java3
-rw-r--r--slf4j-api/src/main/java/org/slf4j/helpers/NOPMDCAdapter.java18
-rwxr-xr-xslf4j-api/src/main/java/org/slf4j/helpers/NOP_FallbackServiceProvider.java47
-rw-r--r--slf4j-api/src/main/java/org/slf4j/helpers/NamedLoggerBase.java5
-rw-r--r--slf4j-api/src/main/java/org/slf4j/helpers/NormalizedParameters.java116
-rw-r--r--slf4j-api/src/main/java/org/slf4j/helpers/Reporter.java181
-rw-r--r--slf4j-api/src/main/java/org/slf4j/helpers/SubstituteLogger.java291
-rwxr-xr-xslf4j-api/src/main/java/org/slf4j/helpers/SubstituteLoggerFactory.java37
-rwxr-xr-xslf4j-api/src/main/java/org/slf4j/helpers/SubstituteServiceProvider.java41
-rw-r--r--slf4j-api/src/main/java/org/slf4j/helpers/ThreadLocalMapOfStacks.java89
-rwxr-xr-xslf4j-api/src/main/java/org/slf4j/helpers/Util.java64
-rw-r--r--slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java73
-rw-r--r--slf4j-api/src/main/java/org/slf4j/impl/StaticMDCBinder.java57
-rw-r--r--slf4j-api/src/main/java/org/slf4j/impl/StaticMarkerBinder.java70
-rw-r--r--slf4j-api/src/main/java/org/slf4j/impl/package.html17
-rw-r--r--slf4j-api/src/main/java/org/slf4j/package.html2
-rw-r--r--slf4j-api/src/main/java/org/slf4j/spi/CallerBoundaryAware.java25
-rwxr-xr-xslf4j-api/src/main/java/org/slf4j/spi/DefaultLoggingEventBuilder.java246
-rw-r--r--slf4j-api/src/main/java/org/slf4j/spi/LocationAwareLogger.java7
-rw-r--r--slf4j-api/src/main/java/org/slf4j/spi/LoggerFactoryBinder.java5
-rw-r--r--slf4j-api/src/main/java/org/slf4j/spi/LoggingEventAware.java23
-rwxr-xr-xslf4j-api/src/main/java/org/slf4j/spi/LoggingEventBuilder.java169
-rw-r--r--slf4j-api/src/main/java/org/slf4j/spi/MDCAdapter.java46
-rw-r--r--slf4j-api/src/main/java/org/slf4j/spi/MarkerFactoryBinder.java5
-rwxr-xr-xslf4j-api/src/main/java/org/slf4j/spi/NOPLoggingEventBuilder.java100
-rwxr-xr-xslf4j-api/src/main/java/org/slf4j/spi/SLF4JServiceProvider.java60
-rwxr-xr-xslf4j-api/src/main/java9/module-info.java8
-rw-r--r--slf4j-api/src/main/resources/META-INF/MANIFEST.MF8
-rwxr-xr-xslf4j-api/src/test/java/org/slf4j/LoggerAccessingThread.java62
-rw-r--r--slf4j-api/src/test/java/org/slf4j/LoggerFactoryTest.java91
-rw-r--r--slf4j-api/src/test/java/org/slf4j/basicTests/BasicMarkerTest.java (renamed from slf4j-api/src/test/java/org/slf4j/BasicMarkerTest.java)22
-rw-r--r--slf4j-api/src/test/java/org/slf4j/basicTests/Differentiator.java (renamed from slf4j-api/src/test/java/org/slf4j/Differentiator.java)2
-rwxr-xr-xslf4j-api/src/test/java/org/slf4j/basicTests/DoubleCheckedInt.java141
-rwxr-xr-xslf4j-api/src/test/java/org/slf4j/basicTests/FluentAPIUsage.java27
-rw-r--r--slf4j-api/src/test/java/org/slf4j/basicTests/NoBindingMultithreadedInitializationTest.java (renamed from slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMDCBinder.java)43
-rw-r--r--slf4j-api/src/test/java/org/slf4j/basicTests/NoBindingTest.java (renamed from slf4j-api/src/test/java/org/slf4j/NoBindingTest.java)18
-rw-r--r--slf4j-api/src/test/java/org/slf4j/eventTest/EventRecordingLoggerTest.java531
-rwxr-xr-xslf4j-api/src/test/java/org/slf4j/helpers/BasicMDCAdapterTest.java17
-rw-r--r--slf4j-api/src/test/java/org/slf4j/helpers/BogoPerf.java150
-rw-r--r--slf4j-api/src/test/java/org/slf4j/helpers/BubbleSortTest.java100
-rw-r--r--slf4j-api/src/test/java/org/slf4j/helpers/MDCAdapterTestBase.java147
-rwxr-xr-xslf4j-api/src/test/java/org/slf4j/helpers/MessageFormatterPerfTest.java111
-rwxr-xr-xslf4j-api/src/test/java/org/slf4j/helpers/MessageFormatterTest.java37
-rw-r--r--slf4j-api/src/test/java/org/slf4j/helpers/MyRandom.java51
-rwxr-xr-xslf4j-api/src/test/java/org/slf4j/helpers/StringPrintStream.java74
-rw-r--r--slf4j-api/src/test/java/org/slf4j/helpers/SubstitutableLoggerTest.java81
-rwxr-xr-xslf4j-api/src/test/java/org/slf4j/helpers/SubstituteLoggerFactoryTest.java21
-rwxr-xr-xslf4j-api/src/test/java/org/slf4j/rule/BlaTest.java38
-rwxr-xr-x[-rw-r--r--]slf4j-api/src/test/java/org/slf4j/rule/RunInNewThread.java (renamed from slf4j-api/src/test/java/org/slf4j/helpers/BubbleSort.java)36
-rwxr-xr-x[-rw-r--r--]slf4j-api/src/test/java/org/slf4j/rule/RunInNewThreadRule.java (renamed from slf4j-ext/src/main/java/org/slf4j/ext/MDCStrLookup.java)47
-rwxr-xr-xslf4j-api/src/test/java/org/slf4j/rule/RunInNewThreadStatement.java68
-rw-r--r--slf4j-api/src/test/java/org/slf4j/testHarness/MultithreadedInitializationTest.java79
-rw-r--r--slf4j-ext/LICENSE.txt (renamed from slf4j-site/LICENSE.txt)2
-rwxr-xr-xslf4j-ext/pom.xml57
-rw-r--r--slf4j-ext/src/main/java/org/slf4j/NDC.java2
-rw-r--r--slf4j-ext/src/main/java/org/slf4j/agent/AgentOptions.java4
-rw-r--r--slf4j-ext/src/main/java/org/slf4j/agent/AgentPremain.java27
-rw-r--r--slf4j-ext/src/main/java/org/slf4j/agent/package.html5
-rw-r--r--slf4j-ext/src/main/java/org/slf4j/cal10n/LocLogger.java2
-rw-r--r--slf4j-ext/src/main/java/org/slf4j/cal10n/LocLoggerFactory.java22
-rwxr-xr-xslf4j-ext/src/main/java/org/slf4j/ext/EventData.java305
-rw-r--r--slf4j-ext/src/main/java/org/slf4j/ext/EventException.java66
-rw-r--r--slf4j-ext/src/main/java/org/slf4j/ext/LoggerWrapper.java97
-rw-r--r--slf4j-ext/src/main/java/org/slf4j/ext/XLogger.java29
-rw-r--r--slf4j-ext/src/main/java/org/slf4j/instrumentation/JavassistHelper.java10
-rw-r--r--slf4j-ext/src/main/java/org/slf4j/instrumentation/LogTransformer.java49
-rw-r--r--slf4j-ext/src/main/java/org/slf4j/instrumentation/ToStringHelper.java6
-rw-r--r--slf4j-ext/src/main/java/org/slf4j/instrumentation/package.html2
-rw-r--r--slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java6
-rw-r--r--slf4j-ext/src/main/java/org/slf4j/profiler/ProfilerRegistry.java4
-rw-r--r--slf4j-ext/src/main/java/org/slf4j/profiler/StopWatch.java2
-rw-r--r--slf4j-ext/src/main/java/org/slf4j/profiler/TimeInstrument.java4
-rw-r--r--slf4j-ext/src/main/resources/META-INF/MANIFEST.MF8
-rw-r--r--slf4j-ext/src/test/java/org/slf4j/NDCTest.java18
-rw-r--r--slf4j-ext/src/test/java/org/slf4j/cal10n_dummy/LocLoggerTest.java20
-rw-r--r--slf4j-ext/src/test/java/org/slf4j/cal10n_dummy/PackageTest.java14
-rw-r--r--slf4j-ext/src/test/java/org/slf4j/dummyExt/EventLoggerTest.java106
-rw-r--r--slf4j-ext/src/test/java/org/slf4j/dummyExt/ListAppender.java2
-rw-r--r--slf4j-ext/src/test/java/org/slf4j/dummyExt/PackageTest.java16
-rw-r--r--slf4j-ext/src/test/java/org/slf4j/dummyExt/XLoggerTest.java57
-rw-r--r--slf4j-ext/src/test/java/org/slf4j/instrumentation/ToStringHelperTest.java7
-rw-r--r--slf4j-ext/src/test/java/org/slf4j/profiler/PackageTest.java14
-rw-r--r--slf4j-ext/src/test/java/org/slf4j/profiler/ProfilerTest.java14
-rw-r--r--slf4j-ext/src/test/java/org/slf4j/profiler/SortAndPruneComposites.java4
-rw-r--r--slf4j-ext/src/test/java/org/slf4j/profiler/UtilTest.java17
-rwxr-xr-xslf4j-jcl/pom.xml53
-rw-r--r--slf4j-jcl/src/main/java/org/slf4j/impl/JCLLoggerAdapter.java531
-rw-r--r--slf4j-jcl/src/main/java/org/slf4j/impl/JCLLoggerFactory.java83
-rw-r--r--slf4j-jcl/src/main/java/org/slf4j/impl/StaticLoggerBinder.java82
-rw-r--r--slf4j-jcl/src/main/java/org/slf4j/impl/StaticMarkerBinder.java67
-rw-r--r--slf4j-jcl/src/main/resources/META-INF/MANIFEST.MF10
-rw-r--r--slf4j-jcl/src/test/java/org/slf4j/InvocationTest.java125
-rw-r--r--slf4j-jdk-platform-logging/LICENSE.txt24
-rw-r--r--slf4j-jdk-platform-logging/pom.xml85
-rw-r--r--slf4j-jdk-platform-logging/src/main/java/module-info.java28
-rw-r--r--slf4j-jdk-platform-logging/src/main/java/org/slf4j/jdk/platform/logging/SLF4JPlatformLogger.java181
-rw-r--r--[-rwxr-xr-x]slf4j-jdk-platform-logging/src/main/java/org/slf4j/jdk/platform/logging/SLF4JPlatformLoggerFactory.java (renamed from slf4j-ext/src/main/java/org/slf4j/ext/EventLogger.java)53
-rw-r--r--slf4j-jdk-platform-logging/src/main/java/org/slf4j/jdk/platform/logging/SLF4JSystemLoggerFinder.java59
-rw-r--r--slf4j-jdk-platform-logging/src/main/resources/META-INF/services/java.lang.System$LoggerFinder1
-rw-r--r--slf4j-jdk-platform-logging/src/test/java/org/slf4j/jdk/platform/logging/test/SLF4JPlatformLoggingTest.java119
-rw-r--r--slf4j-jdk-platform-logging/src/test/java/org/slf4j/jdk/platform/logging/test/StringPrintStream.java67
-rw-r--r--slf4j-jdk14/LICENSE.txt2
-rwxr-xr-xslf4j-jdk14/pom.xml41
-rwxr-xr-xslf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerAdapter.java651
-rw-r--r--slf4j-jdk14/src/main/java/org/slf4j/impl/StaticLoggerBinder.java80
-rw-r--r--slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMDCBinder.java58
-rw-r--r--slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMarkerBinder.java67
-rwxr-xr-xslf4j-jdk14/src/main/java/org/slf4j/jul/JDK14LoggerAdapter.java298
-rw-r--r--slf4j-jdk14/src/main/java/org/slf4j/jul/JDK14LoggerFactory.java (renamed from slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerFactory.java)15
-rwxr-xr-xslf4j-jdk14/src/main/java/org/slf4j/jul/JULServiceProvider.java48
-rwxr-xr-xslf4j-jdk14/src/main/java9/module-info.java9
-rw-r--r--slf4j-jdk14/src/main/resources/META-INF/MANIFEST.MF9
-rwxr-xr-xslf4j-jdk14/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider1
-rw-r--r--slf4j-jdk14/src/test/java/org/slf4j/impl/PerfTest.java76
-rwxr-xr-xslf4j-jdk14/src/test/java/org/slf4j/issue/CallerInfoTest.java122
-rw-r--r--slf4j-jdk14/src/test/java/org/slf4j/issue/LoggerSerializationTest.java15
-rw-r--r--slf4j-jdk14/src/test/java/org/slf4j/jul/CountingHandler.java24
-rwxr-xr-xslf4j-jdk14/src/test/java/org/slf4j/jul/FluentApiInvocationTest.java144
-rwxr-xr-xslf4j-jdk14/src/test/java/org/slf4j/jul/InvocationTest.java (renamed from slf4j-jdk14/src/test/java/org/slf4j/InvocationTest.java)52
-rw-r--r--slf4j-jdk14/src/test/java/org/slf4j/jul/JDK14AdapterLoggerNameTest.java (renamed from slf4j-jdk14/src/test/java/org/slf4j/impl/JDK14AdapterLoggerNameTest.java)53
-rw-r--r--slf4j-jdk14/src/test/java/org/slf4j/jul/JDK14MultithreadedInitializationTest.java77
-rwxr-xr-xslf4j-jdk14/src/test/java/org/slf4j/jul/ListHandler.java23
-rw-r--r--slf4j-log4j12/LICENSE.txt2
-rwxr-xr-xslf4j-log4j12/pom.xml57
-rwxr-xr-xslf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerAdapter.java598
-rw-r--r--slf4j-log4j12/src/main/java/org/slf4j/impl/StaticLoggerBinder.java88
-rw-r--r--slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMarkerBinder.java67
-rw-r--r--slf4j-log4j12/src/main/resources/META-INF/MANIFEST.MF9
-rw-r--r--slf4j-migrator/LICENSE.txt24
-rwxr-xr-xslf4j-migrator/pom.xml27
-rw-r--r--slf4j-migrator/src/main/java/org/slf4j/migrator/FileSelector.java6
-rw-r--r--slf4j-migrator/src/main/java/org/slf4j/migrator/InplaceFileConverter.java4
-rw-r--r--slf4j-migrator/src/main/java/org/slf4j/migrator/Main.java10
-rw-r--r--slf4j-migrator/src/main/java/org/slf4j/migrator/ProjectConverter.java27
-rw-r--r--slf4j-migrator/src/main/java/org/slf4j/migrator/helper/Abbreviator.java4
-rw-r--r--slf4j-migrator/src/main/java/org/slf4j/migrator/internal/MigratorFrame.java28
-rw-r--r--slf4j-migrator/src/main/java/org/slf4j/migrator/line/EmptyRuleSet.java2
-rw-r--r--slf4j-migrator/src/main/java/org/slf4j/migrator/line/JCLRuleSet.java4
-rw-r--r--slf4j-migrator/src/main/java/org/slf4j/migrator/line/JULRuleSet.java4
-rwxr-xr-xslf4j-migrator/src/main/java/org/slf4j/migrator/line/Log4jRuleSet.java4
-rw-r--r--slf4j-migrator/src/main/java/org/slf4j/migrator/line/MultiGroupConversionRule.java4
-rw-r--r--slf4j-migrator/src/main/resources/META-INF/MANIFEST.MF1
-rw-r--r--slf4j-migrator/src/test/java/org/slf4j/migrator/AternativeApproach.java8
-rw-r--r--slf4j-migrator/src/test/java/org/slf4j/migrator/FileConverterTest.java24
-rw-r--r--slf4j-migrator/src/test/java/org/slf4j/migrator/ProjectConverterTest.java10
-rw-r--r--slf4j-migrator/src/test/java/org/slf4j/migrator/helper/AbbreviatorTest.java24
-rw-r--r--slf4j-migrator/src/test/java/org/slf4j/migrator/helper/RandomHelper.java2
-rw-r--r--slf4j-migrator/src/test/java/org/slf4j/migrator/line/JCLRuleSetTest.java12
-rw-r--r--slf4j-migrator/src/test/java/org/slf4j/migrator/line/NoConversionTest.java10
-rw-r--r--slf4j-migrator/src/test/java/org/slf4j/migrator/line/TrivialMatcher.java12
-rw-r--r--slf4j-migrator/src/test/java/org/slf4j/migrator/line/TrivialMatcherTest.java7
-rw-r--r--slf4j-nop/LICENSE.txt2
-rwxr-xr-xslf4j-nop/pom.xml42
-rw-r--r--slf4j-nop/src/main/java/org/slf4j/impl/StaticLoggerBinder.java80
-rw-r--r--slf4j-nop/src/main/java/org/slf4j/impl/StaticMDCBinder.java56
-rw-r--r--slf4j-nop/src/main/java/org/slf4j/impl/StaticMarkerBinder.java67
-rwxr-xr-xslf4j-nop/src/main/java/org/slf4j/nop/NOPServiceProvider.java46
-rwxr-xr-xslf4j-nop/src/main/java9/module-info.java7
-rw-r--r--slf4j-nop/src/main/resources/META-INF/MANIFEST.MF9
-rwxr-xr-xslf4j-nop/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider1
-rw-r--r--slf4j-nop/src/test/java/org/slf4j/nop/InvocationTest.java (renamed from slf4j-nop/src/test/java/org/slf4j/InvocationTest.java)41
-rwxr-xr-xslf4j-nop/src/test/java/org/slf4j/nop/MultithreadedInitializationTest.java150
-rw-r--r--slf4j-reload4j/LICENSE.txt24
-rw-r--r--slf4j-reload4j/pom.xml71
-rw-r--r--slf4j-reload4j/src/main/java/org/slf4j/reload4j/Reload4jLoggerAdapter.java213
-rw-r--r--slf4j-reload4j/src/main/java/org/slf4j/reload4j/Reload4jLoggerFactory.java (renamed from slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerFactory.java)33
-rw-r--r--slf4j-reload4j/src/main/java/org/slf4j/reload4j/Reload4jMDCAdapter.java (renamed from slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jMDCAdapter.java)57
-rw-r--r--slf4j-reload4j/src/main/java/org/slf4j/reload4j/Reload4jServiceProvider.java62
-rw-r--r--slf4j-reload4j/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider1
-rw-r--r--slf4j-reload4j/src/test/java/org/slf4j/reload4j/EventFieldsTest.java61
-rw-r--r--slf4j-reload4j/src/test/java/org/slf4j/reload4j/InvocationTest.java (renamed from slf4j-log4j12/src/test/java/org/slf4j/InvocationTest.java)74
-rw-r--r--slf4j-reload4j/src/test/java/org/slf4j/reload4j/ListAppender.java (renamed from slf4j-log4j12/src/test/java/org/slf4j/ListAppender.java)4
-rw-r--r--slf4j-reload4j/src/test/java/org/slf4j/reload4j/RecursiveInitializationTest.java (renamed from slf4j-log4j12/src/test/java/org/slf4j/impl/RecursiveInitializationTest.java)25
-rw-r--r--slf4j-reload4j/src/test/java/org/slf4j/reload4j/Reload4jMDCAdapterTest.java39
-rw-r--r--slf4j-reload4j/src/test/java/org/slf4j/reload4j/Reload4jMultithreadedInitializationTest.java72
-rw-r--r--slf4j-reload4j/src/test/java/org/slf4j/reload4j/testHarness/RecursiveAppender.java (renamed from slf4j-log4j12/src/test/java/org/slf4j/impl/RecursiveAppender.java)44
-rw-r--r--slf4j-reload4j/src/test/resources/eventFields.properties4
-rw-r--r--slf4j-reload4j/src/test/resources/recursiveInit.properties (renamed from slf4j-log4j12/src/test/resources/recursiveInit.properties)5
-rw-r--r--slf4j-reload4j/src/test/resources/recursiveInitWithActivationDelay.properties9
-rw-r--r--slf4j-simple/LICENSE.txt2
-rwxr-xr-xslf4j-simple/pom.xml46
-rw-r--r--slf4j-simple/src/main/java/org/slf4j/impl/SimpleLogger.java648
-rw-r--r--slf4j-simple/src/main/java/org/slf4j/impl/StaticLoggerBinder.java81
-rw-r--r--slf4j-simple/src/main/java/org/slf4j/impl/StaticMDCBinder.java56
-rw-r--r--slf4j-simple/src/main/java/org/slf4j/impl/StaticMarkerBinder.java68
-rwxr-xr-xslf4j-simple/src/main/java/org/slf4j/simple/OutputChoice.java55
-rw-r--r--slf4j-simple/src/main/java/org/slf4j/simple/SimpleLogger.java475
-rwxr-xr-xslf4j-simple/src/main/java/org/slf4j/simple/SimpleLoggerConfiguration.java193
-rw-r--r--slf4j-simple/src/main/java/org/slf4j/simple/SimpleLoggerFactory.java (renamed from slf4j-simple/src/main/java/org/slf4j/impl/SimpleLoggerFactory.java)32
-rwxr-xr-xslf4j-simple/src/main/java/org/slf4j/simple/SimpleServiceProvider.java50
-rwxr-xr-xslf4j-simple/src/main/java9/module-info.java6
-rw-r--r--slf4j-simple/src/main/resources/META-INF/MANIFEST.MF10
-rwxr-xr-xslf4j-simple/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider1
-rw-r--r--slf4j-simple/src/test/java/org/slf4j/impl/SimpleLoggerTest.java78
-rw-r--r--slf4j-simple/src/test/java/org/slf4j/simple/AcceptanceTest.java50
-rwxr-xr-xslf4j-simple/src/test/java/org/slf4j/simple/DetectLoggerNameMismatchTest.java (renamed from slf4j-simple/src/test/java/org/slf4j/DetectLoggerNameMismatchTest.java)18
-rw-r--r--slf4j-simple/src/test/java/org/slf4j/simple/DoubleInitializationPitfallTest.java37
-rw-r--r--slf4j-simple/src/test/java/org/slf4j/simple/InvocationTest.java (renamed from slf4j-simple/src/test/java/org/slf4j/InvocationTest.java)46
-rw-r--r--slf4j-simple/src/test/java/org/slf4j/simple/LoggerTestSuite.java274
-rw-r--r--slf4j-simple/src/test/java/org/slf4j/simple/SilentPrintStream.java (renamed from slf4j-simple/src/test/java/org/slf4j/SilentPrintStream.java)2
-rw-r--r--slf4j-simple/src/test/java/org/slf4j/simple/SimpleLoggerMultithreadedInitializationTest.java73
-rw-r--r--slf4j-simple/src/test/java/org/slf4j/simple/SimpleLoggerTest.java152
-rwxr-xr-xslf4j-simple/src/test/java/org/slf4j/simple/multiThreadedExecution/MultithereadedExecutionTest.java131
-rwxr-xr-xslf4j-simple/src/test/java/org/slf4j/simple/multiThreadedExecution/StateCheckingPrintStream.java140
-rwxr-xr-xslf4j-site/pom.xml43
-rw-r--r--slf4j-site/src/site/images.src/bindings.flwbin7661 -> 0 bytes
-rwxr-xr-xslf4j-site/src/site/images.src/bridging-black.flwbin5751 -> 0 bytes
-rw-r--r--slf4j-site/src/site/images.src/bridging.flwbin5579 -> 0 bytes
-rw-r--r--slf4j-site/src/site/images.src/concrete-bindings.odgbin19544 -> 0 bytes
-rw-r--r--slf4j-site/src/site/images.src/core-bindings.flwbin4568 -> 0 bytes
-rw-r--r--slf4j-site/src/site/images.src/core-bindings1.flwbin4479 -> 0 bytes
-rw-r--r--slf4j-site/src/site/images.src/core-bindings2.flwbin4458 -> 0 bytes
-rw-r--r--slf4j-site/src/site/images.src/core-bindings3.flwbin4554 -> 0 bytes
-rw-r--r--slf4j-site/src/site/images.src/follow_us.odgbin8824 -> 0 bytes
-rw-r--r--slf4j-site/src/site/images.src/legacy.odgbin26372 -> 0 bytes
-rw-r--r--slf4j-site/src/site/pages/.htaccess1
-rwxr-xr-xslf4j-site/src/site/pages/bug-reporting.html90
-rw-r--r--slf4j-site/src/site/pages/changes/changes-1.3.txt45
-rwxr-xr-xslf4j-site/src/site/pages/codes.html483
-rwxr-xr-xslf4j-site/src/site/pages/compatibility.html269
-rw-r--r--slf4j-site/src/site/pages/css/popup.css67
-rw-r--r--slf4j-site/src/site/pages/css/prettify.css29
-rwxr-xr-xslf4j-site/src/site/pages/css/site.css449
-rw-r--r--slf4j-site/src/site/pages/docs.html153
-rw-r--r--slf4j-site/src/site/pages/download.html123
-rwxr-xr-xslf4j-site/src/site/pages/extensions.html886
-rwxr-xr-xslf4j-site/src/site/pages/faq.html1615
-rw-r--r--slf4j-site/src/site/pages/inde_base.html28
-rwxr-xr-xslf4j-site/src/site/pages/index.html170
-rw-r--r--slf4j-site/src/site/pages/js/decorator.js101
-rw-r--r--slf4j-site/src/site/pages/js/jquery-min.js4
-rw-r--r--slf4j-site/src/site/pages/js/prettify.js23
-rwxr-xr-xslf4j-site/src/site/pages/legacy.html267
-rw-r--r--slf4j-site/src/site/pages/license.html68
-rwxr-xr-xslf4j-site/src/site/pages/localization.html158
-rwxr-xr-xslf4j-site/src/site/pages/mailing-lists.html128
-rwxr-xr-xslf4j-site/src/site/pages/manual.html539
-rwxr-xr-xslf4j-site/src/site/pages/migrator.html226
-rwxr-xr-xslf4j-site/src/site/pages/news.html1638
-rw-r--r--slf4j-site/src/site/pages/support.html43
-rwxr-xr-xslf4j-site/src/site/pages/templates/footer.js28
-rw-r--r--slf4j-site/src/site/pages/templates/header.js12
-rwxr-xr-xslf4j-site/src/site/pages/templates/left.js59
-rw-r--r--slf4j-site/src/site/pages/templates/right.js1
-rw-r--r--slf4j-site/src/site/resources/css/anchor12.pngbin624 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/css/anchor16.pngbin945 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/css/anchor20.pngbin1269 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/css/anchor24.pngbin1685 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/PythonPowered.pngbin945 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/beginnerSLF4J.pngbin106458 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/bindings.pngbin51523 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/bridging.pngbin35850 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/buyDirect.jpgbin24142 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/concrete-bindings.pngbin82592 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/devoxx09.jpegbin12634 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/follow_us.pngbin16337 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/gnu-head-tiny.jpgbin3049 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/jazoon09.gifbin1338 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/legacy.pngbin180307 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/logos/qosLogo.pngbin3370 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/logos/qoslogo.gifbin2743 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/logos/slf4j-logo.jpgbin32793 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/logos/slf4j-small.jpgbin17838 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/logos/valid-html401.pngbin2404 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/mailman.jpgbin2022 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/myjob.pngbin2468 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/slf4j-migrator.gifbin15512 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/twitter-bird-light-bgs.pngbin4392 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/images/twitter.pngbin1847 -> 0 bytes
-rw-r--r--slf4j-site/src/site/resources/slf4j-in-10-slides.pptbin240128 -> 0 bytes
-rwxr-xr-xsrc/main/assembly/source.xml342
-rw-r--r--test0
-rw-r--r--version.pl44
401 files changed, 11507 insertions, 16657 deletions
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000..b87dccda
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,2 @@
+tidelift: maven/org.slf4j:slf4j-api
+github: qos-ch \ No newline at end of file
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 00000000..faa5af5b
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,47 @@
+name: CI
+
+on:
+ push:
+ branches:
+ - '*'
+ pull_request:
+ branches:
+ - '*'
+
+# https://help.github.com/en/actions/automating-your-workflow-with-github-actions/software-installed-on-github-hosted-runners
+
+concurrency:
+ # On master/release, we don't want any jobs cancelled so the sha is used to name the group
+ # On PR branches, we cancel the job if new commits are pushed
+ # More info: https://stackoverflow.com/a/68422069/253468
+ group: ${{ (github.ref == 'refs/heads/branch_1.2.18' || github.ref == 'refs/heads/main' || github.ref == 'refs/heads/release' ) && format('ci-main-{0}', github.sha) || format('ci-main-{0}', github.ref) }}
+ cancel-in-progress: true
+
+permissions:
+ contents: read
+
+jobs:
+ Test:
+ name: JDK ${{ matrix.jdk }}, ${{ matrix.os }}
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ jdk: [11, 17, 19]
+ os: [ubuntu-latest, windows-latest, macos-latest]
+ fail-fast: true
+ max-parallel: 4
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ fetch-depth: 50
+ - name: Set up Java ${{ matrix.jdk }}
+ if: ${{ matrix.jdk != '8' }}
+ uses: actions/setup-java@v3
+ with:
+ distribution: 'temurin'
+ java-version: ${{ matrix.jdk }}
+ - name: Install
+ # download dependencies, etc, so test log looks better
+ run: mvn -B install
+
+
diff --git a/.github/workflows/toolchains.xml b/.github/workflows/toolchains.xml
new file mode 100644
index 00000000..e75a4d31
--- /dev/null
+++ b/.github/workflows/toolchains.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF8"?>
+<toolchains>
+ <toolchain>
+ <type>jdk</type>
+ <provides>
+ <version>1.8</version>
+ </provides>
+ <configuration>
+ <jdkHome>${env.JAVA_HOME_8}</jdkHome>
+ </configuration>
+ </toolchain>
+</toolchains>
diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml
index 31cb3222..3507c0b8 100755
--- a/.idea/codeStyleSettings.xml
+++ b/.idea/codeStyleSettings.xml
@@ -31,8 +31,8 @@
<option name="KEEP_SIMPLE_CLASSES_IN_ONE_LINE" value="true" />
<option name="KEEP_MULTIPLE_EXPRESSIONS_IN_ONE_LINE" value="true" />
<indentOptions>
- <option name="INDENT_SIZE" value="2" />
- <option name="TAB_SIZE" value="2" />
+ <option name="INDENT_SIZE" value="4" />
+ <option name="TAB_SIZE" value="4" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="XML">
diff --git a/.travis.yml b/.travis.yml
index 49af9f15..2f8e805e 100755
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,4 +1,21 @@
+dist: trusty
+
language: java
+
+jdk:
+ - oraclejdk11
+
notifications:
email:
- - slf4j-dev@qos.ch
+ - notification@qos.ch
+
+install: /bin/true
+
+script:
+ - mvn clean
+ - mvn install
+
+cache:
+ directories:
+ - $HOME/.m2
+ \ No newline at end of file
diff --git a/Android.bp b/Android.bp
index db9ce707..2c7e6fc2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -58,7 +58,7 @@ java_library {
host_supported: true,
hostdex: true,
srcs: [
- "slf4j-api/src/main/**/*.java",
+ "slf4j-api/src/main/java/**/*.java",
"slf4j-jdk14/src/main/java/**/*.java",
],
exclude_srcs: [
@@ -78,3 +78,19 @@ java_library {
"//packages/modules/OnDevicePersonalization:__subpackages__",
],
}
+
+java_library_host {
+ name: "slf4j-nop",
+ srcs: [
+ "slf4j-api/src/main/java/**/*.java",
+ "slf4j-nop/src/main/java/**/*.java",
+ ],
+ exclude_srcs: [
+ "slf4j-api/src/main/java/org/slf4j/impl/**/*.java",
+ ],
+ target: {
+ windows: {
+ enabled: true,
+ },
+ },
+}
diff --git a/FUNDING.yml b/FUNDING.yml
new file mode 100644
index 00000000..18dbb116
--- /dev/null
+++ b/FUNDING.yml
@@ -0,0 +1 @@
+github: qos-ch \ No newline at end of file
diff --git a/LICENSE.txt b/LICENSE.txt
index 43112bc7..1a3d0532 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2014 QOS.ch
+Copyright (c) 2004-2022 QOS.ch Sarl (Switzerland)
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/METADATA b/METADATA
index 7ae255df..b509b128 100644
--- a/METADATA
+++ b/METADATA
@@ -1,4 +1,16 @@
+name: "slf4j"
+description:
+ "Simple Logging Facade for Java"
+
third_party {
+ homepage: "https://github.com/qos-ch/slf4j"
+ identifier {
+ type: "Git"
+ value: "https://github.com/qos-ch/slf4j.git"
+ primary_source: true
+ }
+ version: "v_2.0.12"
+ last_upgrade_date { year: 2024 month: 2 day: 16 }
license_note: "would be NOTICE save for:\n"
" log4j-over-slf4j/compatibility/src/main/java/test/Log4j12Calls.java\n"
" log4j-over-slf4j/compatibility/src/main/java/test/Log4j13Calls.java"
diff --git a/README.md b/README.md
index 69663535..6d2e395c 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,70 @@
# About SLF4J
-The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks (e.g. java.util.logging, logback, log4j) allowing the end user to plug in the desired logging framework at deployment time.
+
+The Simple Logging Facade for Java (SLF4J) serves as a simple facade
+or abstraction for various logging frameworks (e.g. java.util.logging,
+logback, reload4j, log4j 2.x) allowing the end user to plug in the desired logging
+framework at deployment time.
+
More information can be found on the [SLF4J website](http://www.slf4j.org).
+
# Build Status
-[![Build Status](https://travis-ci.org/qos-ch/slf4j.png)](https://travis-ci.org/qos-ch/slf4j)
+[![Build Status](https://travis-ci.org/qos-ch/slf4j.svg)](https://travis-ci.org/qos-ch/slf4j)
+
+# Search org.slf4j artifacts on Maven Central
+[![Maven Central](https://img.shields.io/badge/Search%20org%2Eslf4j%20artifacts%20on%20Maven%20Central-2.0.x-green)](https://search.maven.org/search?q=g:org.slf4j%20AND%20v:2.0.%3F)
+
+
+# In case of problems
+
+In case of problems please do not hesitate to post an e-mail message
+on the slf4j-user@qos.ch mailing list. However, please do not
+directly e-mail SLF4J developers. The answer to your question might
+be useful to other users. Moreover, there are many knowledgeable users
+on the slf4j-user mailing lists who can quickly answer your
+questions.
+
+# Urgent issues
+
+For urgent issues do not hesitate to [champion a release](https://github.com/sponsors/qos-ch/sponsorships?tier_id=77436).
+In principle, most championed issues are solved within 3 business days ensued by a release.
+
+# How to build SLF4J
+
+SLF4J uses Maven as its build tool.
+
+SLF4J version 2.0.x will run under Java 8 but requires Java 9 or later to build.
# How to contribute pull requests
-If you are interested in improving SLF4J, great! The SLF4J community looks forward to your contribution. Please follow this process:
-1. Start a discussion on the [slf4j-dev mailing list](http://www.slf4j.org/mailing-lists.html) about your proposed change. Alternately file a [bug report](http://www.slf4j.org/bug-reporting.html).
-2. Fork qos-ch/slf4j. Ideally, create a new branch from your fork for your contribution to make it easier to merge your changes back.
-3. Make your changes on the branch you hopefuly created in Step 2. Be sure that your code passes existing unit tests. Please add unit tests for your work if appropriate. It usually is.
-4. Push your changes to your fork/branch in github. Don't push it to your master! If you do it will make it harder to submit new changes later.
-5. Submit a pull request to SLF4J from from your commit page on github.
+If you are interested in improving SLF4J, that is great! The SLF4J
+community looks forward to your contribution. Please follow this
+process:
+
+1. Start a discussion on the [slf4j-dev mailing
+list](http://www.slf4j.org/mailing-lists.html) about your proposed
+change. Alternately, file a [bug
+report](http://www.slf4j.org/bug-reporting.html) to initiate the
+discussion. Note that we ask pull requests to be linked to a [Jira
+ticket](https://jira.qos.ch/).
+
+2. Fork qos-ch/slf4j. Ideally, create a new branch from your fork for
+your contribution to make it easier to merge your changes back.
+
+3. Make your changes on the branch you hopefully created in Step 2. Be
+sure that your code passes existing unit tests. Please add unit tests
+for your work if appropriate. It usually is.
+
+4. All commits must have signed off by the contributor attesting to
+[Developer Certificate of Origin
+(DCO)](https://developercertificate.org/). Commits without sign off
+will be automatically rejected by the [DCO GitHub
+check](https://probot.github.io/apps/dco/) application.
+
+5. Push your changes to your fork/branch in GitHub. Don't push it to
+your master! If you do it will make it harder to submit new changes
+later.
+
+6. Submit a pull request to SLF4J from your commit page on GitHub.
+
+7. Did we mention that you will be asked to link your pull request
+with a Jira ticket?
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 00000000..9c361c27
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,69 @@
+
+## Reporting security issues
+
+Please report security issues related to the SLF4J project to the
+following email address:
+
+ support(at)qos.ch
+
+
+
+
+## Verifying contents
+
+All SLF4J project artifacts published on Maven central are signed. For
+each artifact, there is an associated signature file with the .asc
+suffix.
+
+### After 2022-08-08
+
+To verify the signature use [this public key](https://www.slf4j.org/public-keys/60200AC4AE761F1614D6C46766D68DAA073BE985.gpg). Here is its fingerprint:
+```
+pub nistp521 2022-08-08 [SC]
+ 60200AC4AE761F1614D6C46766D68DAA073BE985
+uid Ceki Gulcu <ceki@qos.ch>
+sub nistp521 2022-08-08 [E]
+```
+
+A copy of this key is stored on the
+[keys.openpgp.org](https://keys.openpgp.org) keyserver. To add it to
+your public key ring use the following command:
+
+```
+> FINGER_PRINT=60200AC4AE761F1614D6C46766D68DAA073BE985
+> gpg --keyserver hkps://keys.openpgp.org --recv-keys $FINGER_PRINT
+```
+
+### Before 2022-08-08
+
+To verify the signature use [this public key](https://www.slf4j.org/public-keys/ceki-public-key.pgp). Here is its fingerprint:
+
+```
+pub 2048R/A511E325 2012-04-26
+Key fingerprint = 475F 3B8E 59E6 E63A A780 6748 2C7B 12F2 A511 E325
+uid Ceki Gulcu <ceki@qos.ch>
+sub 2048R/7FBFA159 2012-04-26
+```
+
+A copy of this key is stored on the
+[keys.openpgp.org](https://keys.openpgp.org) keyserver. To add it to
+your public key ring use the following command:
+
+```
+> FINGER_PRINT=475F3B8E59E6E63AA78067482C7B12F2A511E325
+> gpg --keyserver hkps://keys.openpgp.org --recv-keys $FINGER_PRINT
+```
+
+
+## Preventing commit history overwrite
+
+In order to prevent loss of commit history, developers of the project
+are highly encouraged to deny branch deletions or history overwrites
+by invoking the following two commands on their local copy of the
+repository.
+
+
+```
+git config receive.denyDelete true
+git config receive.denyNonFastForwards true
+``` \ No newline at end of file
diff --git a/binderVersion.pl b/binderVersion.pl
deleted file mode 100644
index b5b32334..00000000
--- a/binderVersion.pl
+++ /dev/null
@@ -1,42 +0,0 @@
-
-if ($#ARGV < 1) {
- print "Usage: binderVersion.pl VER FILE {FILE, FILE}\n";
- exit;
-}
-
-$V= $ARGV[0];
-# Trim -SNAPSHOT
-$V =~ s/-SNAPSHOT//;
-
-print "VER:${V}\r\n";
-shift(@ARGV);
-
-sub replace () {
- my $filename = $_[0];
-
- if(-s $filename) {
- print "Processing [" . $filename . "]\r\n";
-
- my $original = "$filename.original";
-
- rename($filename, $original);
- open(OUT, ">$filename");
- open(IN, "$original");
-
- while(<IN>) {
- if(/VERSION\s+=\s+".*";/) {
- s/VERSION\s+=\s+".*";/VERSION = "${V}";/;
- }
- print OUT;
- }
- close(IN);
- close(OUT);
- unlink($original);
- } else {
- print "File [" . $filename . "] does not exist\r\n"
- }
-}
-
-foreach $ARG (@ARGV) {
- do replace($ARG);
-}
diff --git a/goVersion.sh b/goVersion.sh
deleted file mode 100644
index 77105f8b..00000000
--- a/goVersion.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-VER=$1
-echo "Will use version '${VER}'"
-echo "Changing pom.xml files"
-find . -name "pom.xml" |xargs perl version.pl ${VER}
-echo "Changing Java files"
-find . -name "StaticLoggerBinder.java" |xargs perl binderVersion.pl ${VER}
-
diff --git a/integration/build.xml b/integration/build.xml
index d3a5d5ac..89ffc373 100644..100755
--- a/integration/build.xml
+++ b/integration/build.xml
@@ -13,13 +13,10 @@
<echo message="runtime classpath: ${runtime_classpath}" />
<echo message="test classpath: ${test_classpath}" />
<echo message="plugin classpath: ${plugin_classpath}" />
+ <echo message="basedir: ${basedir}" />
- <path id="path142Binding">
- <pathelement location="target/test-classes/" />
- <pathelement location="../slf4j-api/target/slf4j-api-${currentVersion}.jar" />
- <pathelement location="./lib/slf4j-simple-1.4.2.jar" />
- </path >
+ <!--<property name="path_to_policy" value="file:./integration/src/policy/java-under-ant.policy"/>-->
<path id="path150Binding">
<pathelement location="target/test-classes/" />
@@ -39,27 +36,12 @@
<pathelement location="./lib/slf4j-simple-1.5.11.jar" />
</path >
- <!--<path id="pathIncompatible">
- <pathelement location="target/test-classes/" />
- <pathelement location="../slf4j-api/target/slf4j-api-${currentVersion}.jar" />
- <pathelement location="./lib/slf4j-simple-INCOMPATIBLE.jar" />
- </path >
- -->
-
<path id="pathCurrent">
<pathelement location="target/test-classes/" />
<pathelement location="../slf4j-api/target/slf4j-api-${currentVersion}.jar" />
<pathelement location="../slf4j-simple/target/slf4j-simple-${currentVersion}.jar" />
</path >
-
- <path id="incompatibleMultiBinding">
- <pathelement location="target/test-classes/" />
- <pathelement location="../slf4j-api/target/slf4j-api-${currentVersion}.jar" />
- <pathelement location="./lib/slf4j-simple-1.5.0.jar" />
- <pathelement location="./lib/slf4j-nop-1.5.6.jar" />
- </path >
-
<path id="multiBinding">
<pathelement location="target/test-classes/" />
<pathelement location="../slf4j-api/target/slf4j-api-${currentVersion}.jar" />
@@ -90,54 +72,64 @@
<!-- this is really very ugly, but it's the only way to circumvent
http://jira.codehaus.org/browse/MANTRUN-95
-->
+ <!--
<taskdef name="junit" classpath="${plugin_classpath};${compile_classpath}"
classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTask" />
+ -->
<target name="init">
<mkdir dir="target/unit-reports" />
</target>
<target name="testAll" depends="init,
- testMissingSingletonMethod,
- testMismatch,
+ testNoProvider150,
+ testMismatch,
testMatch,
- testMultiBinding,
- testIncompatibleMultiBinding,
- testFuture_16Series">
+ testMultiBinding,
+ testFuture_16Series,
+ testActiveSecurityManager">
</target>
- <target name="testMissingSingletonMethod">
+ <target name="testNoProvider150">
- <junit printsummary="yes" fork="no" haltonfailure="yes">
- <classpath refid="path142Binding" />
+ <junit printsummary="yes" fork="no" haltonfailure="yes">
+ <classpath refid="path150Binding" />
<formatter type="plain" />
- <test fork="yes" todir="target/unit-reports"
- outfile="TEST-142BININDING"
- name="org.slf4j.MissingSingletonMethodAssertionTest" />
+ <test fork="yes" todir="target/unit-reports"
+ outfile="TEST-150BINDING"
+ name="org.slf4j.NoProviderAssertionTest" />
</junit>
+ </target>
+
+
+ <target name="testMixed17">
+
<junit printsummary="yes" fork="no" haltonfailure="yes">
- <classpath refid="path150Binding" />
+ <classpath refid="pathMixed17" />
<formatter type="plain" />
<test fork="yes" todir="target/unit-reports"
- outfile="TEST-150BINDING"
- name="org.slf4j.MissingSingletonMethodAssertionTest" />
+ outfile="TEST-MIXED-17"
+ name="org.slf4j.VersionMismatchAssertionTest" />
</junit>
-
</target>
+
<target name="testMismatch">
+ <!--
+
<junit printsummary="yes" fork="no" haltonfailure="yes">
<classpath refid="path1511API" />
<formatter type="plain" />
<test fork="yes" todir="target/unit-reports"
outfile="TEST-MISMATCH-1511API"
- name="org.slf4j.VersionMismatchAssertionTest" />
+ name="org.slf4j.OldAPIVersionMismatchAssertionTest" />
</junit>
+ -->
-
+ <!--
<junit printsummary="yes" fork="no" haltonfailure="yes">
<classpath refid="path1511Binding" />
<formatter type="plain" />
@@ -145,6 +137,7 @@
outfile="TEST-MISMATCH-1511Binding"
name="org.slf4j.VersionMismatchAssertionTest" />
</junit>
+ -->
</target>
@@ -156,16 +149,7 @@
outfile="TEST-Match"
name="org.slf4j.CompatibilityAssertionTest" />
</junit>
- </target>
- <target name="testIncompatibleMultiBinding">
- <junit printsummary="yes" fork="no" haltonfailure="yes">
- <classpath refid="incompatibleMultiBinding" />
- <formatter type="plain" />
- <test fork="yes" todir="target/unit-reports"
- outfile="TEST-IncompatibleMultiBinding"
- name="org.slf4j.IncompatibleMultiBindingAssertionTest" />
- </junit>
</target>
<target name="testMultiBinding">
@@ -178,13 +162,17 @@
</junit>
</target>
+
<target name="testFuture_16Series">
- <junit printsummary="yes" fork="no" haltonfailure="yes">
+
+ <!-- 1.8 uses providers and no longer supports bindings ==
+
+ <junit printsummary="yes" fork="no" haltonfailure="yes">
<classpath refid="binding166" />
<formatter type="plain" />
<test fork="yes" todir="target/unit-reports"
outfile="TEST-binding166"
- name="org.slf4j.CompatibilityAssertionTest" />
+ name="org.slf4j.NoProviderAssertionTest" />
</junit>
@@ -195,6 +183,36 @@
outfile="TEST-api166"
name="org.slf4j.CompatibilityAssertionTest" />
</junit>
+ -->
+ </target>
+
+
+ <condition property="runFromWithinIntegrationModule">
+ <contains string="${user.dir}" substring="integration" />
+ </condition>
+
+ <target name="setPathToPolicy_FromTop" unless="runFromWithinIntegrationModule">
+ <echo>setPathToPolicy_FromTop</echo>
+ <property name="path_to_policy" value="file:./integration/src/policy/java-under-ant.policy"/>
+ </target>
+
+ <target name="setPathToPolicy_FromIntegration" if="runFromWithinIntegrationModule">
+ <echo>setPathToPolicy_FromInegration </echo>
+ <property name="path_to_policy" value="file:./src/policy/java-under-ant.policy"/>
+ </target>
+
+ <target name="testActiveSecurityManager" depends="setPathToPolicy_FromTop, setPathToPolicy_FromIntegration">
+ <junit printsummary="yes" fork="no" haltonfailure="yes">
+ <jvmarg value="-Djava.security.manager"/>
+ <jvmarg value="-Djava.security.policy=${path_to_policy}"/>
+ <jvmarg value="-Dslf4j.detectLoggerNameMismatch=true"/>
+ <classpath refid="pathCurrent" />
+ <formatter type="plain" />
+ <test fork="yes" todir="target/unit-reports"
+ outfile="TEST-SecurityManager"
+ name="org.slf4j.issues.Issue324Test" />
+ </junit>
</target>
+
</project> \ No newline at end of file
diff --git a/integration/lib/slf4j-simple-1.5.4-SNAPSHOT.jar b/integration/lib/slf4j-simple-1.5.4-SNAPSHOT.jar
deleted file mode 100644
index ebae7cd0..00000000
--- a/integration/lib/slf4j-simple-1.5.4-SNAPSHOT.jar
+++ /dev/null
Binary files differ
diff --git a/integration/osgi-build.xml b/integration/osgi-build.xml
index 231c2faa..8d0c17ce 100644..100755
--- a/integration/osgi-build.xml
+++ b/integration/osgi-build.xml
@@ -13,15 +13,22 @@
<echo message="test classpath: ${test_classpath}" />
<echo message="basedir: ${basedir}" />
+ <echo message="ant.java.version: ${ant.java.version}" />
+
<property name="iBundleJar" value="target/iBundle.jar"/>
<property name="bundlesDir" value="bundle"/>
<!-- this is really very ugly, but it's the only way to circumvent
http://jira.codehaus.org/browse/MANTRUN-95
- -->
+
<taskdef name="junit" classpath="${test_classpath}"
classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTask" />
+ -->
+
+ <condition property="jdk9">
+ <matches pattern="9.*" string="${ant.java.version}" />
+ </condition>
<path id="minimal">
<pathelement location="target/test-classes/" />
@@ -59,34 +66,45 @@
<!-- for some reason if mvn is invoked from the parent directory, junit gets
- invoked from the parent dir, which messes up theses tests. Hence, the
+ invoked from the parent dir, which messes up these tests. Hence, the
fork="yes" dir="${basedir}" -->
- <target name="nop">
+<!--
+ <jvmarg line="MINUS_MINUSadd-opens java.base/java.net=ALL-UNNAMED"/>
+ <jvmarg line="MINUS_MINUSadd-opens java.base/java.security=ALL-UNNAMED"/>
+-->
+
+ <target name="nop" unless="jdk9">
<prepareOSGiHarness binding="nop"/>
<junit printsummary="yes" fork="yes" dir="${basedir}" haltonfailure="yes">
<classpath path="${test_classpath}"/>
<formatter type="plain" />
- <test fork="yes" todir="target/unit-reports" name="org.slf4j.test_osgi.BundleTest" />
+ <test todir="target/unit-reports"
+ name="org.slf4j.test_osgi.BundleTest"
+ outfile="OSGI-nop" />
</junit>
</target>
- <target name="simple">
+ <target name="simple" unless="jdk9">
<prepareOSGiHarness binding="simple"/>
<junit printsummary="yes" fork="yes" dir="${basedir}" haltonfailure="yes">
<classpath path="${test_classpath}"/>
<formatter type="plain" />
- <test fork="yes" todir="target/unit-reports" name="org.slf4j.test_osgi.BundleTest" />
+ <test fork="yes" todir="target/unit-reports"
+ name="org.slf4j.test_osgi.BundleTest"
+ outfile="OSGI-simple" />
</junit>
</target>
- <target name="jdk14">
+ <target name="jdk14" unless="jdk9">
<prepareOSGiHarness binding="jdk14"/>
<junit printsummary="yes" fork="yes" dir="${basedir}" haltonfailure="yes">
<classpath path="${test_classpath}"/>
<formatter type="plain" />
- <test fork="yes" todir="target/unit-reports" name="org.slf4j.test_osgi.BundleTest" />
+ <test fork="yes" todir="target/unit-reports"
+ name="org.slf4j.test_osgi.BundleTest"
+ outfile="OSGI-jdk14"/>
</junit>
</target>
-</project> \ No newline at end of file
+</project>
diff --git a/integration/pom.xml b/integration/pom.xml
index 3230dc2f..092d8423 100755
--- a/integration/pom.xml
+++ b/integration/pom.xml
@@ -1,17 +1,16 @@
-<project
- xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
- <version>1.7.13-SNAPSHOT</version>
+ <version>2.0.12</version>
+ <relativePath>../parent/pom.xml</relativePath>
</parent>
-
<artifactId>integration</artifactId>
<packaging>jar</packaging>
<name>SLF4J Integration tests</name>
@@ -19,6 +18,14 @@
<url>http://www.slf4j.org</url>
<description>SLF4J integration tests</description>
+ <properties>
+ <junit.version>4.10</junit.version>
+ <!-- 1.9.1 does not work. Do not update lightly -->
+ <ant-junit.version>1.9.0</ant-junit.version>
+ <antrun-plugin.version>1.8</antrun-plugin.version>
+ </properties>
+
+
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
@@ -26,24 +33,28 @@
</dependency>
<!-- declaration to circumvent http://jira.codehaus.org/browse/MANTRUN-95 -->
+ <!--
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
- <version>3.8.1</version>
+ <version>${junit3.version}</version>
</dependency>
+ -->
<!-- declaration to circumvent http://jira.codehaus.org/browse/MANTRUN-95 -->
+ <!--
<dependency>
<groupId>ant</groupId>
<artifactId>ant-junit</artifactId>
- <version>1.6.5</version>
+ <version>${ant-junit.version}</version>
</dependency>
-
+ -->
<!-- some test run Felix in hosted mode -->
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.main</artifactId>
- <version>2.0.2</version>
+ <version>5.6.1</version>
+ <!--<version>2.0.2</version>-->
</dependency>
</dependencies>
@@ -51,17 +62,17 @@
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
- <version>1.2</version>
+ <version>${antrun-plugin.version}</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
- <version>3.8.1</version>
+ <version>${junit.version}</version>
</dependency>
<dependency>
- <groupId>ant</groupId>
+ <groupId>org.apache.ant</groupId>
<artifactId>ant-junit</artifactId>
- <version>1.6.5</version>
+ <version>${ant-junit.version}</version>
</dependency>
</dependencies>
<executions>
@@ -82,6 +93,7 @@
<goal>run</goal>
</goals>
</execution>
+ <!-- OSGI integration with ServiceLoader mechanism fails at this stage
<execution>
<id>ant-osgi-test</id>
<phase>package</phase>
@@ -97,7 +109,7 @@
<goal>run</goal>
</goals>
</execution>
-
+ -->
</executions>
</plugin>
@@ -113,9 +125,19 @@
</excludes>
</configuration>
</plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+
+
</plugins>
</build>
-</project> \ No newline at end of file
+</project>
diff --git a/integration/src/IBUNDLE-META-INF/MANIFEST.MF b/integration/src/IBUNDLE-META-INF/MANIFEST.MF
index d518a2b6..cd0e0b21 100644
--- a/integration/src/IBUNDLE-META-INF/MANIFEST.MF
+++ b/integration/src/IBUNDLE-META-INF/MANIFEST.MF
@@ -10,6 +10,6 @@ Implementation-Title: iBundle
Bundle-ManifestVersion: 2
Bundle-SymbolicName: iBundle
Bundle-Name: abundle
-Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Export-Package: apack
Import-Package: org.osgi.framework, org.slf4j;version=1.5 \ No newline at end of file
diff --git a/integration/src/policy/java-eclipse.policy b/integration/src/policy/java-eclipse.policy
new file mode 100644
index 00000000..9a42e4d1
--- /dev/null
+++ b/integration/src/policy/java-eclipse.policy
@@ -0,0 +1,10 @@
+
+grant {
+
+ // note that java.lang.RuntimePermission createSecurityManager is NOT granted
+
+ permission java.util.PropertyPermission "user.dir", "read";
+ permission java.util.PropertyPermission "*", "read";
+
+ permission java.net.SocketPermission "*", "connect,resolve";
+}; \ No newline at end of file
diff --git a/integration/src/policy/java-under-ant.policy b/integration/src/policy/java-under-ant.policy
new file mode 100644
index 00000000..41f7fcfb
--- /dev/null
+++ b/integration/src/policy/java-under-ant.policy
@@ -0,0 +1,13 @@
+
+grant {
+
+ // note that java.lang.RuntimePermission createSecurityManager is NOT granted
+
+ permission java.util.PropertyPermission "user.dir", "read";
+
+ // permissions required for Ant's Junit runner
+ permission java.util.PropertyPermission "*", "read, write";
+ permission java.io.FilePermission "./-", "read";
+ permission java.io.FilePermission "./-", "write";
+ permission java.lang.RuntimePermission "setIO";
+}; \ No newline at end of file
diff --git a/integration/src/test/java/org/slf4j/CompatibilityAssertionTest.java b/integration/src/test/java/org/slf4j/CompatibilityAssertionTest.java
index 021ef137..af804406 100644
--- a/integration/src/test/java/org/slf4j/CompatibilityAssertionTest.java
+++ b/integration/src/test/java/org/slf4j/CompatibilityAssertionTest.java
@@ -25,31 +25,33 @@
package org.slf4j;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import java.io.PrintStream;
import java.util.Random;
-import junit.framework.TestCase;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
-public class CompatibilityAssertionTest extends TestCase {
+public class CompatibilityAssertionTest {
StringPrintStream sps = new StringPrintStream(System.err);
PrintStream old = System.err;
int diff = 1024 + new Random().nextInt(10000);
- public CompatibilityAssertionTest(String name) {
- super(name);
- }
-
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() throws Exception {
System.setErr(sps);
}
- protected void tearDown() throws Exception {
- super.tearDown();
+ @After
+ public void tearDown() throws Exception {
System.setErr(old);
}
+ @Test
public void test() throws Exception {
Logger logger = LoggerFactory.getLogger(this.getClass());
String msg = "hello world " + diff;
@@ -57,5 +59,6 @@ public class CompatibilityAssertionTest extends TestCase {
assertEquals(1, sps.stringList.size());
String s0 = (String) sps.stringList.get(0);
assertTrue(s0.contains(msg));
+
}
}
diff --git a/integration/src/test/java/org/slf4j/IncompatibleMultiBindingAssertionTest.java b/integration/src/test/java/org/slf4j/IncompatibleMultiBindingAssertionTest.java
index 80c9b00e..c8fb4081 100644
--- a/integration/src/test/java/org/slf4j/IncompatibleMultiBindingAssertionTest.java
+++ b/integration/src/test/java/org/slf4j/IncompatibleMultiBindingAssertionTest.java
@@ -24,33 +24,35 @@
*/
package org.slf4j;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
import java.io.PrintStream;
import java.util.List;
import java.util.Random;
-import junit.framework.TestCase;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
-public class IncompatibleMultiBindingAssertionTest extends TestCase {
+public class IncompatibleMultiBindingAssertionTest {
StringPrintStream sps = new StringPrintStream(System.err);
PrintStream old = System.err;
int diff = 1024 + new Random().nextInt(10000);
- public IncompatibleMultiBindingAssertionTest(String name) {
- super(name);
- }
-
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() throws Exception {
System.setErr(sps);
}
- protected void tearDown() throws Exception {
- super.tearDown();
+ @After
+ public void tearDown() throws Exception {
System.setErr(old);
}
- public void test() throws Exception {
+ @Test
+ public void smoke() throws Exception {
try {
Logger logger = LoggerFactory.getLogger(this.getClass());
String msg = "hello world " + diff;
diff --git a/integration/src/test/java/org/slf4j/MissingSingletonMethodAssertionTest.java b/integration/src/test/java/org/slf4j/MissingSingletonMethodAssertionTest.java
deleted file mode 100644
index af678ccd..00000000
--- a/integration/src/test/java/org/slf4j/MissingSingletonMethodAssertionTest.java
+++ /dev/null
@@ -1,83 +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;
-
-import java.io.PrintStream;
-import java.util.Random;
-
-import junit.framework.TestCase;
-
-public class MissingSingletonMethodAssertionTest extends TestCase {
-
- StringPrintStream sps = new StringPrintStream(System.err);
- PrintStream old = System.err;
- int diff = 1024 + new Random().nextInt(10000);
-
- public MissingSingletonMethodAssertionTest(String name) {
- super(name);
- }
-
- protected void setUp() throws Exception {
- super.setUp();
- System.setErr(sps);
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- System.setErr(old);
- }
-
- public void test() throws Exception {
- try {
- Logger logger = LoggerFactory.getLogger(this.getClass());
- String msg = "hello world " + diff;
- logger.info(msg);
- fail("NoSuchMethodError expected");
- } catch (NoSuchMethodError e) {
- }
-
- int lineCount = sps.stringList.size();
- assertTrue("number of lines should be 3 but was " + lineCount, lineCount == 3);
-
- // expected output:
- // SLF4J: slf4j-api 1.6.x (or later) is incompatible with this binding.
- // SLF4J: Your binding is version 1.4.x or earlier.
- // SLF4J: Upgrade your binding to version 1.6.x. or 2.0.x
-
- {
- String s = (String) sps.stringList.get(0);
- assertTrue(s.contains("SLF4J: slf4j-api 1.6.x (or later) is incompatible with this binding."));
- }
- {
- String s = (String) sps.stringList.get(1);
- assertTrue(s.contains("SLF4J: Your binding is version 1.5.5 or earlier."));
- }
- {
- String s = (String) sps.stringList.get(2);
- assertTrue(s.contains("SLF4J: Upgrade your binding to version 1.6.x."));
- }
-
- }
-}
diff --git a/integration/src/test/java/org/slf4j/MultiBindingAssertionTest.java b/integration/src/test/java/org/slf4j/MultiBindingAssertionTest.java
index 8d1cb598..052faab2 100644
--- a/integration/src/test/java/org/slf4j/MultiBindingAssertionTest.java
+++ b/integration/src/test/java/org/slf4j/MultiBindingAssertionTest.java
@@ -28,38 +28,38 @@ import java.io.PrintStream;
import java.util.List;
import java.util.Random;
-import junit.framework.TestCase;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.assertTrue;
-public class MultiBindingAssertionTest extends TestCase {
+public class MultiBindingAssertionTest {
StringPrintStream sps = new StringPrintStream(System.err);
PrintStream old = System.err;
int diff = 1024 + new Random().nextInt(10000);
- public MultiBindingAssertionTest(String name) {
- super(name);
- }
-
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() throws Exception {
System.setErr(sps);
}
- protected void tearDown() throws Exception {
- super.tearDown();
+ @After
+ public void tearDown() throws Exception {
System.setErr(old);
}
+ @Test
public void test() throws Exception {
Logger logger = LoggerFactory.getLogger(this.getClass());
String msg = "hello world " + diff;
logger.info(msg);
List<String> list = sps.stringList;
- assertMsgContains(list, 0, "Class path contains multiple SLF4J bindings.");
- assertMsgContains(list, 1, "Found binding in");
- assertMsgContains(list, 2, "Found binding in");
- assertMsgContains(list, 3, "See http://www.slf4j.org/codes.html");
- assertMsgContains(list, 4, "Actual binding is of type [");
+ assertMsgContains(list, 0, "Class path contains multiple SLF4J providers.");
+ assertMsgContains(list, 1, "Found provider");
+ assertMsgContains(list, 2, "Found provider");
+ assertMsgContains(list, 3, "See https://www.slf4j.org/codes.html#multiple_bindings for an explanation.");
+ assertMsgContains(list, 4, "Actual provider is of type [");
}
void assertMsgContains(List<String> strList, int index, String msg) {
diff --git a/slf4j-ext/src/test/java/org/slf4j/dummyExt/MDCStrLookupTest.java b/integration/src/test/java/org/slf4j/NoProviderAssertionTest.java
index 8544e7b3..7ee8baa8 100644
--- a/slf4j-ext/src/test/java/org/slf4j/dummyExt/MDCStrLookupTest.java
+++ b/integration/src/test/java/org/slf4j/NoProviderAssertionTest.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2004-2011 QOS.ch
+ * Copyright (c) 2004-2016 QOS.ch
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
@@ -22,35 +22,36 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j.dummyExt;
+package org.slf4j;
-import junit.framework.TestCase;
+import java.io.PrintStream;
+import java.util.Random;
-import org.slf4j.MDC;
-import org.slf4j.ext.MDCStrLookup;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
-public class MDCStrLookupTest extends TestCase {
+public class NoProviderAssertionTest {
- public MDCStrLookupTest(String name) {
- super(name);
- }
+ StringPrintStream sps = new StringPrintStream(System.err);
+ PrintStream old = System.err;
+ int diff = 1024 + new Random().nextInt(10000);
+ @Before
public void setUp() throws Exception {
- super.setUp();
+ System.setErr(sps);
}
+ @After
public void tearDown() throws Exception {
- super.tearDown();
+ System.setErr(old);
}
- public void testLookup() throws Exception {
- MDC.put("key", "value");
- MDC.put("number", "2");
- MDCStrLookup lookup = new MDCStrLookup();
- assertEquals("value", lookup.lookup("key"));
- assertEquals("2", lookup.lookup("number"));
- assertEquals(null, lookup.lookup(null));
- assertEquals(null, lookup.lookup(""));
- assertEquals(null, lookup.lookup("other"));
+ @Test
+ public void test() throws Exception {
+ Logger logger = LoggerFactory.getLogger(this.getClass());
+ String msg = "hello world " + diff;
+ logger.info(msg);
+ OutputVerifier.noProvider(sps);
}
}
diff --git a/integration/src/test/java/org/slf4j/VersionMismatchAssertionTest.java b/integration/src/test/java/org/slf4j/OldAPIVersionMismatchAssertionTest.java
index c6d90e03..0b67214c 100644
--- a/integration/src/test/java/org/slf4j/VersionMismatchAssertionTest.java
+++ b/integration/src/test/java/org/slf4j/OldAPIVersionMismatchAssertionTest.java
@@ -24,36 +24,39 @@
*/
package org.slf4j;
+import static org.junit.Assert.assertTrue;
+
import java.io.PrintStream;
import java.util.Random;
-import junit.framework.TestCase;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
-public class VersionMismatchAssertionTest extends TestCase {
+public class OldAPIVersionMismatchAssertionTest {
StringPrintStream sps = new StringPrintStream(System.err);
PrintStream old = System.err;
int diff = 1024 + new Random().nextInt(10000);
- public VersionMismatchAssertionTest(String name) {
- super(name);
- }
-
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() throws Exception {
System.setErr(sps);
}
- protected void tearDown() throws Exception {
- super.tearDown();
+ @After
+ public void tearDown() throws Exception {
System.setErr(old);
}
+ @Test
public void test() throws Exception {
Logger logger = LoggerFactory.getLogger(this.getClass());
String msg = "hello world " + diff;
logger.info(msg);
+ OutputVerifier.dump(sps);
+
String s0 = (String) sps.stringList.get(0);
assertTrue(s0.matches("SLF4J: The requested version .* by your slf4j binding is not compatible with.*"));
diff --git a/integration/src/test/java/org/slf4j/OutputVerifier.java b/integration/src/test/java/org/slf4j/OutputVerifier.java
new file mode 100755
index 00000000..fbc71a15
--- /dev/null
+++ b/integration/src/test/java/org/slf4j/OutputVerifier.java
@@ -0,0 +1,54 @@
+package org.slf4j;
+
+import static junit.framework.Assert.assertTrue;
+
+public class OutputVerifier {
+
+ static void noProvider(StringPrintStream sps) {
+ dump(sps);
+ int lineCount = sps.stringList.size();
+ assertTrue("number of lines should be 6 but was " + lineCount, lineCount == 6);
+
+ // expected output: (version 1.8)
+ // SLF4J: No SLF4J providers were found.
+ // SLF4J: Defaulting to no-operation (NOP) logger implementation
+ // SLF4J: See http://www.slf4j.org/codes.html#noProviders for further details.
+ // SLF4J: Class path contains SLF4J bindings targeting slf4j-api versions prior to 1.8.
+ // SLF4J: Ignoring binding found at
+ // [jar:file:..../slf4j-simple-1.4.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
+ // SLF4J: See http://www.slf4j.org/codes.html#ignoredBindings for an explanation.
+
+ {
+ String s = (String) sps.stringList.get(0);
+ assertTrue(s.contains("No SLF4J providers were found."));
+ }
+ {
+ String s = (String) sps.stringList.get(1);
+ assertTrue(s.contains("Defaulting to no-operation (NOP) logger implementation"));
+ }
+ {
+ String s = (String) sps.stringList.get(2);
+ assertTrue(s.contains("See https://www.slf4j.org/codes.html#noProviders for further details."));
+ }
+
+ {
+ String s = (String) sps.stringList.get(3);
+ assertTrue(s.contains("Class path contains SLF4J bindings targeting slf4j-api versions 1.7.x or earlier."));
+ }
+
+ {
+ String s = (String) sps.stringList.get(4);
+ assertTrue(s.contains("Ignoring binding found at"));
+ }
+ {
+ String s = (String) sps.stringList.get(5);
+ assertTrue(s.contains("See https://www.slf4j.org/codes.html#ignoredBindings for an explanation"));
+ }
+ }
+
+ public static void dump(StringPrintStream sps) {
+ for (String s : sps.stringList) {
+ System.out.println(s);
+ }
+ }
+}
diff --git a/integration/src/test/java/org/slf4j/StringPrintStream.java b/integration/src/test/java/org/slf4j/StringPrintStream.java
index 200b745f..a26cb391 100644
--- a/integration/src/test/java/org/slf4j/StringPrintStream.java
+++ b/integration/src/test/java/org/slf4j/StringPrintStream.java
@@ -32,7 +32,7 @@ public class StringPrintStream extends PrintStream {
public static final String LINE_SEP = System.getProperty("line.separator");
PrintStream other;
- List<String> stringList = new ArrayList<String>();
+ List<String> stringList = new ArrayList<>();
public StringPrintStream(PrintStream ps) {
super(ps);
diff --git a/integration/src/test/java/org/slf4j/issues/Issue324Test.java b/integration/src/test/java/org/slf4j/issues/Issue324Test.java
new file mode 100644
index 00000000..9d3cf208
--- /dev/null
+++ b/integration/src/test/java/org/slf4j/issues/Issue324Test.java
@@ -0,0 +1,16 @@
+package org.slf4j.issues;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import junit.framework.TestCase;
+
+public class Issue324Test extends TestCase {
+
+ public void testLoggerCreationInPresenceOfSecurityManager() {
+ String currentDir = System.getProperty("user.dir");
+ System.out.println("currentDir:" + currentDir);
+ Logger logger = LoggerFactory.getLogger(Issue324Test.class);
+ logger.debug("hello");
+ }
+}
diff --git a/integration/src/test/java/org/slf4j/test_osgi/CheckingBundleListener.java b/integration/src/test/java/org/slf4j/test_osgi/CheckingBundleListener.java
index ef4a0349..bdbfdee8 100644
--- a/integration/src/test/java/org/slf4j/test_osgi/CheckingBundleListener.java
+++ b/integration/src/test/java/org/slf4j/test_osgi/CheckingBundleListener.java
@@ -33,7 +33,7 @@ import org.osgi.framework.BundleListener;
public class CheckingBundleListener implements BundleListener {
- List<BundleEvent> eventList = new ArrayList<BundleEvent>();
+ List<BundleEvent> eventList = new ArrayList<>();
public void bundleChanged(BundleEvent be) {
eventList.add(be);
@@ -45,16 +45,14 @@ public class CheckingBundleListener implements BundleListener {
}
public void dumpAll() {
- for (int i = 0; i < eventList.size(); i++) {
- BundleEvent fe = (BundleEvent) eventList.get(i);
+ for (BundleEvent fe : eventList) {
dump(fe);
}
}
boolean exists(String bundleName) {
- for (int i = 0; i < eventList.size(); i++) {
- BundleEvent fe = (BundleEvent) eventList.get(i);
- Bundle b = fe.getBundle();
+ for (BundleEvent bundleEvent : eventList) {
+ Bundle b = bundleEvent.getBundle();
System.out.println("===[" + b + "]");
if (bundleName.equals(b.getSymbolicName())) {
return true;
diff --git a/integration/src/test/java/org/slf4j/test_osgi/FelixHost.java b/integration/src/test/java/org/slf4j/test_osgi/FelixHost.java
index 204b8c23..10997055 100644
--- a/integration/src/test/java/org/slf4j/test_osgi/FelixHost.java
+++ b/integration/src/test/java/org/slf4j/test_osgi/FelixHost.java
@@ -41,7 +41,7 @@ import org.osgi.framework.Constants;
* Runs a hosted version of Felix for testing purposes. Any bundle errors are
* reported via the FrameworkListener passed to the constructor.
*
- * @author Ceki G&uuml;c&uuml;
+ * @author Ceki G&uuml;lc&uuml;
*/
public class FelixHost {
@@ -59,7 +59,7 @@ public class FelixHost {
public void doLaunch() {
// Create a case-insensitive configuration property map.
- StringMap configMap = new StringMap(false);
+ StringMap configMap = new StringMap();
// Configure the Felix instance to be embedded.
// configMap.put(FelixConstants.EMBEDDED_EXECUTION_PROP, "true");
// Add core OSGi packages to be exported from the class path
@@ -75,7 +75,7 @@ public class FelixHost {
try {
// Create host activator;
- List<Object> list = new ArrayList<Object>();
+ List<Object> list = new ArrayList<>();
// list.add(new HostActivator());
configMap.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "org.xml.sax, org.xml.sax.helpers, javax.xml.parsers, javax.naming");
@@ -89,8 +89,8 @@ public class FelixHost {
// otherProps.put(Constants.FRAMEWORK_STORAGE, "bundles");
- otherProps.put(AutoProcessor.AUTO_DEPLOY_DIR_PROPERY, AutoProcessor.AUTO_DEPLOY_DIR_VALUE);
- otherProps.put(AutoProcessor.AUTO_DEPLOY_ACTION_PROPERY, AutoProcessor.AUTO_DEPLOY_START_VALUE + "," + AutoProcessor.AUTO_DEPLOY_INSTALL_VALUE);
+ otherProps.put(AutoProcessor.AUTO_DEPLOY_DIR_PROPERTY, AutoProcessor.AUTO_DEPLOY_DIR_VALUE);
+ otherProps.put(AutoProcessor.AUTO_DEPLOY_ACTION_PROPERTY, AutoProcessor.AUTO_DEPLOY_START_VALUE + "," + AutoProcessor.AUTO_DEPLOY_INSTALL_VALUE);
BundleContext felixBudleContext = felix.getBundleContext();
diff --git a/integration/src/test/java/org/slf4j/test_osgi/FrameworkErrorListener.java b/integration/src/test/java/org/slf4j/test_osgi/FrameworkErrorListener.java
index 2f9458d8..bdb13a7f 100644
--- a/integration/src/test/java/org/slf4j/test_osgi/FrameworkErrorListener.java
+++ b/integration/src/test/java/org/slf4j/test_osgi/FrameworkErrorListener.java
@@ -32,8 +32,9 @@ import org.osgi.framework.FrameworkListener;
public class FrameworkErrorListener implements FrameworkListener {
- public List<FrameworkEvent> errorList = new ArrayList<FrameworkEvent>();
+ public List<FrameworkEvent> errorList = new ArrayList<>();
+ @Override
public void frameworkEvent(FrameworkEvent fe) {
if (fe.getType() == FrameworkEvent.ERROR) {
errorList.add(fe);
@@ -54,9 +55,8 @@ public class FrameworkErrorListener implements FrameworkListener {
}
public void dumpAll() {
- for (int i = 0; i < errorList.size(); i++) {
- FrameworkEvent fe = (FrameworkEvent) errorList.get(i);
- dump(fe);
+ for (FrameworkEvent frameworkEvent : errorList) {
+ dump(frameworkEvent);
}
}
}
diff --git a/jcl-over-slf4j/pom.xml b/jcl-over-slf4j/pom.xml
index c6ff398f..80249164 100755
--- a/jcl-over-slf4j/pom.xml
+++ b/jcl-over-slf4j/pom.xml
@@ -1,65 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
- <version>1.7.13-SNAPSHOT</version>
+ <version>2.0.12</version>
+ <relativePath>../parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jcl-over-slf4j</artifactId>
<packaging>jar</packaging>
- <name>JCL 1.1.1 implemented over SLF4J</name>
- <description>JCL 1.1.1 implemented over SLF4J</description>
+ <name>JCL 1.2 implemented over SLF4J</name>
+ <description>JCL 1.2 implemented over SLF4J</description>
<url>http://www.slf4j.org</url>
+ <licenses>
+ <license>
+ <name>Apache License, Version 2.0</name>
+ <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
- <dependencies>
- <!--
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-nop</artifactId>
- <version>${project.version}</version>
- <scope>provided</scope>
- </dependency>
- -->
+ <properties>
+ <module-name>org.apache.commons.logging</module-name>
+ </properties>
+ <dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
-
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<scope>test</scope>
</dependency>
-
</dependencies>
-
<build>
<plugins>
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
<configuration>
- <archive>
- <manifestEntries>
- <Bundle-Version>${parsedVersion.osgiVersion}</Bundle-Version>
- <Bundle-Description>${project.description}</Bundle-Description>
- <Implementation-Version>${project.version}</Implementation-Version>
- </manifestEntries>
- <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
- </archive>
+ <instructions>
+ <_exportcontents>org.apache.commons.logging*;version=${jcl.version};-noimport:=true</_exportcontents>
+ </instructions>
</configuration>
</plugin>
-
- </plugins>
-
+ </plugins>
</build>
-
-</project> \ No newline at end of file
+</project>
diff --git a/jcl-over-slf4j/src/main/java/org/apache/commons/logging/Log.java b/jcl-over-slf4j/src/main/java/org/apache/commons/logging/Log.java
index 779c4d9d..b74c8a74 100644
--- a/jcl-over-slf4j/src/main/java/org/apache/commons/logging/Log.java
+++ b/jcl-over-slf4j/src/main/java/org/apache/commons/logging/Log.java
@@ -20,7 +20,7 @@ package org.apache.commons.logging;
* <p>A simple logging interface abstracting logging APIs. In order to be
* instantiated successfully by {@link LogFactory}, classes that implement
* this interface must have a constructor that takes a single String
- * parameter representing the "name" of this Log.</p>
+ * parameter representing the "name" of this Log.
*
* <p> The six logging levels used by <code>Log</code> are (in order):
* <ol>
@@ -34,27 +34,27 @@ package org.apache.commons.logging;
* The mapping of these log levels to the concepts used by the underlying
* logging system is implementation dependent.
* The implementation should ensure, though, that this ordering behaves
- * as expected.</p>
+ * as expected.
*
* <p>Performance is often a logging concern.
* By examining the appropriate property,
* a component can avoid expensive operations (producing information
- * to be logged).</p>
+ * to be logged).
*
* <p> For example,
- * <code><pre>
+ * <pre>
* if (log.isDebugEnabled()) {
* ... do something expensive ...
* log.debug(theResult);
* }
- * </pre></code>
- * </p>
+ * </pre>
+ *
*
* <p>Configuration of the underlying logging system will generally be done
* external to the Logging APIs, through whatever mechanism is supported by
- * that system.</p>
+ * that system.
*
- * <p style="color: #E40; font-weight: bold;">Please note that this interface is identical to that found in JCL 1.1.1.</p>
+ * <p style="color: #E40; font-weight: bold;">Please note that this interface is identical to that found in JCL 1.1.1.
*
* @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
* @author Rod Waldhoff
@@ -65,74 +65,74 @@ public interface Log {
// ----------------------------------------------------- Logging Properties
/**
- * <p> Is debug logging currently enabled? </p>
+ * <p> Is debug logging currently enabled?
*
* <p> Call this method to prevent having to perform expensive operations
* (for example, <code>String</code> concatenation)
- * when the log level is more than debug. </p>
+ * when the log level is more than debug.
*/
public boolean isDebugEnabled();
/**
- * <p> Is error logging currently enabled? </p>
+ * <p> Is error logging currently enabled?
*
* <p> Call this method to prevent having to perform expensive operations
* (for example, <code>String</code> concatenation)
- * when the log level is more than error. </p>
+ * when the log level is more than error.
*/
public boolean isErrorEnabled();
/**
- * <p> Is fatal logging currently enabled? </p>
+ * <p> Is fatal logging currently enabled?
*
* <p> Call this method to prevent having to perform expensive operations
* (for example, <code>String</code> concatenation)
- * when the log level is more than fatal. </p>
+ * when the log level is more than fatal.
*/
public boolean isFatalEnabled();
/**
- * <p> Is info logging currently enabled? </p>
+ * <p> Is info logging currently enabled?
*
* <p> Call this method to prevent having to perform expensive operations
* (for example, <code>String</code> concatenation)
- * when the log level is more than info. </p>
+ * when the log level is more than info.
*
* @return true if info enabled, false otherwise
*/
public boolean isInfoEnabled();
/**
- * <p> Is trace logging currently enabled? </p>
+ * <p> Is trace logging currently enabled?
*
* <p> Call this method to prevent having to perform expensive operations
* (for example, <code>String</code> concatenation)
- * when the log level is more than trace. </p>
+ * when the log level is more than trace.
*
* @return true if trace enabled, false otherwise
*/
public boolean isTraceEnabled();
/**
- * <p> Is warn logging currently enabled? </p>
+ * <p> Is warn logging currently enabled?
*
* <p> Call this method to prevent having to perform expensive operations
* (for example, <code>String</code> concatenation)
- * when the log level is more than warn. </p>
+ * when the log level is more than warn.
*/
public boolean isWarnEnabled();
// -------------------------------------------------------- Logging Methods
/**
- * <p> Log a message with trace log level. </p>
+ * <p> Log a message with trace log level.
*
* @param message log this message
*/
public void trace(Object message);
/**
- * <p> Log an error with trace log level. </p>
+ * <p> Log an error with trace log level.
*
* @param message log this message
* @param t log this cause
@@ -140,14 +140,14 @@ public interface Log {
public void trace(Object message, Throwable t);
/**
- * <p> Log a message with debug log level. </p>
+ * <p> Log a message with debug log level.
*
* @param message log this message
*/
public void debug(Object message);
/**
- * <p> Log an error with debug log level. </p>
+ * <p> Log an error with debug log level.
*
* @param message log this message
* @param t log this cause
@@ -155,14 +155,14 @@ public interface Log {
public void debug(Object message, Throwable t);
/**
- * <p> Log a message with info log level. </p>
+ * <p> Log a message with info log level.
*
* @param message log this message
*/
public void info(Object message);
/**
- * <p> Log an error with info log level. </p>
+ * <p> Log an error with info log level.
*
* @param message log this message
* @param t log this cause
@@ -170,14 +170,14 @@ public interface Log {
public void info(Object message, Throwable t);
/**
- * <p> Log a message with warn log level. </p>
+ * <p> Log a message with warn log level.
*
* @param message log this message
*/
public void warn(Object message);
/**
- * <p> Log an error with warn log level. </p>
+ * <p> Log an error with warn log level.
*
* @param message log this message
* @param t log this cause
@@ -185,14 +185,14 @@ public interface Log {
public void warn(Object message, Throwable t);
/**
- * <p> Log a message with error log level. </p>
+ * <p> Log a message with error log level.
*
* @param message log this message
*/
public void error(Object message);
/**
- * <p> Log an error with error log level. </p>
+ * <p> Log an error with error log level.
*
* @param message log this message
* @param t log this cause
@@ -200,14 +200,14 @@ public interface Log {
public void error(Object message, Throwable t);
/**
- * <p> Log a message with fatal log level. </p>
+ * <p> Log a message with fatal log level.
*
* @param message log this message
*/
public void fatal(Object message);
/**
- * <p> Log an error with fatal log level. </p>
+ * <p> Log an error with fatal log level.
*
* @param message log this message
* @param t log this cause
diff --git a/jcl-over-slf4j/src/main/java/org/apache/commons/logging/LogConfigurationException.java b/jcl-over-slf4j/src/main/java/org/apache/commons/logging/LogConfigurationException.java
index 668f413d..c51084ef 100644
--- a/jcl-over-slf4j/src/main/java/org/apache/commons/logging/LogConfigurationException.java
+++ b/jcl-over-slf4j/src/main/java/org/apache/commons/logging/LogConfigurationException.java
@@ -21,7 +21,7 @@ package org.apache.commons.logging;
* An exception that is thrown only if a suitable <code>LogFactory</code> or
* <code>Log</code> instance cannot be created by the corresponding factory
* methods.
- * </p>
+ *
*
* <p>
* In this version of JCL, this exception will never be thrown in practice.
diff --git a/jcl-over-slf4j/src/main/java/org/apache/commons/logging/LogFactory.java b/jcl-over-slf4j/src/main/java/org/apache/commons/logging/LogFactory.java
index 275aab30..f58c0e31 100644
--- a/jcl-over-slf4j/src/main/java/org/apache/commons/logging/LogFactory.java
+++ b/jcl-over-slf4j/src/main/java/org/apache/commons/logging/LogFactory.java
@@ -25,7 +25,7 @@ import org.apache.commons.logging.impl.SLF4JLogFactory;
* Factory for creating {@link Log} instances, which always delegates to an
* instance of {@link SLF4JLogFactory}.
*
- * </p>
+ *
*
* @author Craig R. McClanahan
* @author Costin Manolache
@@ -170,7 +170,7 @@ public abstract class LogFactory {
* <p>
* Construct (if necessary) and return a <code>Log</code> instance, using
* the factory's current set of configuration attributes.
- * </p>
+ *
*
* <p>
* <strong>NOTE </strong>- Depending upon the implementation of the
@@ -178,7 +178,7 @@ public abstract class LogFactory {
* you are returned may or may not be local to the current application, and
* may or may not be returned again on a subsequent call with the same name
* argument.
- * </p>
+ *
*
* @param name
* Logical name of the <code>Log</code> instance to be
@@ -229,7 +229,7 @@ public abstract class LogFactory {
* Construct (if necessary) and return a <code>LogFactory</code> instance,
* using the following ordered lookup procedure to determine the name of the
* implementation class to be loaded.
- * </p>
+ *
* <ul>
* <li>The <code>org.apache.commons.logging.LogFactory</code> system
* property.</li>
@@ -248,7 +248,7 @@ public abstract class LogFactory {
* <code>LogFactory</code> implementation class is utilized, all of the
* properties defined in this file will be set as configuration attributes on
* the corresponding <code>LogFactory</code> instance.
- * </p>
+ *
*
* @exception LogConfigurationException
* if the implementation class is not available or cannot
@@ -321,9 +321,9 @@ public abstract class LogFactory {
* Returns a string that uniquely identifies the specified object, including
* its class.
* <p>
- * The returned string is of form "classname@hashcode", ie is the same as the
+ * The returned string is of form "classname@hashcode", i.e. is the same as the
* return value of the Object.toString() method, but works even when the
- * specified object's class has overidden the toString method.
+ * specified object's class has overridden the toString method.
*
* @param o
* may be null.
@@ -345,64 +345,64 @@ public abstract class LogFactory {
* This method exists to ensure signature compatibility.
*/
protected static Object createFactory(String factoryClass, ClassLoader classLoader) {
- throw new UnsupportedOperationException("Operation [factoryClass] is not supported in jcl-over-slf4j. See also "
- + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
+ throw new UnsupportedOperationException(
+ "Operation [factoryClass] is not supported in jcl-over-slf4j. See also " + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
}
/**
* This method exists to ensure signature compatibility.
*/
protected static ClassLoader directGetContextClassLoader() {
- throw new UnsupportedOperationException("Operation [directGetContextClassLoader] is not supported in jcl-over-slf4j. See also "
- + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
+ throw new UnsupportedOperationException(
+ "Operation [directGetContextClassLoader] is not supported in jcl-over-slf4j. See also " + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
}
/**
* This method exists to ensure signature compatibility.
*/
protected static ClassLoader getContextClassLoader() throws LogConfigurationException {
- throw new UnsupportedOperationException("Operation [getContextClassLoader] is not supported in jcl-over-slf4j. See also "
- + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
+ throw new UnsupportedOperationException(
+ "Operation [getContextClassLoader] is not supported in jcl-over-slf4j. See also " + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
}
/**
* This method exists to ensure signature compatibility.
*/
protected static ClassLoader getClassLoader(Class clazz) {
- throw new UnsupportedOperationException("Operation [getClassLoader] is not supported in jcl-over-slf4j. See also "
- + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
+ throw new UnsupportedOperationException(
+ "Operation [getClassLoader] is not supported in jcl-over-slf4j. See also " + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
}
/**
* This method exists to ensure signature compatibility.
*/
protected static boolean isDiagnosticsEnabled() {
- throw new UnsupportedOperationException("Operation [isDiagnosticsEnabled] is not supported in jcl-over-slf4j. See also "
- + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
+ throw new UnsupportedOperationException(
+ "Operation [isDiagnosticsEnabled] is not supported in jcl-over-slf4j. See also " + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
}
/**
* This method exists to ensure signature compatibility.
*/
protected static void logRawDiagnostic(String msg) {
- throw new UnsupportedOperationException("Operation [logRawDiagnostic] is not supported in jcl-over-slf4j. See also "
- + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
+ throw new UnsupportedOperationException(
+ "Operation [logRawDiagnostic] is not supported in jcl-over-slf4j. See also " + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
}
/**
* This method exists to ensure signature compatibility.
*/
protected static LogFactory newFactory(final String factoryClass, final ClassLoader classLoader, final ClassLoader contextClassLoader) {
- throw new UnsupportedOperationException("Operation [logRawDiagnostic] is not supported in jcl-over-slf4j. See also "
- + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
+ throw new UnsupportedOperationException(
+ "Operation [logRawDiagnostic] is not supported in jcl-over-slf4j. See also " + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
}
/**
* This method exists to ensure signature compatibility.
*/
protected static LogFactory newFactory(final String factoryClass, final ClassLoader classLoader) {
- throw new UnsupportedOperationException("Operation [newFactory] is not supported in jcl-over-slf4j. See also "
- + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
+ throw new UnsupportedOperationException(
+ "Operation [newFactory] is not supported in jcl-over-slf4j. See also " + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
}
} \ No newline at end of file
diff --git a/jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/NoOpLog.java b/jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/NoOpLog.java
index 45e99a4a..49f72528 100644
--- a/jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/NoOpLog.java
+++ b/jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/NoOpLog.java
@@ -23,7 +23,7 @@ import org.apache.commons.logging.Log;
* <p>
* Trivial implementation of Log that throws away all messages. No configurable
* system properties are supported.
- * </p>
+ *
*
* @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
* @author Rod Waldhoff
diff --git a/jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4JLocationAwareLog.java b/jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4JLocationAwareLog.java
index ef48be67..755c2f59 100644
--- a/jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4JLocationAwareLog.java
+++ b/jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4JLocationAwareLog.java
@@ -43,11 +43,11 @@ public class SLF4JLocationAwareLog implements Log, Serializable {
// in both Log4jLogger and Jdk14Logger classes in the original JCL, the
// logger instance is transient
- private transient LocationAwareLogger logger;
+ private final transient LocationAwareLogger logger;
private static final String FQCN = SLF4JLocationAwareLog.class.getName();
- SLF4JLocationAwareLog(LocationAwareLogger logger) {
+ public SLF4JLocationAwareLog(LocationAwareLogger logger) {
this.logger = logger;
this.name = logger.getName();
}
@@ -104,7 +104,9 @@ public class SLF4JLocationAwareLog implements Log, Serializable {
* the message to log. Converted to {@link String}
*/
public void trace(Object message) {
- logger.log(null, FQCN, LocationAwareLogger.TRACE_INT, String.valueOf(message), null, null);
+ if (isTraceEnabled()) {
+ logger.log(null, FQCN, LocationAwareLogger.TRACE_INT, String.valueOf(message), null, null);
+ }
}
/**
@@ -117,7 +119,9 @@ public class SLF4JLocationAwareLog implements Log, Serializable {
* the exception to log
*/
public void trace(Object message, Throwable t) {
- logger.log(null, FQCN, LocationAwareLogger.TRACE_INT, String.valueOf(message), null, t);
+ if (isTraceEnabled()) {
+ logger.log(null, FQCN, LocationAwareLogger.TRACE_INT, String.valueOf(message), null, t);
+ }
}
/**
@@ -128,7 +132,9 @@ public class SLF4JLocationAwareLog implements Log, Serializable {
* the message to log. Converted to {@link String}
*/
public void debug(Object message) {
- logger.log(null, FQCN, LocationAwareLogger.DEBUG_INT, String.valueOf(message), null, null);
+ if (isDebugEnabled()) {
+ logger.log(null, FQCN, LocationAwareLogger.DEBUG_INT, String.valueOf(message), null, null);
+ }
}
/**
@@ -141,7 +147,9 @@ public class SLF4JLocationAwareLog implements Log, Serializable {
* the exception to log
*/
public void debug(Object message, Throwable t) {
- logger.log(null, FQCN, LocationAwareLogger.DEBUG_INT, String.valueOf(message), null, t);
+ if (isDebugEnabled()) {
+ logger.log(null, FQCN, LocationAwareLogger.DEBUG_INT, String.valueOf(message), null, t);
+ }
}
/**
@@ -152,7 +160,9 @@ public class SLF4JLocationAwareLog implements Log, Serializable {
* the message to log. Converted to {@link String}
*/
public void info(Object message) {
- logger.log(null, FQCN, LocationAwareLogger.INFO_INT, String.valueOf(message), null, null);
+ if (isInfoEnabled()) {
+ logger.log(null, FQCN, LocationAwareLogger.INFO_INT, String.valueOf(message), null, null);
+ }
}
/**
@@ -165,7 +175,9 @@ public class SLF4JLocationAwareLog implements Log, Serializable {
* the exception to log
*/
public void info(Object message, Throwable t) {
- logger.log(null, FQCN, LocationAwareLogger.INFO_INT, String.valueOf(message), null, t);
+ if (isInfoEnabled()) {
+ logger.log(null, FQCN, LocationAwareLogger.INFO_INT, String.valueOf(message), null, t);
+ }
}
/**
@@ -176,7 +188,9 @@ public class SLF4JLocationAwareLog implements Log, Serializable {
* the message to log. Converted to {@link String}
*/
public void warn(Object message) {
- logger.log(null, FQCN, LocationAwareLogger.WARN_INT, String.valueOf(message), null, null);
+ if (isWarnEnabled()) {
+ logger.log(null, FQCN, LocationAwareLogger.WARN_INT, String.valueOf(message), null, null);
+ }
}
/**
@@ -189,7 +203,9 @@ public class SLF4JLocationAwareLog implements Log, Serializable {
* the exception to log
*/
public void warn(Object message, Throwable t) {
- logger.log(null, FQCN, LocationAwareLogger.WARN_INT, String.valueOf(message), null, t);
+ if (isWarnEnabled()) {
+ logger.log(null, FQCN, LocationAwareLogger.WARN_INT, String.valueOf(message), null, t);
+ }
}
/**
@@ -200,7 +216,9 @@ public class SLF4JLocationAwareLog implements Log, Serializable {
* the message to log. Converted to {@link String}
*/
public void error(Object message) {
- logger.log(null, FQCN, LocationAwareLogger.ERROR_INT, String.valueOf(message), null, null);
+ if (isErrorEnabled()) {
+ logger.log(null, FQCN, LocationAwareLogger.ERROR_INT, String.valueOf(message), null, null);
+ }
}
/**
@@ -213,7 +231,9 @@ public class SLF4JLocationAwareLog implements Log, Serializable {
* the exception to log
*/
public void error(Object message, Throwable t) {
- logger.log(null, FQCN, LocationAwareLogger.ERROR_INT, String.valueOf(message), null, t);
+ if (isErrorEnabled()) {
+ logger.log(null, FQCN, LocationAwareLogger.ERROR_INT, String.valueOf(message), null, t);
+ }
}
/**
@@ -224,7 +244,9 @@ public class SLF4JLocationAwareLog implements Log, Serializable {
* the message to log. Converted to {@link String}
*/
public void fatal(Object message) {
- logger.log(null, FQCN, LocationAwareLogger.ERROR_INT, String.valueOf(message), null, null);
+ if (isErrorEnabled()) {
+ logger.log(null, FQCN, LocationAwareLogger.ERROR_INT, String.valueOf(message), null, null);
+ }
}
/**
@@ -237,7 +259,9 @@ public class SLF4JLocationAwareLog implements Log, Serializable {
* the exception to log
*/
public void fatal(Object message, Throwable t) {
- logger.log(null, FQCN, LocationAwareLogger.ERROR_INT, String.valueOf(message), null, t);
+ if (isErrorEnabled()) {
+ logger.log(null, FQCN, LocationAwareLogger.ERROR_INT, String.valueOf(message), null, t);
+ }
}
/**
diff --git a/jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4JLog.java b/jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4JLog.java
index 5ee59f7b..2e796c2b 100644
--- a/jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4JLog.java
+++ b/jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4JLog.java
@@ -42,9 +42,9 @@ public class SLF4JLog implements Log, Serializable {
// in both Log4jLogger and Jdk14Logger classes in the original JCL, the
// logger instance is transient
- private transient Logger logger;
+ private final transient Logger logger;
- SLF4JLog(Logger logger) {
+ public SLF4JLog(Logger logger) {
this.logger = logger;
this.name = logger.getName();
}
diff --git a/jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4JLogFactory.java b/jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4JLogFactory.java
index d715c59f..2050adb2 100644
--- a/jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4JLogFactory.java
+++ b/jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4JLogFactory.java
@@ -42,7 +42,7 @@ import java.util.concurrent.ConcurrentMap;
*
* <p>
* This implementation ignores any configured attributes.
- * </p>
+ *
*
* @author Rod Waldhoff
* @author Craig R. McClanahan
@@ -64,7 +64,7 @@ public class SLF4JLogFactory extends LogFactory {
* Public no-arguments constructor required by the lookup mechanism.
*/
public SLF4JLogFactory() {
- loggerMap = new ConcurrentHashMap<String, Log>();
+ loggerMap = new ConcurrentHashMap<>();
}
// ----------------------------------------------------- Manifest Constants
@@ -105,12 +105,12 @@ public class SLF4JLogFactory extends LogFactory {
@SuppressWarnings("unchecked")
public String[] getAttributeNames() {
- List<String> names = new ArrayList<String>();
+ List<String> names = new ArrayList<>();
Enumeration<String> keys = attributes.keys();
while (keys.hasMoreElements()) {
names.add((String) keys.nextElement());
}
- String results[] = new String[names.size()];
+ String[] results = new String[names.size()];
for (int i = 0; i < results.length; i++) {
results[i] = (String) names.get(i);
}
@@ -136,7 +136,7 @@ public class SLF4JLogFactory extends LogFactory {
* <p>
* Construct (if necessary) and return a <code>Log</code> instance, using
* the factory's current set of configuration attributes.
- * </p>
+ *
*
* @param name
* Logical name of the <code>Log</code> instance to be returned
@@ -173,12 +173,10 @@ public class SLF4JLogFactory extends LogFactory {
public void release() {
// This method is never called by jcl-over-slf4j classes. However,
// in certain deployment scenarios, in particular if jcl-over-slf4j.jar
- // is
- // in the the web-app class loader and the official commons-logging.jar is
- // deployed in some parent class loader (e.g. commons/lib), then it is
- // possible
- // for the parent class loader to mask the classes shipping in
- // jcl-over-slf4j.jar.
+ // is in the web-app class loader and the official commons-logging.jar
+ // is deployed in some parent class loader (e.g. commons/lib), then it
+ // is possible for the parent class loader to mask the classes shipping
+ // in jcl-over-slf4j.jar.
System.out.println("WARN: The method " + SLF4JLogFactory.class + "#release() was invoked.");
System.out.println("WARN: Please see http://www.slf4j.org/codes.html#release for an explanation.");
System.out.flush();
@@ -216,4 +214,4 @@ public class SLF4JLogFactory extends LogFactory {
}
}
-} \ No newline at end of file
+}
diff --git a/jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/SimpleLog.java b/jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/SimpleLog.java
index 46b5d70e..e8223af6 100644
--- a/jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/SimpleLog.java
+++ b/jcl-over-slf4j/src/main/java/org/apache/commons/logging/impl/SimpleLog.java
@@ -35,7 +35,7 @@ import org.apache.commons.logging.LogConfigurationException;
* Simple implementation of Log that sends all enabled log messages, for all
* defined loggers, to System.err. The following system properties are supported
* to configure the behavior of this logger:
- * </p>
+ *
* <ul>
* <li><code>org.apache.commons.logging.simplelog.defaultlog</code> - Default
* logging detail level for all instances of SimpleLog. Must be one of ("trace",
@@ -67,7 +67,7 @@ import org.apache.commons.logging.LogConfigurationException;
* this implementation also checks for a class loader resource named
* <code>"simplelog.properties"</code>, and includes any matching definitions
* from this resource (if it exists).
- * </p>
+ *
*
* @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
* @author Rod Waldhoff
@@ -87,7 +87,7 @@ public class SimpleLog implements Log, Serializable {
/** Properties loaded from simplelog.properties */
static protected final Properties simpleLogProps = new Properties();
- /** The default format to use when formating dates */
+ /** The default format to use when formatting dates */
static protected final String DEFAULT_DATE_TIME_FORMAT = "yyyy/MM/dd HH:mm:ss:SSS zzz";
/** Include the instance name in the log message? */
@@ -157,9 +157,14 @@ public class SimpleLog implements Log, Serializable {
if (null != in) {
try {
simpleLogProps.load(in);
- in.close();
} catch (java.io.IOException e) {
// ignored
+ } finally {
+ try {
+ in.close();
+ } catch (java.io.IOException e) {
+ // ignored
+ }
}
}
@@ -243,7 +248,7 @@ public class SimpleLog implements Log, Serializable {
/**
* <p>
* Set logging level.
- * </p>
+ *
*
* @param currentLogLevel
* new logging level
@@ -257,7 +262,7 @@ public class SimpleLog implements Log, Serializable {
/**
* <p>
* Get logging level.
- * </p>
+ *
*/
public int getLevel() {
@@ -270,7 +275,7 @@ public class SimpleLog implements Log, Serializable {
* <p>
* Do the actual logging. This method assembles the message and then calls
* <code>write()</code> to cause it to be written.
- * </p>
+ *
*
* @param type
* One of the LOG_LEVEL_XXX constants defining the log level
@@ -349,7 +354,7 @@ public class SimpleLog implements Log, Serializable {
* Write the content of the message accumulated in the specified
* <code>StringBuffer</code> to the appropriate output destination. The
* default implementation writes to <code>System.err</code>.
- * </p>
+ *
*
* @param buffer
* A <code>StringBuffer</code> containing the accumulated text to be
@@ -378,7 +383,7 @@ public class SimpleLog implements Log, Serializable {
/**
* <p>
* Log a message with debug log level.
- * </p>
+ *
*/
public final void debug(Object message) {
@@ -390,7 +395,7 @@ public class SimpleLog implements Log, Serializable {
/**
* <p>
* Log an error with debug log level.
- * </p>
+ *
*/
public final void debug(Object message, Throwable t) {
@@ -402,7 +407,7 @@ public class SimpleLog implements Log, Serializable {
/**
* <p>
* Log a message with trace log level.
- * </p>
+ *
*/
public final void trace(Object message) {
@@ -414,7 +419,7 @@ public class SimpleLog implements Log, Serializable {
/**
* <p>
* Log an error with trace log level.
- * </p>
+ *
*/
public final void trace(Object message, Throwable t) {
@@ -426,7 +431,7 @@ public class SimpleLog implements Log, Serializable {
/**
* <p>
* Log a message with info log level.
- * </p>
+ *
*/
public final void info(Object message) {
@@ -438,7 +443,7 @@ public class SimpleLog implements Log, Serializable {
/**
* <p>
* Log an error with info log level.
- * </p>
+ *
*/
public final void info(Object message, Throwable t) {
@@ -450,7 +455,7 @@ public class SimpleLog implements Log, Serializable {
/**
* <p>
* Log a message with warn log level.
- * </p>
+ *
*/
public final void warn(Object message) {
@@ -462,7 +467,7 @@ public class SimpleLog implements Log, Serializable {
/**
* <p>
* Log an error with warn log level.
- * </p>
+ *
*/
public final void warn(Object message, Throwable t) {
@@ -474,7 +479,7 @@ public class SimpleLog implements Log, Serializable {
/**
* <p>
* Log a message with error log level.
- * </p>
+ *
*/
public final void error(Object message) {
@@ -486,7 +491,7 @@ public class SimpleLog implements Log, Serializable {
/**
* <p>
* Log an error with error log level.
- * </p>
+ *
*/
public final void error(Object message, Throwable t) {
@@ -498,7 +503,7 @@ public class SimpleLog implements Log, Serializable {
/**
* <p>
* Log a message with fatal log level.
- * </p>
+ *
*/
public final void fatal(Object message) {
@@ -510,7 +515,7 @@ public class SimpleLog implements Log, Serializable {
/**
* <p>
* Log an error with fatal log level.
- * </p>
+ *
*/
public final void fatal(Object message, Throwable t) {
@@ -522,12 +527,12 @@ public class SimpleLog implements Log, Serializable {
/**
* <p>
* Are debug messages currently enabled?
- * </p>
+ *
*
* <p>
* This allows expensive operations such as <code>String</code> concatenation
* to be avoided when the message will be ignored by the logger.
- * </p>
+ *
*/
public final boolean isDebugEnabled() {
@@ -537,12 +542,12 @@ public class SimpleLog implements Log, Serializable {
/**
* <p>
* Are error messages currently enabled?
- * </p>
+ *
*
* <p>
* This allows expensive operations such as <code>String</code> concatenation
* to be avoided when the message will be ignored by the logger.
- * </p>
+ *
*/
public final boolean isErrorEnabled() {
@@ -552,12 +557,12 @@ public class SimpleLog implements Log, Serializable {
/**
* <p>
* Are fatal messages currently enabled?
- * </p>
+ *
*
* <p>
* This allows expensive operations such as <code>String</code> concatenation
* to be avoided when the message will be ignored by the logger.
- * </p>
+ *
*/
public final boolean isFatalEnabled() {
@@ -567,12 +572,12 @@ public class SimpleLog implements Log, Serializable {
/**
* <p>
* Are info messages currently enabled?
- * </p>
+ *
*
* <p>
* This allows expensive operations such as <code>String</code> concatenation
* to be avoided when the message will be ignored by the logger.
- * </p>
+ *
*/
public final boolean isInfoEnabled() {
@@ -582,12 +587,12 @@ public class SimpleLog implements Log, Serializable {
/**
* <p>
* Are trace messages currently enabled?
- * </p>
+ *
*
* <p>
* This allows expensive operations such as <code>String</code> concatenation
* to be avoided when the message will be ignored by the logger.
- * </p>
+ *
*/
public final boolean isTraceEnabled() {
@@ -597,12 +602,12 @@ public class SimpleLog implements Log, Serializable {
/**
* <p>
* Are warn messages currently enabled?
- * </p>
+ *
*
* <p>
* This allows expensive operations such as <code>String</code> concatenation
* to be avoided when the message will be ignored by the logger.
- * </p>
+ *
*/
public final boolean isWarnEnabled() {
@@ -668,15 +673,13 @@ public class SimpleLog implements Log, Serializable {
}
private static InputStream getResourceAsStream(final String name) {
- return AccessController.doPrivileged(new PrivilegedAction<InputStream>() {
- public InputStream run() {
- ClassLoader threadCL = getContextClassLoader();
-
- if (threadCL != null) {
- return threadCL.getResourceAsStream(name);
- } else {
- return ClassLoader.getSystemResourceAsStream(name);
- }
+ return AccessController.doPrivileged((PrivilegedAction<InputStream>) () -> {
+ ClassLoader threadCL = getContextClassLoader();
+
+ if (threadCL != null) {
+ return threadCL.getResourceAsStream(name);
+ } else {
+ return ClassLoader.getSystemResourceAsStream(name);
}
});
}
diff --git a/jcl-over-slf4j/src/main/java/org/apache/commons/logging/package.html b/jcl-over-slf4j/src/main/java/org/apache/commons/logging/package.html
index 014e85a6..26f3fe6c 100755
--- a/jcl-over-slf4j/src/main/java/org/apache/commons/logging/package.html
+++ b/jcl-over-slf4j/src/main/java/org/apache/commons/logging/package.html
@@ -31,7 +31,7 @@ replacement for the original JCL version 1.0.4.
<p>As the original JCL version 1.0.4, the present version supports
various logging APIs. It differs from the original in implementation
but not the public API. This implementation uses SLF4J under the
-covers. As as such, all the logging systems that SLF4J supports,
+covers. As such, all the logging systems that SLF4J supports,
e.g. NOP, Simple, JDK14, nlog4j are supported by this version of JCL.
</p>
diff --git a/jcl-over-slf4j/src/main/java9/module-info.java b/jcl-over-slf4j/src/main/java9/module-info.java
new file mode 100755
index 00000000..8c33c164
--- /dev/null
+++ b/jcl-over-slf4j/src/main/java9/module-info.java
@@ -0,0 +1,4 @@
+module org.apache.commons.logging {
+ requires org.slf4j;
+ exports org.apache.commons.logging;
+}
diff --git a/jcl-over-slf4j/src/main/resources/META-INF/MANIFEST.MF b/jcl-over-slf4j/src/main/resources/META-INF/MANIFEST.MF
deleted file mode 100644
index d5233ea3..00000000
--- a/jcl-over-slf4j/src/main/resources/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,9 +0,0 @@
-Implementation-Title: jcl-over-slf4j
-Bundle-ManifestVersion: 2
-Bundle-SymbolicName: jcl.over.slf4j
-Bundle-Name: jcl-over-slf4j
-Bundle-Vendor: SLF4J.ORG
-Bundle-RequiredExecutionEnvironment: J2SE-1.5
-Export-Package: org.apache.commons.logging;version=1.1.1,
- org.apache.commons.logging.impl;version=1.1.1
-Import-Package: org.slf4j;version=${parsedVersion.osgiVersion}, org.slf4j.spi;version=${parsedVersion.osgiVersion}
diff --git a/jcl-over-slf4j/src/test/java/org/apache/commons/logging/InvokeJCLTest.java b/jcl-over-slf4j/src/test/java/org/apache/commons/logging/test/InvokeJCLTest.java
index ef5d23cb..931ed8ba 100644
--- a/jcl-over-slf4j/src/test/java/org/apache/commons/logging/InvokeJCLTest.java
+++ b/jcl-over-slf4j/src/test/java/org/apache/commons/logging/test/InvokeJCLTest.java
@@ -23,12 +23,20 @@
*
*/
-package org.apache.commons.logging;
+package org.apache.commons.logging.test;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
-public class InvokeJCLTest extends TestCase {
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.Test;
+
+public class InvokeJCLTest {
+
+ @Test
public void testIsEnabledAPI() {
// assume that we are running over slf4j-jdk14
Log log = LogFactory.getLog(InvokeJCLTest.class);
@@ -40,6 +48,7 @@ public class InvokeJCLTest extends TestCase {
assertTrue(log.isFatalEnabled());
}
+ @Test
public void testPrintAPI() {
Log log = LogFactory.getLog(InvokeJCLTest.class);
Exception e = new Exception("just testing");
@@ -80,4 +89,58 @@ public class InvokeJCLTest extends TestCase {
log.fatal(null, e);
log.fatal("fatal message", e);
}
+
+ @Test
+ public void testAvoidConvertingObjectToString() {
+ Log log = LogFactory.getLog(InvokeJCLTest.class);
+ Exception e = new Exception("just testing");
+
+ TestMessage fatalMsg = new TestMessage("fatal msg");
+ TestMessage errorMsg = new TestMessage("error msg");
+ TestMessage warnMsg = new TestMessage("warn msg");
+ TestMessage infoMsg = new TestMessage("info msg");
+ TestMessage debugMsg = new TestMessage("debug msg");
+ TestMessage traceMsg = new TestMessage("trace msg");
+
+ log.fatal(fatalMsg);
+ log.fatal(fatalMsg, e);
+ assertEquals(2, fatalMsg.invokedCount);
+
+ log.error(errorMsg);
+ log.error(errorMsg, e);
+ assertEquals(2, errorMsg.invokedCount);
+
+ log.warn(warnMsg);
+ log.warn(warnMsg, e);
+ assertEquals(2, warnMsg.invokedCount);
+
+ log.info(infoMsg);
+ log.info(infoMsg, e);
+ assertEquals(2, infoMsg.invokedCount);
+
+ log.debug(debugMsg);
+ log.debug(debugMsg, e);
+ assertEquals(0, debugMsg.invokedCount);
+
+ log.trace(traceMsg);
+ log.trace(traceMsg, e);
+ assertEquals(0, traceMsg.invokedCount);
+ }
+
+ static class TestMessage {
+
+ private final String msg;
+ int invokedCount = 0;
+
+ TestMessage(String msg) {
+ this.msg = msg;
+ }
+
+ @Override
+ public String toString() {
+ invokedCount++;
+ return msg;
+ }
+ }
+
}
diff --git a/jcl-over-slf4j/src/test/java/org/apache/commons/logging/impl/SerializationTest.java b/jcl-over-slf4j/src/test/java/org/apache/commons/logging/test/SerializationTest.java
index 017d6b84..3ca0b9ac 100644
--- a/jcl-over-slf4j/src/test/java/org/apache/commons/logging/impl/SerializationTest.java
+++ b/jcl-over-slf4j/src/test/java/org/apache/commons/logging/test/SerializationTest.java
@@ -22,7 +22,7 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.apache.commons.logging.impl;
+package org.apache.commons.logging.test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -30,30 +30,29 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
-import junit.framework.TestCase;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.slf4j.impl.JDK14LoggerFactory;
+import org.apache.commons.logging.impl.SLF4JLocationAwareLog;
+import org.apache.commons.logging.impl.SLF4JLog;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.jul.JDK14LoggerFactory;
import org.slf4j.spi.LocationAwareLogger;
-public class SerializationTest extends TestCase {
+public class SerializationTest {
ObjectInputStream ois;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos;
- public SerializationTest(String name) {
- super(name);
- }
-
- protected void setUp() throws Exception {
+ @Before
+ public void setUp() throws Exception {
oos = new ObjectOutputStream(baos);
- super.setUp();
}
- protected void tearDown() throws Exception {
- super.tearDown();
+ @After
+ public void tearDown() throws Exception {
oos.close();
}
@@ -67,6 +66,7 @@ public class SerializationTest extends TestCase {
resuscitatedLog.isDebugEnabled();
}
+ @Test
public void testSLF4JLog() throws Exception {
JDK14LoggerFactory factory = new JDK14LoggerFactory();
SLF4JLog log = new SLF4JLog(factory.getLogger("x"));
@@ -74,12 +74,14 @@ public class SerializationTest extends TestCase {
verify();
}
+ @Test
public void testSmoke() throws Exception {
Log log = LogFactory.getLog("testing");
oos.writeObject(log);
verify();
}
+ @Test
public void testLocationAware() throws Exception {
JDK14LoggerFactory factory = new JDK14LoggerFactory();
SLF4JLocationAwareLog log = new SLF4JLocationAwareLog((LocationAwareLogger) factory.getLogger("x"));
diff --git a/slf4j-android/LICENSE.txt b/jul-to-slf4j/LICENSE.txt
index 361d2ce0..1a3d0532 100644
--- a/slf4j-android/LICENSE.txt
+++ b/jul-to-slf4j/LICENSE.txt
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2013 QOS.ch
+Copyright (c) 2004-2022 QOS.ch Sarl (Switzerland)
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/jul-to-slf4j/pom.xml b/jul-to-slf4j/pom.xml
index 4c5476c5..89640acb 100755
--- a/jul-to-slf4j/pom.xml
+++ b/jul-to-slf4j/pom.xml
@@ -1,14 +1,14 @@
-<project
- xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
- <version>1.7.13-SNAPSHOT</version>
+ <version>2.0.12</version>
+ <relativePath>../parent/pom.xml</relativePath>
</parent>
<artifactId>jul-to-slf4j</artifactId>
@@ -26,7 +26,7 @@
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
+ <artifactId>slf4j-reload4j</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
@@ -34,31 +34,7 @@
<build>
<plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <source>${required.jdk.version}</source>
- <target>${required.jdk.version}</target>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <archive>
- <manifestEntries>
- <Bundle-Version>${parsedVersion.osgiVersion}</Bundle-Version>
- <Bundle-Description>${project.description}</Bundle-Description>
- <Implementation-Version>${project.version}
- </Implementation-Version>
- </manifestEntries>
- <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
- </archive>
- </configuration>
- </plugin>
-
</plugins>
</build>
-</project> \ No newline at end of file
+</project>
diff --git a/jul-to-slf4j/src/main/java/org/slf4j/bridge/SLF4JBridgeHandler.java b/jul-to-slf4j/src/main/java/org/slf4j/bridge/SLF4JBridgeHandler.java
index 72576a03..74adedcf 100755
--- a/jul-to-slf4j/src/main/java/org/slf4j/bridge/SLF4JBridgeHandler.java
+++ b/jul-to-slf4j/src/main/java/org/slf4j/bridge/SLF4JBridgeHandler.java
@@ -36,15 +36,15 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.spi.LocationAwareLogger;
-// Based on http://bugzilla.slf4j.org/show_bug.cgi?id=38
+// Based on http://jira.qos.ch/browse/SLF4J-30
/**
- * <p>Bridge/route all JUL log records to the SLF4J API.</p>
+ * <p>Bridge/route all JUL log records to the SLF4J API.
* <p>Essentially, the idea is to install on the root logger an instance of
* <code>SLF4JBridgeHandler</code> as the sole JUL handler in the system. Subsequently, the
* SLF4JBridgeHandler instance will redirect all JUL log records are redirected
* to the SLF4J API based on the following mapping of levels:
- * </p>
+ *
* <pre>
* FINEST -&gt; TRACE
* FINER -&gt; DEBUG
@@ -52,7 +52,7 @@ import org.slf4j.spi.LocationAwareLogger;
* INFO -&gt; INFO
* WARNING -&gt; WARN
* SEVERE -&gt; ERROR</pre>
- * <p><b>Programmatic installation:</b></p>
+ * <p><b>Programmatic installation:</b>
* <pre>
* // Optionally remove existing handlers attached to j.u.l root logger
* SLF4JBridgeHandler.removeHandlersForRootLogger(); // (since SLF4J 1.6.5)
@@ -60,12 +60,12 @@ import org.slf4j.spi.LocationAwareLogger;
* // add SLF4JBridgeHandler to j.u.l's root logger, should be done once during
* // the initialization phase of your application
* SLF4JBridgeHandler.install();</pre>
- * <p><b>Installation via <em>logging.properties</em> configuration file:</b></p>
+ * <p><b>Installation via <em>logging.properties</em> configuration file:</b>
* <pre>
* // register SLF4JBridgeHandler as handler for the j.u.l. root logger
* handlers = org.slf4j.bridge.SLF4JBridgeHandler</pre>
* <p>Once SLF4JBridgeHandler is installed, logging by j.u.l. loggers will be directed to
- * SLF4J. Example: </p>
+ * SLF4J. Example:
* <pre>
* import java.util.logging.Logger;
* ...
@@ -79,17 +79,26 @@ import org.slf4j.spi.LocationAwareLogger;
* SLF4J translation can seriously increase the cost of disabled logging
* statements (60 fold or 6000% increase) and measurably impact the performance of enabled log
* statements (20% overall increase).</b> Please note that as of logback-version 0.9.25,
- * it is possible to completely eliminate the 60 fold translation overhead for disabled
+ * it is possible to completely eliminate the 60-fold translation overhead for disabled
* log statements with the help of <a href="http://logback.qos.ch/manual/configuration.html#LevelChangePropagator">LevelChangePropagator</a>.
- * </p>
+ *
*
* <p>If you are concerned about application performance, then use of <code>SLF4JBridgeHandler</code>
- * is appropriate only if any one the following two conditions is true:</p>
+ * is appropriate only if any of the following conditions is true:
* <ol>
* <li>few j.u.l. logging statements are in play</li>
* <li>LevelChangePropagator has been installed</li>
* </ol>
*
+ * <h2>As a Java 9/Jigsaw module</h2>
+ *
+ * <p>Given that <b>to</b> is a reserved keyword under Java 9 within module productions,
+ * the MANIFEST.MF file in <em>jul-to-slf4j.jar</em> declares <b>jul_to_slf4j</b> as
+ * its Automatic Module Name. Thus, if your application is Jigsaw modularized, the requires
+ * statement in your <em>module-info.java</em> needs to be <b>jul_to_slf4j</b>
+ * (note the two underscores).
+ *
+ *
* @author Christian Stein
* @author Joern Huxhorn
* @author Ceki G&uuml;lc&uuml;
@@ -109,9 +118,8 @@ public class SLF4JBridgeHandler extends Handler {
/**
* Adds a SLF4JBridgeHandler instance to jul's root logger.
- * <p/>
- * <p/>
- * This handler will redirect j.u.l. logging to SLF4J. However, only logs enabled
+ *
+ * <p>This handler will redirect j.u.l. logging to SLF4J. However, only logs enabled
* in j.u.l. will be redirected. For example, if a log statement invoking a
* j.u.l. logger is disabled, then the corresponding non-event will <em>not</em>
* reach SLF4JBridgeHandler and cannot be redirected.
@@ -135,9 +143,9 @@ public class SLF4JBridgeHandler extends Handler {
public static void uninstall() throws SecurityException {
java.util.logging.Logger rootLogger = getRootLogger();
Handler[] handlers = rootLogger.getHandlers();
- for (int i = 0; i < handlers.length; i++) {
- if (handlers[i] instanceof SLF4JBridgeHandler) {
- rootLogger.removeHandler(handlers[i]);
+ for (Handler handler : handlers) {
+ if (handler instanceof SLF4JBridgeHandler) {
+ rootLogger.removeHandler(handler);
}
}
}
@@ -145,14 +153,14 @@ public class SLF4JBridgeHandler extends Handler {
/**
* Returns true if SLF4JBridgeHandler has been previously installed, returns false otherwise.
*
- * @return true if SLF4JBridgeHandler is already installed, false other wise
- * @throws SecurityException
+ * @return true if SLF4JBridgeHandler is already installed, false otherwise
+ *
*/
- public static boolean isInstalled() throws SecurityException {
+ public static boolean isInstalled() {
java.util.logging.Logger rootLogger = getRootLogger();
Handler[] handlers = rootLogger.getHandlers();
- for (int i = 0; i < handlers.length; i++) {
- if (handlers[i] instanceof SLF4JBridgeHandler) {
+ for (Handler handler : handlers) {
+ if (handler instanceof SLF4JBridgeHandler) {
return true;
}
}
@@ -166,8 +174,8 @@ public class SLF4JBridgeHandler extends Handler {
public static void removeHandlersForRootLogger() {
java.util.logging.Logger rootLogger = getRootLogger();
java.util.logging.Handler[] handlers = rootLogger.getHandlers();
- for (int i = 0; i < handlers.length; i++) {
- rootLogger.removeHandler(handlers[i]);
+ for (Handler handler : handlers) {
+ rootLogger.removeHandler(handler);
}
}
@@ -193,6 +201,9 @@ public class SLF4JBridgeHandler extends Handler {
/**
* Return the Logger instance that will be used for logging.
+ *
+ * @param record a LogRecord
+ * @return an SLF4J logger corresponding to the record parameter's logger name
*/
protected Logger getSLF4JLogger(LogRecord record) {
String name = record.getLoggerName();
@@ -259,19 +270,25 @@ public class SLF4JBridgeHandler extends Handler {
}
Object[] params = record.getParameters();
// avoid formatting when there are no or 0 parameters. see also
- // http://bugzilla.slf4j.org/show_bug.cgi?id=212
+ // http://jira.qos.ch/browse/SLF4J-203
if (params != null && params.length > 0) {
- message = MessageFormat.format(message, params);
+ try {
+ message = MessageFormat.format(message, params);
+ } catch (IllegalArgumentException e) {
+ // default to the same behavior as in java.util.logging.Formatter.formatMessage(LogRecord)
+ // see also http://jira.qos.ch/browse/SLF4J-337
+ return message;
+ }
}
return message;
}
/**
* Publish a LogRecord.
- * <p/>
+ * <p>
* The logging request was made initially to a Logger object, which
* initialized the LogRecord and forwarded it here.
- * <p/>
+ * <p>
* This handler ignores the Level attached to the LogRecord, as SLF4J cares
* about discarding log statements.
*
@@ -285,13 +302,12 @@ public class SLF4JBridgeHandler extends Handler {
}
Logger slf4jLogger = getSLF4JLogger(record);
- String message = record.getMessage(); // can be null!
// this is a check to avoid calling the underlying logging system
// with a null message. While it is legitimate to invoke j.u.l. with
// a null message, other logging frameworks do not support this.
- // see also http://bugzilla.slf4j.org/show_bug.cgi?id=108
- if (message == null) {
- message = "";
+ // see also http://jira.qos.ch/browse/SLF4J-99
+ if (record.getMessage() == null) {
+ record.setMessage("");
}
if (slf4jLogger instanceof LocationAwareLogger) {
callLocationAwareLogger((LocationAwareLogger) slf4jLogger, record);
diff --git a/jul-to-slf4j/src/main/java/org/slf4j/bridge/package.html b/jul-to-slf4j/src/main/java/org/slf4j/bridge/package.html
index 2b643c31..30628238 100644
--- a/jul-to-slf4j/src/main/java/org/slf4j/bridge/package.html
+++ b/jul-to-slf4j/src/main/java/org/slf4j/bridge/package.html
@@ -10,6 +10,6 @@
<p>Bridge/route all JUL log records to the SLF4J API.</p>
- <hr/>
+ <hr>
</body>
</html>
diff --git a/jul-to-slf4j/src/main/java9/module-info.java b/jul-to-slf4j/src/main/java9/module-info.java
new file mode 100644
index 00000000..10d4f540
--- /dev/null
+++ b/jul-to-slf4j/src/main/java9/module-info.java
@@ -0,0 +1,7 @@
+module jul.to.slf4j {
+
+ requires org.slf4j;
+ requires java.logging;
+
+ exports org.slf4j.bridge;
+} \ No newline at end of file
diff --git a/jul-to-slf4j/src/main/resources/META-INF/MANIFEST.MF b/jul-to-slf4j/src/main/resources/META-INF/MANIFEST.MF
deleted file mode 100644
index e1ab4c0d..00000000
--- a/jul-to-slf4j/src/main/resources/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,7 +0,0 @@
-Bundle-ManifestVersion: 2
-Bundle-SymbolicName: jul.to.slf4j
-Bundle-Name: jul-to-slf4j
-Bundle-Vendor: SLF4J.ORG
-Bundle-RequiredExecutionEnvironment: J2SE-1.5
-Export-Package: org.slf4j.bridge;version=${parsedVersion.osgiVersion};uses:="org.slf4j,org.slf4j.spi"
-Import-Package: org.slf4j;version=${parsedVersion.osgiVersion},org.slf4j.spi;version=${parsedVersion.osgiVersion}
diff --git a/jul-to-slf4j/src/test/java/org/slf4j/bridge/ListAppender.java b/jul-to-slf4j/src/test/java/org/slf4j/bridge/ListAppender.java
index e5fb5f3b..41cc5d81 100644
--- a/jul-to-slf4j/src/test/java/org/slf4j/bridge/ListAppender.java
+++ b/jul-to-slf4j/src/test/java/org/slf4j/bridge/ListAppender.java
@@ -32,7 +32,7 @@ import org.apache.log4j.spi.LoggingEvent;
public class ListAppender extends AppenderSkeleton {
- public List<LoggingEvent> list = new ArrayList<LoggingEvent>();
+ public List<LoggingEvent> list = new ArrayList<>();
public boolean extractLocationInfo = false;
diff --git a/jul-to-slf4j/src/test/java/org/slf4j/bridge/SLF4JBridgeHandlerPerfTest.java b/jul-to-slf4j/src/test/java/org/slf4j/bridge/SLF4JBridgeHandlerPerfTest.java
index 17e2329e..2860aa70 100644
--- a/jul-to-slf4j/src/test/java/org/slf4j/bridge/SLF4JBridgeHandlerPerfTest.java
+++ b/jul-to-slf4j/src/test/java/org/slf4j/bridge/SLF4JBridgeHandlerPerfTest.java
@@ -27,13 +27,14 @@ package org.slf4j.bridge;
import java.util.logging.Handler;
import java.util.logging.LogManager;
-import junit.framework.TestCase;
-
import org.apache.log4j.FileAppender;
import org.apache.log4j.PatternLayout;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
import org.slf4j.LoggerFactory;
-public class SLF4JBridgeHandlerPerfTest extends TestCase {
+public class SLF4JBridgeHandlerPerfTest {
static String LOGGER_NAME = "yay";
static int RUN_LENGTH = 100 * 1000;
@@ -50,29 +51,25 @@ public class SLF4JBridgeHandlerPerfTest extends TestCase {
Handler[] existingHandlers;
- public SLF4JBridgeHandlerPerfTest(String arg0) {
- super(arg0);
- }
-
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() throws Exception {
fileAppender = new FileAppender(new PatternLayout("%r [%t] %p %c %x - %m%n"), "target/test-output/toto.log");
existingHandlers = julRootLogger.getHandlers();
- for (int i = 0; i < existingHandlers.length; i++) {
- julRootLogger.removeHandler(existingHandlers[i]);
+ for (Handler existingHandler : existingHandlers) {
+ julRootLogger.removeHandler(existingHandler);
}
log4jRoot = org.apache.log4j.Logger.getRootLogger();
log4jRoot.addAppender(fileAppender);
}
- protected void tearDown() throws Exception {
- super.tearDown();
+ @After
+ public void tearDown() throws Exception {
SLF4JBridgeHandler.uninstall();
fileAppender.close();
log4jRoot.getLoggerRepository().resetConfiguration();
- for (int i = 0; i < existingHandlers.length; i++) {
- julRootLogger.addHandler(existingHandlers[i]);
+ for (Handler existingHandler : existingHandlers) {
+ julRootLogger.addHandler(existingHandler);
}
}
@@ -94,6 +91,7 @@ public class SLF4JBridgeHandlerPerfTest extends TestCase {
return (end - start) * 1.0 / RUN_LENGTH;
}
+ @Test
public void testPerf() {
SLF4JBridgeHandler.install();
diff --git a/jul-to-slf4j/src/test/java/org/slf4j/bridge/SLF4JBridgeHandlerTest.java b/jul-to-slf4j/src/test/java/org/slf4j/bridge/SLF4JBridgeHandlerTest.java
index a413cdbe..79ca53e0 100755
--- a/jul-to-slf4j/src/test/java/org/slf4j/bridge/SLF4JBridgeHandlerTest.java
+++ b/jul-to-slf4j/src/test/java/org/slf4j/bridge/SLF4JBridgeHandlerTest.java
@@ -24,43 +24,46 @@
*/
package org.slf4j.bridge;
+import static org.junit.Assert.assertEquals;
+
import java.text.MessageFormat;
import java.util.ResourceBundle;
import java.util.logging.Level;
-import junit.framework.TestCase;
-
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
-public class SLF4JBridgeHandlerTest extends TestCase {
+public class SLF4JBridgeHandlerTest {
static String LOGGER_NAME = "yay";
ListAppender listAppender = new ListAppender();
org.apache.log4j.Logger log4jRoot;
- java.util.logging.Logger julLogger = java.util.logging.Logger.getLogger("yay");
-
- public SLF4JBridgeHandlerTest(String arg0) {
- super(arg0);
- }
-
- protected void setUp() throws Exception {
- super.setUp();
+ java.util.logging.Logger julLogger = java.util.logging.Logger.getLogger(LOGGER_NAME);
+ java.util.logging.Logger julRootLogger = java.util.logging.Logger.getLogger("");
+
+ @Before
+ public void setUp() throws Exception {
listAppender.extractLocationInfo = true;
log4jRoot = org.apache.log4j.Logger.getRootLogger();
log4jRoot.addAppender(listAppender);
log4jRoot.setLevel(org.apache.log4j.Level.TRACE);
+ julRootLogger.setLevel(Level.FINEST);
}
- protected void tearDown() throws Exception {
- super.tearDown();
+ @After
+ public void tearDown() throws Exception {
SLF4JBridgeHandler.uninstall();
log4jRoot.getLoggerRepository().resetConfiguration();
}
+ @Test
public void testSmoke() {
SLF4JBridgeHandler.install();
+
String msg = "msg";
julLogger.info(msg);
assertEquals(1, listAppender.list.size());
@@ -77,7 +80,21 @@ public class SLF4JBridgeHandlerTest extends TestCase {
assertEquals("SLF4JBridgeHandlerTest.java", li.getFileName());
assertEquals("testSmoke", li.getMethodName());
}
+
+ @Test
+ public void LOGBACK_1612() {
+ SLF4JBridgeHandler.install();
+
+ String msg = "LOGBACK_1612";
+ julLogger.finer(msg);
+ assertEquals(1, listAppender.list.size());
+ LoggingEvent le = (LoggingEvent) listAppender.list.get(0);
+ assertEquals(LOGGER_NAME, le.getLoggerName());
+ assertEquals(msg, le.getMessage());
+
+ }
+ @Test
public void testLevels() {
SLF4JBridgeHandler.install();
String msg = "msg";
@@ -100,6 +117,9 @@ public class SLF4JBridgeHandlerTest extends TestCase {
assertLevel(i++, org.apache.log4j.Level.ERROR);
}
+
+
+ @Test
public void testLogWithResourceBundle() {
SLF4JBridgeHandler.install();
@@ -113,11 +133,12 @@ public class SLF4JBridgeHandlerTest extends TestCase {
julResourceBundleLogger.info(msg);
assertEquals(1, listAppender.list.size());
- LoggingEvent le = (LoggingEvent) listAppender.list.get(0);
+ LoggingEvent le = listAppender.list.get(0);
assertEquals(LOGGER_NAME, le.getLoggerName());
assertEquals(expectedMsg, le.getMessage());
}
+ @Test
public void testLogWithResourceBundleWithParameters() {
SLF4JBridgeHandler.install();
@@ -146,36 +167,60 @@ public class SLF4JBridgeHandlerTest extends TestCase {
LoggingEvent le = null;
- le = (LoggingEvent) listAppender.list.get(0);
+ le = listAppender.list.get(0);
assertEquals("foo", le.getLoggerName());
assertEquals(expectedMsg1, le.getMessage());
- le = (LoggingEvent) listAppender.list.get(1);
+ le = listAppender.list.get(1);
assertEquals("foo", le.getLoggerName());
assertEquals(expectedMsg2, le.getMessage());
- le = (LoggingEvent) listAppender.list.get(2);
+ le = listAppender.list.get(2);
assertEquals("foo", le.getLoggerName());
assertEquals(expectedMsg3, le.getMessage());
- le = (LoggingEvent) listAppender.list.get(3);
+ le = listAppender.list.get(3);
assertEquals("yay", le.getLoggerName());
assertEquals(expectedMsg3, le.getMessage());
}
+ @Test
public void testLogWithPlaceholderNoParameters() {
SLF4JBridgeHandler.install();
String msg = "msg {non-number-string}";
julLogger.logp(Level.INFO, "SLF4JBridgeHandlerTest", "testLogWithPlaceholderNoParameters", msg, new Object[0]);
assertEquals(1, listAppender.list.size());
- LoggingEvent le = (LoggingEvent) listAppender.list.get(0);
+ LoggingEvent le = listAppender.list.get(0);
assertEquals(LOGGER_NAME, le.getLoggerName());
assertEquals(msg, le.getMessage());
}
+ // See http://jira.qos.ch/browse/SLF4J-337
+
+ @Test
+ public void illFormattedInputShouldBeReturnedAsIs() {
+ SLF4JBridgeHandler.install();
+ String msg = "foo {18=bad} {0}";
+
+ julLogger.log(Level.INFO, msg, "ignored parameter due to IllegalArgumentException");
+ assertEquals(1, listAppender.list.size());
+ LoggingEvent le = listAppender.list.get(0);
+ assertEquals(msg, le.getMessage());
+ }
+
+ @Test
+ public void withNullMessage() {
+ SLF4JBridgeHandler.install();
+ String msg = null;
+ julLogger.log(Level.INFO, msg);
+ assertEquals(1, listAppender.list.size());
+ LoggingEvent le = listAppender.list.get(0);
+ assertEquals("", le.getMessage());
+ }
+
void assertLevel(int index, org.apache.log4j.Level expectedLevel) {
- LoggingEvent le = (LoggingEvent) listAppender.list.get(index);
+ LoggingEvent le = listAppender.list.get(index);
assertEquals(expectedLevel, le.getLevel());
}
}
diff --git a/log4j-over-slf4j/LICENSE.txt b/log4j-over-slf4j/LICENSE.txt
new file mode 100644
index 00000000..2bb9ad24
--- /dev/null
+++ b/log4j-over-slf4j/LICENSE.txt
@@ -0,0 +1,176 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS \ No newline at end of file
diff --git a/log4j-over-slf4j/compatibility/build.xml b/log4j-over-slf4j/compatibility/build.xml
index 5115a42a..b8136313 100644
--- a/log4j-over-slf4j/compatibility/build.xml
+++ b/log4j-over-slf4j/compatibility/build.xml
@@ -39,7 +39,7 @@
<!-- ================================================================= -->
<target name="usage">
<echo>
- These are some of the targets supported by this ANT build scpript:
+ These are some of the targets supported by this ANT build script:
all - run all available tests
refresh - copy required jar files to the lib directory
diff --git a/log4j-over-slf4j/compatibility/readme.txt b/log4j-over-slf4j/compatibility/readme.txt
index 6554cc63..86bbc820 100644
--- a/log4j-over-slf4j/compatibility/readme.txt
+++ b/log4j-over-slf4j/compatibility/readme.txt
@@ -5,7 +5,7 @@ that uses either log4j 1.2.x, or log4j 1.3.x.
In the same directory is a build.xml file that uses ant to
compile the test cases with the corresponding log4j version,
-and to runs these tests without log4j in the classpath but with
+and to run these tests without log4j in the classpath but with
logback jars instead.
To run the tests, one must have ant installed. Issuing the following command,
@@ -14,4 +14,4 @@ once in the compatibility directory will launch the tests:
ant all
To obtain more information about the use of the log4j-over-slf4j module,
-please visit http://www..slf4j.org/log4j-over-slf4j.html \ No newline at end of file
+please visit http://www.slf4j.org/log4j-over-slf4j.html
diff --git a/log4j-over-slf4j/pom.xml b/log4j-over-slf4j/pom.xml
index 6f6c0266..7823734f 100755
--- a/log4j-over-slf4j/pom.xml
+++ b/log4j-over-slf4j/pom.xml
@@ -1,5 +1,5 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
@@ -7,16 +7,17 @@
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
- <version>1.7.13-SNAPSHOT</version>
+ <version>2.0.12</version>
+ <relativePath>../parent/pom.xml</relativePath>
</parent>
- <artifactId>log4j-over-slf4j</artifactId>
- <packaging>jar</packaging>
- <name>Log4j Implemented Over SLF4J</name>
+ <artifactId>log4j-over-slf4j</artifactId>
+ <packaging>jar</packaging>
+ <name>Log4j Implemented Over SLF4J</name>
<description>Log4j implemented over SLF4J</description>
- <url>http://www.slf4j.org</url>
+ <url>http://www.slf4j.org</url>
<licenses>
<license>
@@ -25,39 +26,34 @@
</license>
</licenses>
+
+
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
- </dependency>
-
+ </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<scope>test</scope>
- </dependency>
+ </dependency>
</dependencies>
-
<build>
<plugins>
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
<configuration>
- <archive>
- <manifestEntries>
- <Bundle-Version>${parsedVersion.osgiVersion}</Bundle-Version>
- <Bundle-Description>${project.description}</Bundle-Description>
- <Implementation-Version>${project.version}</Implementation-Version>
- </manifestEntries>
- <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
- </archive>
- </configuration>
+ <instructions>
+ <_exportcontents>org.apache.log4j*;version=${reload4j.version};-noimport:=true</_exportcontents>
+ </instructions>
+ </configuration>
</plugin>
-
+
</plugins>
</build>
-</project> \ No newline at end of file
+</project>
diff --git a/log4j-over-slf4j/src/main/java/org/apache/log4j/Appender.java b/log4j-over-slf4j/src/main/java/org/apache/log4j/Appender.java
index 3df673fb..fcc09994 100644
--- a/log4j-over-slf4j/src/main/java/org/apache/log4j/Appender.java
+++ b/log4j-over-slf4j/src/main/java/org/apache/log4j/Appender.java
@@ -18,7 +18,6 @@ package org.apache.log4j;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.ErrorHandler;
-import org.apache.log4j.spi.Layout;
import org.apache.log4j.spi.LoggingEvent;
/**
@@ -55,7 +54,7 @@ public interface Appender {
/**
* Release any resources allocated within the appender such as file
* handles, network connections, etc.
- * <p/>
+ *
* <p>It is a programming error to append to a closed appender.
*
* @since 0.8.4
@@ -115,12 +114,12 @@ public interface Appender {
* Configurators call this method to determine if the appender
* requires a layout. If this method returns <code>true</code>,
* meaning that layout is required, then the configurator will
- * configure an layout using the configuration information at its
+ * configure a layout using the configuration information at its
* disposal. If this method returns <code>false</code>, meaning that
* a layout is not required, then layout configuration will be
* skipped even if there is available layout configuration
- * information at the disposal of the configurator..
- * <p/>
+ * information at the disposal of the configurator.
+ *
* <p>In the rather exceptional case, where the appender
* implementation admits a layout but can also work without it, then
* the appender should return <code>true</code>.
diff --git a/log4j-over-slf4j/src/main/java/org/apache/log4j/Category.java b/log4j-over-slf4j/src/main/java/org/apache/log4j/Category.java
index 0d29fbe9..ee4d7893 100644
--- a/log4j-over-slf4j/src/main/java/org/apache/log4j/Category.java
+++ b/log4j-over-slf4j/src/main/java/org/apache/log4j/Category.java
@@ -29,7 +29,7 @@ import java.util.Enumeration;
* This class is a minimal implementation of the original
* <code>org.apache.log4j.Category</code> class (as found in log4j 1.2) by
* delegation of all calls to a {@link org.slf4j.Logger} instance.
- * </p>
+ *
*
* <p>
* Log4j's <code>trace</code>, <code>debug()</code>, <code>info()</code>,
@@ -45,12 +45,12 @@ public class Category {
private static final String CATEGORY_FQCN = Category.class.getName();
- private String name;
+ private final String name;
protected org.slf4j.Logger slf4jLogger;
private org.slf4j.spi.LocationAwareLogger locationAwareLogger;
- private static Marker FATAL_MARKER = MarkerFactory.getMarker("FATAL");
+ private static final Marker FATAL_MARKER = MarkerFactory.getMarker("FATAL");
Category(String name) {
this.name = name;
@@ -125,6 +125,7 @@ public class Category {
/**
* @deprecated Please use {@link #getLevel} instead.
+ * @return a Level
*/
final public Level getPriority() {
return null;
@@ -132,6 +133,9 @@ public class Category {
/**
* Delegates to {@link org.slf4j.Logger#isDebugEnabled} method in SLF4J
+ *
+ * @return true if this logger is enabled for the level DEBUG
+ *
*/
public boolean isDebugEnabled() {
return slf4jLogger.isDebugEnabled();
@@ -139,13 +143,17 @@ public class Category {
/**
* Delegates to {@link org.slf4j.Logger#isInfoEnabled} method in SLF4J
+ *
+ * @return true if this logger is enabled for the level INFO
*/
public boolean isInfoEnabled() {
return slf4jLogger.isInfoEnabled();
}
/**
- * Delegates tob {@link org.slf4j.Logger#isWarnEnabled} method in SLF4J
+ * Delegates to {@link org.slf4j.Logger#isWarnEnabled} method in SLF4J
+ *
+ * @return true if this logger is enabled for the level WARN
*/
public boolean isWarnEnabled() {
return slf4jLogger.isWarnEnabled();
@@ -153,6 +161,8 @@ public class Category {
/**
* Delegates to {@link org.slf4j.Logger#isErrorEnabled} method in SLF4J
+ *
+ * @return true if this logger is enabled for the level ERROR
*/
public boolean isErrorEnabled() {
return slf4jLogger.isErrorEnabled();
@@ -160,13 +170,11 @@ public class Category {
/**
* Determines whether the priority passed as parameter is enabled in the
- * underlying SLF4J logger. Each log4j priority is mapped directly to its
- * SLF4J equivalent, except for FATAL which is mapped as ERROR.
+ * underlying SLF4J logger. Each log4j priority is mapped directly to its SLF4J
+ * equivalent, except for FATAL which is mapped as ERROR.
*
- * @param p
- * the priority to check against
- * @return true if this logger is enabled for the given level, false
- * otherwise.
+ * @param p the priority to check against
+ * @return true if this logger is enabled for the given level, false otherwise.
*/
public boolean isEnabledFor(Priority p) {
switch (p.level) {
@@ -194,19 +202,19 @@ public class Category {
} else {
switch (level) {
case LocationAwareLogger.TRACE_INT:
- slf4jLogger.trace(marker, m);
+ slf4jLogger.trace(marker, m, (Throwable) t);
break;
case LocationAwareLogger.DEBUG_INT:
- slf4jLogger.debug(marker, m);
+ slf4jLogger.debug(marker, m, (Throwable) t);
break;
case LocationAwareLogger.INFO_INT:
- slf4jLogger.info(marker, m);
+ slf4jLogger.info(marker, m, (Throwable) t);
break;
case LocationAwareLogger.WARN_INT:
- slf4jLogger.warn(marker, m);
+ slf4jLogger.warn(marker, m, (Throwable) t);
break;
case LocationAwareLogger.ERROR_INT:
- slf4jLogger.error(marker, m);
+ slf4jLogger.error(marker, m, (Throwable) t);
break;
}
}
@@ -214,6 +222,8 @@ public class Category {
/**
* Delegates to {@link org.slf4j.Logger#debug(String)} method of SLF4J.
+ *
+ * @param message a message to log
*/
public void debug(Object message) {
differentiatedLog(null, CATEGORY_FQCN, LocationAwareLogger.DEBUG_INT, message, null);
@@ -222,6 +232,9 @@ public class Category {
/**
* Delegates to {@link org.slf4j.Logger#debug(String,Throwable)} method in
* SLF4J.
+ *
+ * @param message a message to log
+ * @param t a throwable to log
*/
public void debug(Object message, Throwable t) {
differentiatedLog(null, CATEGORY_FQCN, LocationAwareLogger.DEBUG_INT, message, t);
@@ -229,14 +242,18 @@ public class Category {
/**
* Delegates to {@link org.slf4j.Logger#info(String)} method in SLF4J.
+ *
+ * @param message a message to log
*/
public void info(Object message) {
differentiatedLog(null, CATEGORY_FQCN, LocationAwareLogger.INFO_INT, message, null);
}
/**
- * Delegates to {@link org.slf4j.Logger#info(String,Throwable)} method in
- * SLF4J.
+ * Delegates to {@link org.slf4j.Logger#info(String,Throwable)} method in SLF4J.
+ *
+ * @param message a message to log
+ * @param t a throwable to log
*/
public void info(Object message, Throwable t) {
differentiatedLog(null, CATEGORY_FQCN, LocationAwareLogger.INFO_INT, message, t);
@@ -244,14 +261,20 @@ public class Category {
/**
* Delegates to {@link org.slf4j.Logger#warn(String)} method in SLF4J.
+ *
+ * @param message a message to log
+ *
*/
public void warn(Object message) {
differentiatedLog(null, CATEGORY_FQCN, LocationAwareLogger.WARN_INT, message, null);
}
/**
- * Delegates to {@link org.slf4j.Logger#warn(String,Throwable)} method in
- * SLF4J.
+ * Delegates to {@link org.slf4j.Logger#warn(String,Throwable)} method in SLF4J.
+ *
+ * @param message a message to log
+ * @param t a throwable to log
+ *
*/
public void warn(Object message, Throwable t) {
differentiatedLog(null, CATEGORY_FQCN, LocationAwareLogger.WARN_INT, message, t);
@@ -259,6 +282,9 @@ public class Category {
/**
* Delegates to {@link org.slf4j.Logger#error(String)} method in SLF4J.
+ *
+ * @param message a message to log
+ *
*/
public void error(Object message) {
differentiatedLog(null, CATEGORY_FQCN, LocationAwareLogger.ERROR_INT, message, null);
@@ -267,6 +293,10 @@ public class Category {
/**
* Delegates to {@link org.slf4j.Logger#error(String,Throwable)} method in
* SLF4J.
+ *
+ * @param message a message to log
+ * @param t a throwable to log
+ *
*/
public void error(Object message, Throwable t) {
differentiatedLog(null, CATEGORY_FQCN, LocationAwareLogger.ERROR_INT, message, t);
@@ -274,6 +304,9 @@ public class Category {
/**
* Delegates to {@link org.slf4j.Logger#error(String)} method in SLF4J.
+ *
+ * @param message a message to log
+ *
*/
public void fatal(Object message) {
differentiatedLog(FATAL_MARKER, CATEGORY_FQCN, LocationAwareLogger.ERROR_INT, message, null);
@@ -282,6 +315,10 @@ public class Category {
/**
* Delegates to {@link org.slf4j.Logger#error(String,Throwable)} method in
* SLF4J. In addition, the call is marked with a marker named "FATAL".
+ *
+ * @param message a message to log
+ * @param t a throwable to log
+ *
*/
public void fatal(Object message, Throwable t) {
differentiatedLog(FATAL_MARKER, CATEGORY_FQCN, LocationAwareLogger.ERROR_INT, message, t);
@@ -291,7 +328,7 @@ public class Category {
log(FQCN, p, msg, t);
}
- // See also http://bugzilla.slf4j.org/show_bug.cgi?id=168
+ // See also http://jira.qos.ch/browse/SLF4J-159
public void log(String FQCN, Priority p, Object msg, Throwable t) {
int levelInt = priorityToLevelInt(p);
differentiatedLog(null, FQCN, levelInt, msg, t);
@@ -347,4 +384,13 @@ public class Category {
// nothing to do
}
+ public boolean getAdditivity() {
+ return false;
+ }
+
+ public void assertLog(boolean assertion, String msg) {
+ if (!assertion)
+ error(msg);
+ }
+
}
diff --git a/log4j-over-slf4j/src/main/java/org/apache/log4j/ConsoleAppender.java b/log4j-over-slf4j/src/main/java/org/apache/log4j/ConsoleAppender.java
index 40e8f800..c1935074 100644
--- a/log4j-over-slf4j/src/main/java/org/apache/log4j/ConsoleAppender.java
+++ b/log4j-over-slf4j/src/main/java/org/apache/log4j/ConsoleAppender.java
@@ -15,6 +15,18 @@
*/
package org.apache.log4j;
+/**
+ * Skeleton implementation of ConsoleAppender
+ */
public class ConsoleAppender extends WriterAppender {
+ public ConsoleAppender() {
+ }
+
+ public ConsoleAppender(Layout layout) {
+ }
+
+ public ConsoleAppender(Layout layout, String target) {
+ }
+
}
diff --git a/log4j-over-slf4j/src/main/java/org/apache/log4j/Layout.java b/log4j-over-slf4j/src/main/java/org/apache/log4j/Layout.java
index 4ea3d990..1f4ef945 100644
--- a/log4j-over-slf4j/src/main/java/org/apache/log4j/Layout.java
+++ b/log4j-over-slf4j/src/main/java/org/apache/log4j/Layout.java
@@ -20,7 +20,7 @@ package org.apache.log4j;
/**
* This class is a minimal implementation of the original Log4J class.
*
- * @author Christian Trutz <christian.trutz@belaso.de>
+ * @author Christian Trutz
* */
public class Layout {
diff --git a/log4j-over-slf4j/src/main/java/org/apache/log4j/Level.java b/log4j-over-slf4j/src/main/java/org/apache/log4j/Level.java
index 62ef578e..ddadbea0 100644
--- a/log4j-over-slf4j/src/main/java/org/apache/log4j/Level.java
+++ b/log4j-over-slf4j/src/main/java/org/apache/log4j/Level.java
@@ -26,21 +26,21 @@ import java.io.ObjectStreamException;
import java.io.Serializable;
/**
- Defines the minimum set of levels recognized by the system, that is
- <code>OFF</code>, <code>FATAL</code>, <code>ERROR</code>,
- <code>WARN</code>, <code>INFO</code>, <code>DEBUG</code> and
- <code>ALL</code>.
-
- <p>The <code>Level</code> class may be subclassed to define a larger
- level set.
-
- @author Ceki G&uuml;lc&uuml;
-
+ * Defines the minimum set of levels recognized by the system, that is
+ * <code>OFF</code>, <code>FATAL</code>, <code>ERROR</code>, <code>WARN</code>,
+ * <code>INFO</code>, <code>DEBUG</code> and <code>ALL</code>.
+ *
+ * <p>
+ * The <code>Level</code> class may be subclassed to define a larger level set.
+ *
+ * @author Ceki G&uuml;lc&uuml;
+ *
*/
public class Level extends Priority implements Serializable {
/**
* TRACE level integer value.
+ *
* @since 1.2.12
*/
public static final int TRACE_INT = 5000;
@@ -49,48 +49,52 @@ public class Level extends Priority implements Serializable {
public static final int X_TRACE_INT = DEBUG_INT - 100;
/**
- The <code>OFF</code> has the highest possible rank and is
- intended to turn off logging. */
+ * The <code>OFF</code> has the highest possible rank and is intended to turn
+ * off logging.
+ */
final static public Level OFF = new Level(OFF_INT, "OFF", 0);
/**
- The <code>FATAL</code> level designates very severe error
- events that will presumably lead the application to abort.
+ * The <code>FATAL</code> level designates very severe error events that will
+ * presumably lead the application to abort.
*/
final static public Level FATAL = new Level(FATAL_INT, "FATAL", 0);
/**
- The <code>ERROR</code> level designates error events that
- might still allow the application to continue running. */
+ * The <code>ERROR</code> level designates error events that might still allow
+ * the application to continue running.
+ */
final static public Level ERROR = new Level(ERROR_INT, "ERROR", 3);
/**
- The <code>WARN</code> level designates potentially harmful situations.
- */
+ * The <code>WARN</code> level designates potentially harmful situations.
+ */
final static public Level WARN = new Level(WARN_INT, "WARN", 4);
/**
- The <code>INFO</code> level designates informational messages
- that highlight the progress of the application at coarse-grained
- level. */
+ * The <code>INFO</code> level designates informational messages that highlight
+ * the progress of the application at coarse-grained level.
+ */
final static public Level INFO = new Level(INFO_INT, "INFO", 6);
/**
- The <code>DEBUG</code> Level designates fine-grained
- informational events that are most useful to debug an
- application. */
+ * The <code>DEBUG</code> Level designates fine-grained informational events
+ * that are most useful to debug an application.
+ */
final static public Level DEBUG = new Level(DEBUG_INT, "DEBUG", 7);
/**
- * The <code>TRACE</code> Level designates finer-grained
- * informational events than the <code>DEBUG</code level.
- * @since 1.2.12
- */
+ * The <code>TRACE</code> Level designates finer-grained informational events
+ * than the <code>DEBUG</code> level.
+ *
+ * @since 1.2.12
+ */
public static final Level TRACE = new Level(TRACE_INT, "TRACE", 7);
/**
- The <code>ALL</code> has the lowest possible rank and is intended to
- turn on all logging. */
+ * The <code>ALL</code> has the lowest possible rank and is intended to turn on
+ * all logging.
+ */
final static public Level ALL = new Level(ALL_INT, "ALL", 7);
/**
@@ -99,33 +103,47 @@ public class Level extends Priority implements Serializable {
static final long serialVersionUID = 3491141966387921974L;
/**
- Instantiate a Level object.
+ * Instantiate a Level object.
+ *
+ * @param level a level
+ * @param levelStr a level string
+ * @param syslogEquivalent the Syslog equivalent
*/
protected Level(int level, String levelStr, int syslogEquivalent) {
super(level, levelStr, syslogEquivalent);
}
/**
- Convert the string passed as argument to a level. If the
- conversion fails, then this method returns {@link #DEBUG}.
- */
+ * Convert the string passed as argument to a level. If the conversion fails,
+ * then this method returns {@link #DEBUG}.
+ *
+ * @param sArg a string
+ * @return corresponding Level
+ *
+ */
public static Level toLevel(String sArg) {
return (Level) toLevel(sArg, Level.DEBUG);
}
/**
- Convert an integer passed as argument to a level. If the
- conversion fails, then this method returns {@link #DEBUG}.
-
- */
+ * Convert an integer passed as argument to a level. If the conversion fails,
+ * then this method returns {@link #DEBUG}.
+ *
+ * @param val an int
+ * @return a level
+ */
public static Level toLevel(int val) {
return (Level) toLevel(val, Level.DEBUG);
}
/**
- Convert an integer passed as argument to a level. If the
- conversion fails, then this method returns the specified default.
- */
+ * Convert an integer passed as argument to a level. If the conversion fails,
+ * then this method returns the specified default.
+ *
+ * @param val a value
+ * @param defaultLevel a defaultLevel
+ * @return corresponding Level
+ */
public static Level toLevel(int val, Level defaultLevel) {
switch (val) {
case ALL_INT:
@@ -150,10 +168,13 @@ public class Level extends Priority implements Serializable {
}
/**
- Convert the string passed as argument to a level. If the
- conversion fails, then this method returns the value of
- <code>defaultLevel</code>.
- */
+ * Convert the string passed as argument to a level. If the conversion fails,
+ * then this method returns the value of <code>defaultLevel</code>.
+ *
+ * @param sArg a string
+ * @param defaultLevel a default level
+ * @return corresponding level
+ */
public static Level toLevel(String sArg, Level defaultLevel) {
if (sArg == null)
return defaultLevel;
@@ -181,8 +202,9 @@ public class Level extends Priority implements Serializable {
/**
* Custom deserialization of Level.
+ *
* @param s serialization stream.
- * @throws IOException if IO exception.
+ * @throws IOException if IO exception.
* @throws ClassNotFoundException if class not found.
*/
private void readObject(final ObjectInputStream s) throws IOException, ClassNotFoundException {
@@ -197,6 +219,7 @@ public class Level extends Priority implements Serializable {
/**
* Serialize level.
+ *
* @param s serialization stream.
* @throws IOException if exception during serialization.
*/
@@ -208,14 +231,15 @@ public class Level extends Priority implements Serializable {
}
/**
- * Resolved deserialized level to one of the stock instances.
- * May be overriden in classes derived from Level.
+ * Resolved deserialized level to one of the stock instances. May be overridden
+ * in classes derived from Level.
+ *
* @return resolved object.
* @throws ObjectStreamException if exception during resolution.
*/
private Object readResolve() throws ObjectStreamException {
//
- // if the deserizalized object is exactly an instance of Level
+ // if the deserialized object is exactly an instance of Level
//
if (getClass() == Level.class) {
return toLevel(level);
diff --git a/log4j-over-slf4j/src/main/java/org/apache/log4j/Log4jLoggerFactory.java b/log4j-over-slf4j/src/main/java/org/apache/log4j/Log4jLoggerFactory.java
index 738b6a6c..eea3c97d 100644
--- a/log4j-over-slf4j/src/main/java/org/apache/log4j/Log4jLoggerFactory.java
+++ b/log4j-over-slf4j/src/main/java/org/apache/log4j/Log4jLoggerFactory.java
@@ -17,7 +17,6 @@
package org.apache.log4j;
import org.apache.log4j.spi.LoggerFactory;
-import org.slf4j.helpers.Util;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -34,24 +33,7 @@ import java.util.concurrent.ConcurrentMap;
class Log4jLoggerFactory {
// String, Logger
- private static ConcurrentMap<String, Logger> log4jLoggers = new ConcurrentHashMap<String, Logger>();
-
- private static final String LOG4J_DELEGATION_LOOP_URL = "http://www.slf4j.org/codes.html#log4jDelegationLoop";
-
- // check for delegation loops
- static {
- try {
- Class.forName("org.slf4j.impl.Log4jLoggerFactory");
- String part1 = "Detected both log4j-over-slf4j.jar AND slf4j-log4j12.jar on the class path, preempting StackOverflowError. ";
- String part2 = "See also " + LOG4J_DELEGATION_LOOP_URL + " for more details.";
-
- Util.report(part1);
- Util.report(part2);
- throw new IllegalStateException(part1 + part2);
- } catch (ClassNotFoundException e) {
- // this is the good case
- }
- }
+ private static final ConcurrentMap<String, Logger> log4jLoggers = new ConcurrentHashMap<>();
public static Logger getLogger(String name) {
org.apache.log4j.Logger instance = log4jLoggers.get(name);
diff --git a/log4j-over-slf4j/src/main/java/org/apache/log4j/LogManager.java b/log4j-over-slf4j/src/main/java/org/apache/log4j/LogManager.java
index 51c9c85d..42619190 100644
--- a/log4j-over-slf4j/src/main/java/org/apache/log4j/LogManager.java
+++ b/log4j-over-slf4j/src/main/java/org/apache/log4j/LogManager.java
@@ -22,12 +22,11 @@ import java.util.Enumeration;
import java.util.Vector;
/**
- * <p/>
+ * <p>
* This class is a minimal implementation of the original
* <code>org.apache.log4j.LogManager</code> class (as found in log4j 1.2)
* delegating all calls to SLF4J.
- * <p/>
- * <p/>
+ * <p>
* This implementation does <b>NOT</b> implement the setRepositorySelector(),
* getLoggerRepository(), exists(), getCurrentLoggers(), shutdown() and
* resetConfiguration() methods which do not have SLF4J equivalents.
@@ -51,7 +50,7 @@ public class LogManager {
/**
* Returns a logger instance created by loggerFactory. This method was requested in
- * <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=234">bug #234</a>. Note that
+ * <a href="http://jira.qos.ch/browse/SLF4J-225">SLF4J-225</a>. Note that
* log4j-over-slf4j does not ship with a LoggerFactory implementation. If this
* method is called, the caller must provide his/her own implementation.
*
@@ -67,7 +66,7 @@ public class LogManager {
/**
* This bogus implementation returns an empty enumeration.
*
- * @return
+ * @return an Enumeration of current loggers
*/
public static Enumeration getCurrentLoggers() {
return new Vector().elements();
diff --git a/log4j-over-slf4j/src/main/java/org/apache/log4j/Logger.java b/log4j-over-slf4j/src/main/java/org/apache/log4j/Logger.java
index 12ec1761..198b4e9e 100644
--- a/log4j-over-slf4j/src/main/java/org/apache/log4j/Logger.java
+++ b/log4j-over-slf4j/src/main/java/org/apache/log4j/Logger.java
@@ -24,7 +24,7 @@ import org.slf4j.spi.LocationAwareLogger;
* This class is a minimal implementation of the original
* <code>org.apache.log4j.Logger</code> class (as found in log4j 1.2)
* delegating all calls to a {@link org.slf4j.Logger} instance.
- * </p>
+ *
*
* @author Ceki G&uuml;lc&uuml;
* */
@@ -52,7 +52,7 @@ public class Logger extends Category {
/**
* Does the obvious.
*
- * @return
+ * @return the root logger
*/
public static Logger getRootLogger() {
return Log4jLoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
@@ -61,6 +61,8 @@ public class Logger extends Category {
/**
* Delegates to {@link org.slf4j.Logger#isTraceEnabled}
* method of SLF4J.
+ *
+ * @return whether this logger is enabled for the level TRACE
*/
public boolean isTraceEnabled() {
return slf4jLogger.isTraceEnabled();
@@ -68,6 +70,9 @@ public class Logger extends Category {
/**
* Delegates to {@link org.slf4j.Logger#trace(String)} method in SLF4J.
+ *
+ * @param message the message to log
+ *
*/
public void trace(Object message) {
differentiatedLog(null, LOGGER_FQCN, LocationAwareLogger.TRACE_INT, message, null);
@@ -76,9 +81,12 @@ public class Logger extends Category {
/**
* Delegates to {@link org.slf4j.Logger#trace(String,Throwable)}
* method in SLF4J.
+ *
+ * @param message the message to log
+ * @param t a Throwable to log
*/
public void trace(Object message, Throwable t) {
- differentiatedLog(null, LOGGER_FQCN, LocationAwareLogger.TRACE_INT, message, null);
+ differentiatedLog(null, LOGGER_FQCN, LocationAwareLogger.TRACE_INT, message, t);
}
}
diff --git a/log4j-over-slf4j/src/main/java/org/apache/log4j/MDC.java b/log4j-over-slf4j/src/main/java/org/apache/log4j/MDC.java
index c4a8eff4..32118d4d 100644
--- a/log4j-over-slf4j/src/main/java/org/apache/log4j/MDC.java
+++ b/log4j-over-slf4j/src/main/java/org/apache/log4j/MDC.java
@@ -49,6 +49,8 @@ public class MDC {
* This method is not part of the Log4J public API. However it
* has been called by other projects. This method is here temporarily
* until projects who are depending on this method release fixes.
+ *
+ * @return a copy of the underlying map returned as a Hashtable
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@Deprecated
diff --git a/log4j-over-slf4j/src/main/java/org/apache/log4j/PatternLayout.java b/log4j-over-slf4j/src/main/java/org/apache/log4j/PatternLayout.java
index a38df63b..a65fa2b9 100644
--- a/log4j-over-slf4j/src/main/java/org/apache/log4j/PatternLayout.java
+++ b/log4j-over-slf4j/src/main/java/org/apache/log4j/PatternLayout.java
@@ -20,7 +20,7 @@ package org.apache.log4j;
/**
* This class is a minimal implementation of the original Log4J class.
*
- * @author Christian Trutz <christian.trutz@belaso.de>
+ * @author Christian Trutz
* */
public class PatternLayout extends Layout {
diff --git a/log4j-over-slf4j/src/main/java/org/apache/log4j/Priority.java b/log4j-over-slf4j/src/main/java/org/apache/log4j/Priority.java
index bb4f8d4a..08eebca9 100644
--- a/log4j-over-slf4j/src/main/java/org/apache/log4j/Priority.java
+++ b/log4j-over-slf4j/src/main/java/org/apache/log4j/Priority.java
@@ -21,8 +21,8 @@ package org.apache.log4j;
// Contributors: Kitching Simon <Simon.Kitching@OOOrange.ch>
/**
- <font color="#AA4444">Refrain from using this class directly, use
- the {@link Level} class instead</font>.
+ <b>Refrain from using this class directly, use
+ the {@link Level} class instead</b>.
@author Ceki G&uuml;lc&uuml; */
public class Priority {
@@ -48,21 +48,25 @@ public class Priority {
/**
* @deprecated Use {@link Level#ERROR} instead.
*/
+ @Deprecated
final static public Priority ERROR = new Level(ERROR_INT, "ERROR", 3);
/**
* @deprecated Use {@link Level#WARN} instead.
*/
+ @Deprecated
final static public Priority WARN = new Level(WARN_INT, "WARN", 4);
/**
* @deprecated Use {@link Level#INFO} instead.
*/
+ @Deprecated
final static public Priority INFO = new Level(INFO_INT, "INFO", 6);
/**
* @deprecated Use {@link Level#DEBUG} instead.
*/
+ @Deprecated
final static public Priority DEBUG = new Level(DEBUG_INT, "DEBUG", 7);
/**
@@ -76,6 +80,15 @@ public class Priority {
/**
Instantiate a level object.
+ @param
+ */
+
+ /**
+ * Instantiate a level object.
+ *
+ * @param level a level as in int
+ * @param levelStr a levelStr
+ * @param syslogEquivalent the syslog equivalent level integer
*/
protected Priority(int level, String levelStr, int syslogEquivalent) {
this.level = level;
@@ -98,20 +111,23 @@ public class Priority {
/**
Return the syslog equivalent of this priority as an integer.
+ @return the Syslog Equivalent of this Priority
*/
public final int getSyslogEquivalent() {
return syslogEquivalent;
}
/**
- Returns <code>true</code> if this level has a higher or equal
- level than the level passed as argument, <code>false</code>
- otherwise.
-
- <p>You should think twice before overriding the default
- implementation of <code>isGreaterOrEqual</code> method.
-
- */
+ * Returns <code>true</code> if this level has a higher or equal
+ * level than the level passed as argument, <code>false</code>
+ * otherwise.
+ *
+ * <p>You should think twice before overriding the default
+ * implementation of <code>isGreaterOrEqual</code> method.
+ *
+ * @param r a priority
+ * @return a boolean
+ */
public boolean isGreaterOrEqual(Priority r) {
return level >= r.level;
}
@@ -119,9 +135,11 @@ public class Priority {
/**
Return all possible priorities as an array of Level objects in
descending order.
-
+
@deprecated This method will be removed with no replacement.
+ @return array of all possible priorities
*/
+ @Deprecated
public static Priority[] getAllPossiblePriorities() {
return new Priority[] { Priority.FATAL, Priority.ERROR, Level.WARN, Priority.INFO, Priority.DEBUG };
}
@@ -134,7 +152,9 @@ public class Priority {
}
/**
- Returns the integer representation of this level.
+ * Returns the integer representation of this level.
+ *
+ * @return integer representation of this level
*/
public final int toInt() {
return level;
@@ -142,29 +162,46 @@ public class Priority {
/**
* @deprecated Please use the {@link Level#toLevel(String)} method instead.
+ *
+ * @param sArg a string to convert to a Priority
+ * @return the corresponding Priority
*/
+ @Deprecated
public static Priority toPriority(String sArg) {
return Level.toLevel(sArg);
}
/**
* @deprecated Please use the {@link Level#toLevel(int)} method instead.
+ *
+ * @param val an integer to convert to a Priority
+ * @return the corresponding Priority
*/
+ @Deprecated
public static Priority toPriority(int val) {
return toPriority(val, Priority.DEBUG);
}
/**
* @deprecated Please use the {@link Level#toLevel(int, Level)} method instead.
- */
+ *
+ * @param val an integer value
+ * @param defaultPriority a default priority value
+ * @return corresponding Priority value
+ */
+ @Deprecated
public static Priority toPriority(int val, Priority defaultPriority) {
return Level.toLevel(val, (Level) defaultPriority);
}
/**
* @deprecated Please use the {@link Level#toLevel(String, Level)} method instead.
+ * @param sArg string value
+ * @param defaultPriority a default Priority
+ * @return a Priority
*/
+ @Deprecated
public static Priority toPriority(String sArg, Priority defaultPriority) {
return Level.toLevel(sArg, (Level) defaultPriority);
}
-} \ No newline at end of file
+}
diff --git a/log4j-over-slf4j/src/main/java/org/apache/log4j/PropertyConfigurator.java b/log4j-over-slf4j/src/main/java/org/apache/log4j/PropertyConfigurator.java
index baf4c136..6af30d06 100644
--- a/log4j-over-slf4j/src/main/java/org/apache/log4j/PropertyConfigurator.java
+++ b/log4j-over-slf4j/src/main/java/org/apache/log4j/PropertyConfigurator.java
@@ -23,7 +23,7 @@ import org.apache.log4j.spi.Configurator;
import org.apache.log4j.spi.LoggerRepository;
/**
- * An nop implementation of PropertyConfigurator.
+ * A no-op implementation of PropertyConfigurator.
*/
public class PropertyConfigurator implements Configurator {
public static void configure(Properties properties) {
diff --git a/log4j-over-slf4j/src/main/java/org/apache/log4j/RollingFileAppender.java b/log4j-over-slf4j/src/main/java/org/apache/log4j/RollingFileAppender.java
index b3295974..7cecc550 100644
--- a/log4j-over-slf4j/src/main/java/org/apache/log4j/RollingFileAppender.java
+++ b/log4j-over-slf4j/src/main/java/org/apache/log4j/RollingFileAppender.java
@@ -22,7 +22,7 @@ import java.io.IOException;
/**
* This class is a minimal implementation of the original Log4J class.
*
- * @author Christian Trutz <christian.trutz@belaso.de>
+ * @author Christian Trutz
* */
public class RollingFileAppender {
diff --git a/log4j-over-slf4j/src/main/java/org/apache/log4j/helpers/LogLog.java b/log4j-over-slf4j/src/main/java/org/apache/log4j/helpers/LogLog.java
index 01157ab7..0270e418 100644
--- a/log4j-over-slf4j/src/main/java/org/apache/log4j/helpers/LogLog.java
+++ b/log4j-over-slf4j/src/main/java/org/apache/log4j/helpers/LogLog.java
@@ -25,7 +25,7 @@ package org.apache.log4j.helpers;
<b>log4j.configDebug</b> variable.
<p>All log4j internal debug calls go to <code>System.out</code>
- where as internal error messages are sent to
+ whereas internal error messages are sent to
<code>System.err</code>. All internal messages are prepended with
the string "log4j: ".
@@ -37,20 +37,20 @@ public class LogLog {
/**
Defining this value makes log4j print log4j-internal debug
statements to <code>System.out</code>.
-
+
<p> The value of this string is <b>log4j.debug</b>.
-
- <p>Note that the search for all option names is case sensitive. */
+
+ <p>Note that the search for all option names is case-sensitive. */
public static final String DEBUG_KEY = "log4j.debug";
/**
Defining this value makes log4j components print log4j-internal
debug statements to <code>System.out</code>.
-
+
<p> The value of this string is <b>log4j.configDebug</b>.
-
- <p>Note that the search for all option names is case sensitive.
-
+
+ <p>Note that the search for all option names is case-sensitive.
+
@deprecated Use {@link #DEBUG_KEY} instead.
*/
public static final String CONFIG_DEBUG_KEY = "log4j.configDebug";
@@ -127,7 +127,7 @@ public class LogLog {
/**
In quite mode no LogLog generates strictly no output, not even
for errors.
-
+
@param quietMode A true for not
*/
public static void setQuietMode(boolean quietMode) {
diff --git a/log4j-over-slf4j/src/main/java/org/apache/log4j/spi/Configurator.java b/log4j-over-slf4j/src/main/java/org/apache/log4j/spi/Configurator.java
index abf75609..f15cbf07 100644
--- a/log4j-over-slf4j/src/main/java/org/apache/log4j/spi/Configurator.java
+++ b/log4j-over-slf4j/src/main/java/org/apache/log4j/spi/Configurator.java
@@ -16,7 +16,6 @@
package org.apache.log4j.spi;
-import org.apache.log4j.spi.LoggerRepository;
import java.net.URL;
/**
@@ -41,10 +40,10 @@ public interface Configurator {
/**
Interpret a resource pointed by a URL and set up log4j accordingly.
-
+
The configuration is done relative to the <code>hierarchy</code>
parameter.
-
+
@param url The URL to parse
@param repository The hierarchy to operation upon.
*/
diff --git a/log4j-over-slf4j/src/main/java/org/apache/log4j/spi/HierarchyEventListener.java b/log4j-over-slf4j/src/main/java/org/apache/log4j/spi/HierarchyEventListener.java
index a774949e..9271b70b 100644
--- a/log4j-over-slf4j/src/main/java/org/apache/log4j/spi/HierarchyEventListener.java
+++ b/log4j-over-slf4j/src/main/java/org/apache/log4j/spi/HierarchyEventListener.java
@@ -19,7 +19,7 @@ package org.apache.log4j.spi;
import org.apache.log4j.*;
/**
- Listen to events occuring within a {@link
+ Listen to events occurring within a {@link
org.apache.log4j.Hierarchy Hierarchy}.
@author Ceki G&uuml;lc&uuml;
diff --git a/log4j-over-slf4j/src/main/java/org/apache/log4j/spi/Layout.java b/log4j-over-slf4j/src/main/java/org/apache/log4j/spi/Layout.java
deleted file mode 100644
index 32d49074..00000000
--- a/log4j-over-slf4j/src/main/java/org/apache/log4j/spi/Layout.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2001-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.log4j.spi;
-
-public class Layout {
-}
diff --git a/log4j-over-slf4j/src/main/java/org/apache/log4j/spi/LoggerFactory.java b/log4j-over-slf4j/src/main/java/org/apache/log4j/spi/LoggerFactory.java
index c3e756d7..0f008bfa 100644
--- a/log4j-over-slf4j/src/main/java/org/apache/log4j/spi/LoggerFactory.java
+++ b/log4j-over-slf4j/src/main/java/org/apache/log4j/spi/LoggerFactory.java
@@ -21,7 +21,7 @@ import org.apache.log4j.Logger;
/**
Implement this interface to create new instances of Logger or
- a sub-class of Logger.
+ a subclass of Logger.
<p>See <code>examples/subclass/MyLogger.java</code> for an example.
diff --git a/log4j-over-slf4j/src/main/java/org/apache/log4j/spi/LoggerRepository.java b/log4j-over-slf4j/src/main/java/org/apache/log4j/spi/LoggerRepository.java
index 4decdb78..87a3b61d 100644
--- a/log4j-over-slf4j/src/main/java/org/apache/log4j/spi/LoggerRepository.java
+++ b/log4j-over-slf4j/src/main/java/org/apache/log4j/spi/LoggerRepository.java
@@ -25,7 +25,7 @@ import java.util.Enumeration;
* <code>Loggers</code>. The relation between loggers in a repository
* depends on the repository but typically loggers are arranged in a
* named hierarchy.
- * <p/>
+ *
* <p>In addition to the creational methods, a
* <code>LoggerRepository</code> can be queried for existing loggers,
* can act as a point of registry for events related to loggers.
@@ -37,6 +37,8 @@ public interface LoggerRepository {
/**
* Add a {@link HierarchyEventListener} event to the repository.
+ *
+ * @param listener a listener
*/
public void addHierarchyEventListener(HierarchyEventListener listener);
diff --git a/log4j-over-slf4j/src/main/java9/module-info.java b/log4j-over-slf4j/src/main/java9/module-info.java
new file mode 100755
index 00000000..35017bea
--- /dev/null
+++ b/log4j-over-slf4j/src/main/java9/module-info.java
@@ -0,0 +1,8 @@
+module log4j {
+ requires org.slf4j;
+ requires java.xml;
+ exports org.apache.log4j;
+ exports org.apache.log4j.helpers;
+ exports org.apache.log4j.spi;
+ exports org.apache.log4j.xml;
+} \ No newline at end of file
diff --git a/log4j-over-slf4j/src/main/resources/META-INF/MANIFEST.MF b/log4j-over-slf4j/src/main/resources/META-INF/MANIFEST.MF
deleted file mode 100644
index 531f5842..00000000
--- a/log4j-over-slf4j/src/main/resources/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,8 +0,0 @@
-Implementation-Title: log4j-over-slf4j
-Bundle-ManifestVersion: 2
-Bundle-SymbolicName: log4j.over.slf4j
-Bundle-Name: log4j-over-slf4j
-Bundle-Vendor: SLF4J.ORG
-Bundle-RequiredExecutionEnvironment: J2SE-1.5
-Export-Package: org.apache.log4j;version=${log4j.version},org.apache.log4j.helpers;version=${log4j.version},org.apache.log4j.spi;version=${log4j.version},org.apache.log4j.xml;version=${log4j.version}
-Import-Package: org.slf4j;version=${slf4j.api.minimum.compatible.version}, org.slf4j.helpers;version=${slf4j.api.minimum.compatible.version}, org.slf4j.spi;version=${slf4j.api.minimum.compatible.version}
diff --git a/log4j-over-slf4j/src/test/java/org/apache/log4j/NDCTest.java b/log4j-over-slf4j/src/test/java/org/apache/log4j/test/NDCTest.java
index 74c2cd3b..ff87cff4 100644
--- a/log4j-over-slf4j/src/test/java/org/apache/log4j/NDCTest.java
+++ b/log4j-over-slf4j/src/test/java/org/apache/log4j/test/NDCTest.java
@@ -22,35 +22,46 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.apache.log4j;
+package org.apache.log4j.test;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.log4j.NDC;
/**
- * @author Ceki G&uuml;c&uuml;
+ * @author Ceki G&uuml;lc&uuml;
*/
-public class NDCTest extends TestCase {
+public class NDCTest {
+ @Before
public void setUp() {
assertEquals(0, NDC.getDepth());
}
+ @After
public void tearDown() {
NDC.clear();
}
+ @Test
public void testSmoke() {
NDC.push("a");
String back = NDC.pop();
assertEquals("a", back);
}
+ @Test
public void testPop() {
NDC.push("peek");
String back = NDC.peek();
assertEquals("peek", back);
}
+ @Test
public void testClear() {
NDC.push("clear");
NDC.clear();
diff --git a/log4j-over-slf4j/src/test/java/org/apache/log4j/Trivial.java b/log4j-over-slf4j/src/test/java/org/apache/log4j/test/Trivial.java
index 50edf2d3..6a8fbcc5 100644
--- a/log4j-over-slf4j/src/test/java/org/apache/log4j/Trivial.java
+++ b/log4j-over-slf4j/src/test/java/org/apache/log4j/test/Trivial.java
@@ -22,7 +22,7 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.apache.log4j;
+package org.apache.log4j.test;
import org.apache.log4j.Logger;
diff --git a/log4j-over-slf4j/src/test/java/org/dummy/Bug131.java b/log4j-over-slf4j/src/test/java/org/dummy/Bug131.java
index c97d5666..4453ac22 100644
--- a/log4j-over-slf4j/src/test/java/org/dummy/Bug131.java
+++ b/log4j-over-slf4j/src/test/java/org/dummy/Bug131.java
@@ -24,16 +24,18 @@
*/
package org.dummy;
+import static org.junit.Assert.assertEquals;
+
import java.util.logging.Level;
import java.util.logging.LogRecord;
-import junit.framework.TestCase;
-
import org.apache.log4j.Category;
import org.apache.log4j.Logger;
+import org.junit.Test;
-public class Bug131 extends TestCase {
+public class Bug131 {
+ @Test
public void testBug131() {
ListHandler listHandler = new ListHandler();
diff --git a/log4j-over-slf4j/src/test/java/org/dummy/Bug139.java b/log4j-over-slf4j/src/test/java/org/dummy/Bug139.java
index f6cfe63f..1bb280ce 100644
--- a/log4j-over-slf4j/src/test/java/org/dummy/Bug139.java
+++ b/log4j-over-slf4j/src/test/java/org/dummy/Bug139.java
@@ -24,16 +24,18 @@
*/
package org.dummy;
+import static org.junit.Assert.assertEquals;
+
import java.util.logging.Level;
import java.util.logging.LogRecord;
-import junit.framework.TestCase;
-
import org.apache.log4j.Category;
import org.apache.log4j.Logger;
+import org.junit.Test;
-public class Bug139 extends TestCase {
+public class Bug139 {
+ @Test
public void test() {
ListHandler listHandler = new ListHandler();
java.util.logging.Logger root = java.util.logging.Logger.getLogger("");
diff --git a/log4j-over-slf4j/src/test/java/org/dummy/ListHandler.java b/log4j-over-slf4j/src/test/java/org/dummy/ListHandler.java
index c29ebfa1..2a237239 100644
--- a/log4j-over-slf4j/src/test/java/org/dummy/ListHandler.java
+++ b/log4j-over-slf4j/src/test/java/org/dummy/ListHandler.java
@@ -31,7 +31,7 @@ import java.util.logging.LogRecord;
public class ListHandler extends Handler {
- List<LogRecord> list = new ArrayList<LogRecord>();
+ List<LogRecord> list = new ArrayList<>();
public void close() throws SecurityException {
diff --git a/slf4j-jcl/LICENSE.txt b/osgi-over-slf4j/LICENSE.txt
index 508a2728..1a3d0532 100644
--- a/slf4j-jcl/LICENSE.txt
+++ b/osgi-over-slf4j/LICENSE.txt
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2007 QOS.ch
+Copyright (c) 2004-2022 QOS.ch Sarl (Switzerland)
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/osgi-over-slf4j/pom.xml b/osgi-over-slf4j/pom.xml
index 1962dd6b..71c69929 100755
--- a/osgi-over-slf4j/pom.xml
+++ b/osgi-over-slf4j/pom.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
@@ -6,12 +7,13 @@
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
- <version>1.7.13-SNAPSHOT</version>
+ <version>2.0.12</version>
+ <relativePath>../parent/pom.xml</relativePath>
</parent>
<artifactId>osgi-over-slf4j</artifactId>
- <packaging>bundle</packaging>
+ <packaging>jar</packaging>
<name>OSGi LogService implemented over SLF4J</name>
<url>http://www.slf4j.org</url>
@@ -36,24 +38,27 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
- <version>${project.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
+
<build>
<plugins>
+
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>2.3.7</version>
- <extensions>true</extensions>
<configuration>
<instructions>
- <Export-Package>org.osgi.service.log</Export-Package>
+ <Bundle-SymbolicName>org.slf4j.osgi-over-slf4j</Bundle-SymbolicName>
<Bundle-Activator>org.slf4j.osgi.logservice.impl.Activator</Bundle-Activator>
+ <Bundle-Category>osgi</Bundle-Category>
+ <_exportcontents combine.self="override" />
</instructions>
</configuration>
</plugin>
+
</plugins>
</build>
+
</project>
diff --git a/parent/pom.xml b/parent/pom.xml
new file mode 100644
index 00000000..b702b5ff
--- /dev/null
+++ b/parent/pom.xml
@@ -0,0 +1,397 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-bom</artifactId>
+ <version>2.0.12</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>slf4j-parent</artifactId>
+ <packaging>pom</packaging>
+ <name>SLF4J Parent POM</name>
+ <description>SLF4J project parent pom.xml file</description>
+
+
+ <organization>
+ <name>QOS.ch</name>
+ <url>http://www.qos.ch</url>
+ </organization>
+ <inceptionYear>2005</inceptionYear>
+
+
+ <properties>
+ <!-- yyyy-MM-dd'T'HH:mm:ss'Z' -->
+ <project.build.outputTimestamp>2024-02-05T21:21:00Z</project.build.outputTimestamp>
+ <latest.1.version>1.7.36</latest.1.version>
+ <!-- java.util.ServiceLoader requires Java 6 -->
+ <jdk.version>8</jdk.version>
+ <maven.compiler.source>${jdk.version}</maven.compiler.source>
+ <maven.compiler.target>${jdk.version}</maven.compiler.target>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.build.resourceEncoding>UTF-8</project.build.resourceEncoding>
+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+ <!-- used in integration testing -->
+ <cal10n.version>0.8.1</cal10n.version>
+ <reload4j.version>1.2.22</reload4j.version>
+ <logback.version>1.2.10</logback.version>
+ <jcl.version>1.2</jcl.version>
+ <junit.version>4.13.1</junit.version>
+ <maven-site-plugin.version>3.7.1</maven-site-plugin.version>
+ <maven-compiler-plugin.version>3.10.1</maven-compiler-plugin.version>
+ <maven-surefire-plugin.version>3.0.0-M7</maven-surefire-plugin.version>
+ <maven-javadoc-plugin.version>3.6.3</maven-javadoc-plugin.version>
+ <maven-source-plugin.version>3.2.1</maven-source-plugin.version>
+ <maven-deploy-plugin.version>3.0.0-M1</maven-deploy-plugin.version>
+ <maven-jar-plugin.version>3.2.0</maven-jar-plugin.version>
+ <maven-jxr-plugin.version>3.1.1</maven-jxr-plugin.version>
+ <maven-bundle-plugin.version>5.1.9</maven-bundle-plugin.version>
+ </properties>
+
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junit.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <dependencyManagement>
+ <dependencies>
+
+ <dependency>
+ <groupId>ch.qos.reload4j</groupId>
+ <artifactId>reload4j</artifactId>
+ <version>${reload4j.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>ch.qos.cal10n</groupId>
+ <artifactId>cal10n-api</artifactId>
+ <version>${cal10n.version}</version>
+ </dependency>
+
+ </dependencies>
+ </dependencyManagement>
+
+ <build>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-ssh</artifactId>
+ <version>2.10</version>
+ </extension>
+ </extensions>
+
+ <resources>
+ <resource>
+ <directory>${project.basedir}/src/main/resources</directory>
+ <filtering>true</filtering>
+ </resource>
+
+ <resource>
+ <directory>..</directory>
+ <targetPath>META-INF</targetPath>
+ <includes>
+ <include>LICENSE.txt</include>
+ </includes>
+ </resource>
+ </resources>
+
+ <pluginManagement>
+ <plugins>
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>animal-sniffer-maven-plugin</artifactId>
+ <version>1.14</version>
+ <configuration>
+ <signature>
+ <groupId>org.codehaus.mojo.signature</groupId>
+ <artifactId>java16</artifactId>
+ <version>1.0</version>
+ </signature>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>${maven-deploy-plugin.version}</version>
+ </plugin>
+
+ </plugins>
+ </pluginManagement>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>${maven-compiler-plugin.version}</version>
+ <executions>
+
+ <execution>
+ <id>default-compile</id>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ <configuration>
+ <source>${jdk.version}</source>
+ <target>${jdk.version}</target>
+ </configuration>
+ </execution>
+
+ <execution>
+ <id>module-compile</id>
+ <phase>compile</phase>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ <configuration>
+ <release>9</release>
+ <compileSourceRoots>
+ <compileSourceRoot>${project.basedir}/src/main/java9</compileSourceRoot>
+ </compileSourceRoots>
+ <multiReleaseOutput>true</multiReleaseOutput>
+ </configuration>
+ </execution>
+
+
+ </executions>
+
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>${maven-jar-plugin.version}</version>
+ <executions>
+ <!-- Repeated in slf4j-api/pom.xml -->
+ <execution>
+ <id>default-jar</id>
+ <phase>package</phase>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ <configuration>
+ <archive>
+ <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+ </archive>
+ <skipIfEmpty>true</skipIfEmpty>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>${maven-bundle-plugin.version}</version>
+ <configuration>
+ <supportIncrementalBuild>true</supportIncrementalBuild>
+ <!-- populated by the plugin itself -->
+ <instructions>
+ <Bundle-SymbolicName>${replacestring;${project.artifactId};-;.}</Bundle-SymbolicName>
+ <Bundle-Vendor>SLF4J.ORG</Bundle-Vendor>
+ <_snapshot/>
+ <_exportcontents>!META-INF.versions.9,*;-noimport:=true</_exportcontents>
+ <Bundle-Description>${project.description}</Bundle-Description>
+ <Bundle-DocURL>${project.url}</Bundle-DocURL>
+ <X-Compile-Source-JDK>${maven.compiler.source}</X-Compile-Source-JDK>
+ <X-Compile-Target-JDK>${maven.compiler.target}</X-Compile-Target-JDK>
+ <Implementation-Version>${project.version}</Implementation-Version>
+ <Implementation-Title>${project.artifactId}</Implementation-Title>
+ <Multi-Release>true</Multi-Release>
+ <_removeheaders>Private-Package,Bundle-SCM, Bundle-Developers, Include-Resource</_removeheaders>
+ </instructions>
+ </configuration>
+ <executions>
+ <execution>
+ <id>bundle-manifest</id>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>manifest</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>${maven-surefire-plugin.version}</version>
+ <configuration>
+ <forkCount>1</forkCount>
+ <reuseForks>false</reuseForks>
+ <reportFormat>plain</reportFormat>
+ <trimStackTrace>false</trimStackTrace>
+ <excludes>
+ <exclude>**/AllTest.java</exclude>
+ <exclude>**/PackageTest.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>${maven-source-plugin.version}</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-site-plugin</artifactId>
+ <version>${maven-site-plugin.version}</version>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-project-info-reports-plugin</artifactId>
+ <version>3.0.0</version>
+ </plugin>
+ </plugins>
+
+ </build>
+
+ <profiles>
+ <profile>
+ <id>skipTests</id>
+ <properties>
+ <maven.test.skip>true</maven.test.skip>
+ </properties>
+ </profile>
+
+ <profile>
+ <id>javadocjar</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>${maven-javadoc-plugin.version}</version>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <additionalparam>-Xdoclint:none</additionalparam>
+ <failOnError>false</failOnError>
+ <sourceFileExcludes>
+ <sourceFileExclude>**/module-info.java</sourceFileExclude>
+ </sourceFileExcludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
+ <profile>
+ <id>license</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>com.google.code.maven-license-plugin</groupId>
+ <artifactId>maven-license-plugin</artifactId>
+ <configuration>
+ <header>src/main/licenseHeader.txt</header>
+ <quiet>false</quiet>
+ <failIfMissing>true</failIfMissing>
+ <aggregate>true</aggregate>
+ <includes>
+ <include>src/**/*.java</include>
+ </includes>
+ <useDefaultExcludes>true</useDefaultExcludes>
+ <useDefaultMapping>true</useDefaultMapping>
+ <properties>
+ <year>1999</year>
+ </properties>
+ <headerDefinitions>
+ <headerDefinition>src/main/javadocHeaders.xml</headerDefinition>
+ </headerDefinitions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <pluginRepositories>
+ </pluginRepositories>
+ </profile>
+
+
+ <profile>
+ <id>generate-osgi-service-loader-mediator-entries</id>
+ <activation>
+ <file>
+ <exists>src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider</exists>
+ </file>
+ </activation>
+ <build>
+ <!-- Add the OSGi Service Loader Mediator Specification Manifest entries for each module that has a SLF4JServiceProvider Service-Loader file.-->
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Provide-Capability><![CDATA[
+ osgi.service;objectClass:List<String>="org.slf4j.spi.SLF4JServiceProvider";type=${slf4j.provider.type};effective:=active,
+ osgi.serviceloader;osgi.serviceloader="org.slf4j.spi.SLF4JServiceProvider";register:="${slf4j.provider.implementation}";type=${slf4j.provider.type}
+ ]]></Provide-Capability>
+ <Require-Capability><![CDATA[
+ osgi.extender;filter:="(&(osgi.extender=osgi.serviceloader.registrar)(version>=1.0.0)(!(version>=2.0.0)))"
+ ]]></Require-Capability>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
+ <!--
+ <profile>
+ <id>travis</id>
+ <activation>
+ <property>
+ <name>env.TRAVIS</name>
+ <value>true</value>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-toolchains-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+ <execution>
+ <id>toolchain</id>
+ <phase>none</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ -->
+ </profiles>
+
+
+</project>
diff --git a/pom.xml b/pom.xml
index b2fb3e2c..bbebde28 100755
--- a/pom.xml
+++ b/pom.xml
@@ -1,24 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.slf4j</groupId>
- <artifactId>slf4j-parent</artifactId>
- <version>1.7.13-SNAPSHOT</version>
-
+ <artifactId>slf4j-bom</artifactId>
+ <version>2.0.12</version>
<packaging>pom</packaging>
- <name>SLF4J</name>
- <description>Top SLF4J project pom.xml file</description>
+
<url>http://www.slf4j.org</url>
- <organization>
- <name>QOS.ch</name>
- <url>http://www.qos.ch</url>
- </organization>
- <inceptionYear>2005</inceptionYear>
+ <name>SLF4J BOM</name>
+ <description>SLF4J project BOM</description>
<licenses>
<license>
@@ -29,59 +23,31 @@
</licenses>
<scm>
- <url>https://github.com/ceki/slf4j</url>
- <connection>git@github.com:qos-ch/slf4j.git</connection>
+ <url>https://github.com/qos-ch/slf4j</url>
+ <connection>scm:git:https://github.com/qos-ch/slf4j.git</connection>
</scm>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <required.jdk.version>1.5</required.jdk.version>
- <slf4j.api.minimum.compatible.version>1.6.0</slf4j.api.minimum.compatible.version>
- <cal10n.version>0.8.1</cal10n.version>
- <log4j.version>1.2.17</log4j.version>
- <logback.version>1.0.13</logback.version>
- <junit.version>4.10</junit.version>
- <maven-site-plugin.version>3.3</maven-site-plugin.version>
- <javadoc.plugin.version>2.10.2</javadoc.plugin.version>
- </properties>
-
- <developers>
- <developer>
- <id>ceki</id>
- <name>Ceki Gulcu</name>
- <email>ceki@qos.ch</email>
- </developer>
- </developers>
+ <!-- Inspired by Improving the Maven Bill of Materials (BOM) Pattern -->
+ <!-- https://www.garretwilson.com/blog/2023/06/14/improve-maven-bom-pattern -->
<modules>
+ <module>parent</module>
<module>slf4j-api</module>
- <!--<module>slf4j-scala-api</module>-->
<module>slf4j-simple</module>
<module>slf4j-nop</module>
<module>slf4j-jdk14</module>
+ <module>slf4j-jdk-platform-logging</module>
<module>slf4j-log4j12</module>
- <module>slf4j-jcl</module>
- <module>slf4j-android</module>
+ <module>slf4j-reload4j</module>
<module>slf4j-ext</module>
<module>jcl-over-slf4j</module>
<module>log4j-over-slf4j</module>
<module>jul-to-slf4j</module>
<module>osgi-over-slf4j</module>
<module>integration</module>
- <module>slf4j-site</module>
<module>slf4j-migrator</module>
</modules>
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>${junit.version}</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
-
<dependencyManagement>
<dependencies>
@@ -93,257 +59,169 @@
<dependency>
<groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-nop</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>${project.version}</version>
</dependency>
+
<dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>${log4j.version}</version>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-jdk-platform-logging</artifactId>
+ <version>${project.version}</version>
</dependency>
<dependency>
- <groupId>ch.qos.cal10n</groupId>
- <artifactId>cal10n-api</artifactId>
- <version>${cal10n.version}</version>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>${project.version}</version>
</dependency>
- </dependencies>
- </dependencyManagement>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-reload4j</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-ext</artifactId>
+ <version>${project.version}</version>
+ </dependency>
- <build>
- <extensions>
- <extension>
- <groupId>org.apache.maven.wagon</groupId>
- <artifactId>wagon-ssh</artifactId>
- <version>2.0</version>
- </extension>
- </extensions>
-
- <resources>
- <resource>
- <directory>src/main/resources</directory>
- <filtering>true</filtering>
- </resource>
- </resources>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <version>${project.version}</version>
+ </dependency>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>2.3.2</version>
- <configuration>
- <source>1.5</source>
- <target>1.5</target>
- </configuration>
- </plugin>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>log4j-over-slf4j</artifactId>
+ <version>${project.version}</version>
+ </dependency>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <version>2.3.1</version>
- </plugin>
-
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>2.10</version>
- <configuration>
- <forkMode>once</forkMode>
- <reportFormat>plain</reportFormat>
- <trimStackTrace>false</trimStackTrace>
- <excludes>
- <exclude>**/AllTest.java</exclude>
- <exclude>**/PackageTest.java</exclude>
- </excludes>
- </configuration>
- </plugin>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jul-to-slf4j</artifactId>
+ <version>${project.version}</version>
+ </dependency>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- <version>2.1.2</version>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>osgi-over-slf4j</artifactId>
+ <version>${project.version}</version>
+ </dependency>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-assembly-plugin</artifactId>
- <version>2.2</version>
- <configuration>
- <descriptors>
- <descriptor>src/main/assembly/source.xml</descriptor>
- </descriptors>
- <finalName>slf4j-${project.version}</finalName>
- <appendAssemblyId>false</appendAssemblyId>
- <outputDirectory>target/site/dist/</outputDirectory>
- </configuration>
- </plugin>
- <!-- as suggested in http://bugzilla.slf4j.org/show_bug.cgi?id=152 -->
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.7</version>
- <executions>
- <execution>
- <id>parse-version</id>
- <goals>
- <goal>parse-version</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
+ </dependencies>
+ </dependencyManagement>
+
+ <distributionManagement>
- <!-- ====== site plugin ===== -->
+ <repository>
+ <id>sonatype-nexus-staging</id>
+ <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
+ </repository>
+
+ </distributionManagement>
+
+ <developers>
+ <developer>
+ <id>ceki</id>
+ <name>Ceki Gulcu</name>
+ <email>ceki@qos.ch</email>
+ </developer>
+ </developers>
+
+ <build>
+ <plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-site-plugin</artifactId>
- <version>${maven-site-plugin.version}</version>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>3.6.3</version>
<configuration>
- <reportPlugins>
-
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jxr-plugin</artifactId>
- <version>2.3</version>
- <configuration>
- <aggregate>true</aggregate>
- <javadocDir>target/site/apidocs/</javadocDir>
- <linkJavadoc>true</linkJavadoc>
- </configuration>
- </plugin>
-
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <version>${javadoc.plugin.version}</version>
- <configuration>
- <!--<aggregate>true</aggregate>-->
- <excludePackageNames>org.slf4j.migrator:org.slf4j.migrator.*</excludePackageNames>
- <links>
- <link>
- http://java.sun.com/j2se/1.5.0/docs/api
- </link>
- </links>
- <groups>
- <group>
- <title>SLF4J packages</title>
- <packages>org.slf4j:org.slf4j.*</packages>
- </group>
-
- <group>
- <title>SLF4J extensions</title>
- <packages>
- org.slf4j.cal10n:org.slf4j.profiler:org.slf4j.ext:org.slf4j.instrumentation:org.slf4j.agent
- </packages>
- </group>
-
- <group>
- <title>Jakarta Commons Logging packages</title>
- <packages>org.apache.commons.*</packages>
- </group>
-
- <group>
- <title>java.util.logging (JUL) to SLF4J bridge</title>
- <packages>org.slf4j.bridge</packages>
- </group>
-
- <group>
- <title>Apache log4j</title>
- <packages>org.apache.log4j:org.apache.log4j.*</packages>
- </group>
- </groups>
- </configuration>
- </plugin>
-
- </reportPlugins>
+ <verbose>true</verbose>
+ <skippedModules>
+ slf4j-jdk-platform-logging,slf4j-migrator,osgi-over-slf4j
+ </skippedModules>
+ <detectLinks>true</detectLinks>
+ <doctitle>SLF4J project modules ${project.version}</doctitle>
+ <windowtitle>SLF4J javadoc</windowtitle>
+ <bottom><![CDATA[Copyright &copy; 2005-{currentYear} QOS.CH Sarl. All rights reserved]]></bottom>
+ <linksource>true</linksource>
+ <additionalOptions>
+ <additionalOption>-Xdoclint:none</additionalOption>
+ </additionalOptions>
+ <groups>
+ <group>
+ <title>SLF4J API packages</title>
+ <packages>org.slf4j:org.slf4j.spi:org.slf4j.event:org.slf4j.helpers</packages>
+ </group>
+
+ <group>
+ <title>slf4j-simple package</title>
+ <packages>org.slf4j.simple</packages>
+ </group>
+
+ <group>
+ <title>slf4j-nop package</title>
+ <packages>org.slf4j.nop</packages>
+ </group>
+
+
+ <group>
+ <title>slf4j-jdk14 package</title>
+ <packages>org.slf4j.jul</packages>
+ </group>
+
+
+ <group>
+ <title>slf4j-reload4j package</title>
+ <packages>org.slf4j.reload4j</packages>
+ </group>
+
+
+ <group>
+ <title>SLF4J extensions</title>
+ <packages>
+ org.slf4j.cal10n:org.slf4j.profiler:org.slf4j.ext:org.slf4j.instrumentation:org.slf4j.agent
+ </packages>
+ </group>
+
+ <group>
+ <title>Jakarta Commons Logging packages</title>
+ <packages>org.apache.commons.*</packages>
+ </group>
+
+ <group>
+ <title>java.util.logging (JUL) to SLF4J bridge</title>
+ <packages>org.slf4j.bridge</packages>
+ </group>
+
+ <group>
+ <title>log4j-over-slf4j redirection</title>
+ <packages>org.apache.log4j:org.apache.log4j.*</packages>
+ </group>
+ </groups>
+
</configuration>
</plugin>
</plugins>
-
</build>
<profiles>
- <profile>
- <id>skipTests</id>
- <properties>
- <maven.test.skip>true</maven.test.skip>
- </properties>
- </profile>
-
- <profile>
- <id>javadocjar</id>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <version>${javadoc.plugin.version}</version>
- <executions>
- <execution>
- <id>attach-javadocs</id>
- <goals>
- <goal>jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
-
- <profile>
- <id>license</id>
- <build>
- <plugins>
- <plugin>
- <groupId>com.google.code.maven-license-plugin</groupId>
- <artifactId>maven-license-plugin</artifactId>
- <configuration>
- <header>src/main/licenseHeader.txt</header>
- <quiet>false</quiet>
- <failIfMissing>true</failIfMissing>
- <aggregate>true</aggregate>
- <includes>
- <include>src/**/*.java</include>
- </includes>
- <useDefaultExcludes>true</useDefaultExcludes>
- <useDefaultMapping>true</useDefaultMapping>
- <properties>
- <year>1999</year>
- </properties>
- <headerDefinitions>
- <headerDefinition>src/main/javadocHeaders.xml</headerDefinition>
- </headerDefinitions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <pluginRepositories>
- <pluginRepository>
- <id>mc-release</id>
- <name>Local Maven repository of releases</name>
- <url>http://mc-repo.googlecode.com/svn/maven2/releases</url>
- <snapshots>
- <enabled>false</enabled>
- </snapshots>
- <releases>
- <enabled>true</enabled>
- </releases>
- </pluginRepository>
- </pluginRepositories>
- </profile>
<profile>
<id>sign-artifacts</id>
@@ -366,25 +244,6 @@
</plugins>
</build>
</profile>
-
</profiles>
- <pluginRepositories>
- </pluginRepositories>
-
- <distributionManagement>
- <site>
- <id>pixie</id>
- <url>scp://pixie.qos.ch/var/www/www.slf4j.org/htdocs/</url>
- </site>
-
- <repository>
- <!--<id>pixie</id>-->
- <!--<url>scp://pixie.qos.ch/var/mvnrepo/</url>-->
- <id>sonatype-nexus-staging</id>
- <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
- </repository>
-
- </distributionManagement>
-
</project>
diff --git a/release.sh b/release.sh
new file mode 100755
index 00000000..30daedec
--- /dev/null
+++ b/release.sh
@@ -0,0 +1,61 @@
+
+# Javadoc
+
+#JDK8 - mvn site:site
+#rscpSLF4J apidocs/
+
+# JDK 11+
+# adding the following
+#mvn -Ddoclint=none -Dadditionalparam=-Xdoclint:none javadoc:aggregate
+
+
+#mvn versions:set -DgenerateBackupPoms=false -DnewVersion=${VERSION_NUMBER}
+
+MVN='/java/maven-3.5.2//bin/mvn'
+
+function checkExit(){
+ if test "$?" != "0"; then
+ echo Command $1 exited with abnormal status
+ exit 1;
+ else echo $?
+ fi
+}
+
+function echoRunAndCheck () { # echo and then run the command
+ echo $1
+ $1
+ ret=$?
+ if test "$ret" != "0";
+ then
+ echo Failed command: $1
+ exit 1;
+ else echo Successful run: $1
+ fi
+}
+
+echoRunAndCheck "$MVN clean"
+
+echoRunAndCheck "$MVN install"
+
+#echoRunAndCheck "$MVN site:site"
+
+#echoRunAndCheck "$MVN javadoc:aggregate"
+
+#echoRunAndCheck "$MVN jxr:aggregate"
+
+
+if [ ! -z "$PASS" ]
+then
+ export GPG_TTY=$(tty)
+ echoRunAndCheck "$MVN deploy -P javadocjar,sign-artifacts"
+fi
+
+
+git tag -m "tagging" -a v_${VERSION_NUMBER}
+git push --tags
+
+#Update release version and add next version on jira
+
+
+
+echo Full Success
diff --git a/slf4j-android/.gitignore b/slf4j-android/.gitignore
deleted file mode 100755
index 7792e06b..00000000
--- a/slf4j-android/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-bin/
-gen/
diff --git a/slf4j-android/AndroidManifest.xml b/slf4j-android/AndroidManifest.xml
deleted file mode 100755
index a2b9e40c..00000000
--- a/slf4j-android/AndroidManifest.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="org.slf4j"
- android:versionCode="176"
- android:versionName="1.7.6">
- <uses-sdk android:minSdkVersion="3" />
-</manifest> \ No newline at end of file
diff --git a/slf4j-android/pom.xml b/slf4j-android/pom.xml
deleted file mode 100644
index 28a3b41a..00000000
--- a/slf4j-android/pom.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
- <parent>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-parent</artifactId>
- <version>1.7.13-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
-
- <artifactId>slf4j-android</artifactId>
- <packaging>jar</packaging>
- <name>SLF4J Android Binding</name>
- <description>SLF4J Android Binding</description>
- <url>http://www.slf4j.org</url>
-
- <dependencies>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>com.google.android</groupId>
- <artifactId>android</artifactId>
- <version>1.5_r4</version>
- <scope>provided</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <archive>
- <manifestEntries>
- <Bundle-Version>${parsedVersion.osgiVersion}</Bundle-Version>
- <Bundle-Description>${project.description}</Bundle-Description>
- <Implementation-Version>${project.version}</Implementation-Version>
- </manifestEntries>
- <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
- </archive>
- </configuration>
- </plugin>
-
- <plugin>
- <!-- Google Android requires class compatibility set to 5.0 -->
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <source>${required.jdk.version}</source>
- <target>${required.jdk.version}</target>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project> \ No newline at end of file
diff --git a/slf4j-android/project.properties b/slf4j-android/project.properties
deleted file mode 100755
index 0d4e7607..00000000
--- a/slf4j-android/project.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system use,
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-
-android.library=true
-# Indicates whether an apk should be generated for each density.
-split.density=false
-# Project target.
-target=android-3
diff --git a/slf4j-android/src/main/java/org/slf4j/impl/AndroidLoggerAdapter.java b/slf4j-android/src/main/java/org/slf4j/impl/AndroidLoggerAdapter.java
deleted file mode 100755
index c13a7ce8..00000000
--- a/slf4j-android/src/main/java/org/slf4j/impl/AndroidLoggerAdapter.java
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * Copyright (c) 2004-2013 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 android.util.Log;
-import org.slf4j.helpers.FormattingTuple;
-import org.slf4j.helpers.MarkerIgnoringBase;
-import org.slf4j.helpers.MessageFormatter;
-
-/**
- * <p>A simple implementation that delegates all log requests to the Google Android
- * logging facilities. Note that this logger does not support {@link org.slf4j.Marker}.
- * Methods taking marker data as parameter simply invoke the eponymous method
- * without the Marker argument, discarding any marker data in the process.</p>
- *
- * <p>The logging levels specified for SLF4J can be almost directly mapped to
- * the levels that exist in the Google Android platform. The following table
- * shows the mapping implemented by this logger.</p>
- *
- * <table border="1">
- * <tr><th><b>SLF4J<b></th><th><b>Android</b></th></tr>
- * <tr><td>TRACE</td><td>{@link android.util.Log#VERBOSE}</td></tr>
- * <tr><td>DEBUG</td><td>{@link android.util.Log#DEBUG}</td></tr>
- * <tr><td>INFO</td><td>{@link android.util.Log#INFO}</td></tr>
- * <tr><td>WARN</td><td>{@link android.util.Log#WARN}</td></tr>
- * <tr><td>ERROR</td><td>{@link android.util.Log#ERROR}</td></tr>
- * </table>
- *
- * <p>Use loggers as usual:
- * <ul>
- * <li>
- * Declare a logger<br/>
- * <code>private static final Logger logger = LoggerFactory.getLogger(MyClass.class);</code>
- * </li>
- * <li>
- * Invoke logging methods, e.g.,<br/>
- * <code>logger.debug("Some log message. Details: {}", someObject);</code><br/>
- * <code>logger.debug("Some log message with varargs. Details: {}, {}, {}", someObject1, someObject2, someObject3);</code>
- * </li>
- * </ul>
- * </p>
- *
- * <p>Logger instances created using the LoggerFactory are named either according to the name
- * or the fully qualified class name of the class given as a parameter.
- * Each logger name will be used as the log message tag on the Android platform.
- * However, tag names cannot be longer than 23 characters so if logger name exceeds this limit then
- * it will be truncated by the LoggerFactory. The following examples illustrate this.
- * <table border="1">
- * <tr><th><b>Original Name<b></th><th><b>Truncated Name</b></th></tr>
- * <tr><td>org.example.myproject.mypackage.MyClass</td><td>o*.e*.m*.m*.MyClass</td></tr>
- * <tr><td>o.e.myproject.mypackage.MyClass</td><td>o.e.m*.m*.MyClass</td></tr>
- * <tr><td>org.example.ThisNameIsWayTooLongAndWillBeTruncated</td><td>*LongAndWillBeTruncated</td></tr>
- * <tr><td>ThisNameIsWayTooLongAndWillBeTruncated</td><td>*LongAndWillBeTruncated</td></tr>
- * </table>
- * </p>
- *
- * @author Andrey Korzhevskiy <a.korzhevskiy@gmail.com>
- */
-class AndroidLoggerAdapter extends MarkerIgnoringBase {
- private static final long serialVersionUID = -1227274521521287937L;
-
-
- /**
- * Package access allows only {@link AndroidLoggerFactory} to instantiate
- * SimpleLogger instances.
- */
- AndroidLoggerAdapter(String tag) {
- this.name = tag;
- }
-
- /**
- * Is this logger instance enabled for the VERBOSE level?
- *
- * @return True if this Logger is enabled for level VERBOSE, false otherwise.
- */
- public boolean isTraceEnabled() {
- return isLoggable(Log.VERBOSE);
- }
-
- /**
- * Log a message object at level VERBOSE.
- *
- * @param msg
- * - the message object to be logged
- */
- public void trace(String msg) {
- log(Log.VERBOSE, msg, null);
- }
-
- /**
- * Log a message at level VERBOSE according to the specified format and
- * argument.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for level VERBOSE.
- * </p>
- *
- * @param format
- * the format string
- * @param arg
- * the argument
- */
- public void trace(String format, Object arg) {
- formatAndLog(Log.VERBOSE, format, arg);
- }
-
- /**
- * Log a message at level VERBOSE according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the VERBOSE level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg1
- * the first argument
- * @param arg2
- * the second argument
- */
- public void trace(String format, Object arg1, Object arg2) {
- formatAndLog(Log.VERBOSE, format, arg1, arg2);
- }
-
- /**
- * Log a message at level VERBOSE according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the VERBOSE level.
- * </p>
- *
- * @param format
- * the format string
- * @param argArray
- * an array of arguments
- */
- public void trace(String format, Object... argArray) {
- formatAndLog(Log.VERBOSE, format, argArray);
- }
-
- /**
- * Log an exception (throwable) at level VERBOSE with an accompanying message.
- *
- * @param msg
- * the message accompanying the exception
- * @param t
- * the exception (throwable) to log
- */
- public void trace(String msg, Throwable t) {
- log(Log.VERBOSE, msg, t);
- }
-
- /**
- * Is this logger instance enabled for the DEBUG level?
- *
- * @return True if this Logger is enabled for level DEBUG, false otherwise.
- */
- public boolean isDebugEnabled() {
- return isLoggable(Log.DEBUG);
- }
-
- /**
- * Log a message object at level DEBUG.
- *
- * @param msg
- * - the message object to be logged
- */
- public void debug(String msg) {
- log(Log.DEBUG, msg, null);
- }
-
- /**
- * Log a message at level DEBUG according to the specified format and argument.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for level DEBUG.
- * </p>
- *
- * @param format
- * the format string
- * @param arg
- * the argument
- */
- public void debug(String format, Object arg) {
- formatAndLog(Log.DEBUG, format, arg);
- }
-
- /**
- * Log a message at level DEBUG according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the DEBUG level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg1
- * the first argument
- * @param arg2
- * the second argument
- */
- public void debug(String format, Object arg1, Object arg2) {
- formatAndLog(Log.DEBUG, format, arg1, arg2);
- }
-
- /**
- * Log a message at level DEBUG according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the DEBUG level.
- * </p>
- *
- * @param format
- * the format string
- * @param argArray
- * an array of arguments
- */
- public void debug(String format, Object... argArray) {
- formatAndLog(Log.DEBUG, format, argArray);
- }
-
- /**
- * Log an exception (throwable) at level DEBUG with an accompanying message.
- *
- * @param msg
- * the message accompanying the exception
- * @param t
- * the exception (throwable) to log
- */
- public void debug(String msg, Throwable t) {
- log(Log.VERBOSE, msg, t);
- }
-
- /**
- * Is this logger instance enabled for the INFO level?
- *
- * @return True if this Logger is enabled for the INFO level, false otherwise.
- */
- public boolean isInfoEnabled() {
- return isLoggable(Log.INFO);
- }
-
- /**
- * Log a message object at the INFO level.
- *
- * @param msg
- * - the message object to be logged
- */
- public void info(String msg) {
- log(Log.INFO, msg, null);
- }
-
- /**
- * Log a message at level INFO according to the specified format and argument.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the INFO level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg
- * the argument
- */
- public void info(String format, Object arg) {
- formatAndLog(Log.INFO, format, arg);
- }
-
- /**
- * Log a message at the INFO level according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the INFO level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg1
- * the first argument
- * @param arg2
- * the second argument
- */
- public void info(String format, Object arg1, Object arg2) {
- formatAndLog(Log.INFO, format, arg1, arg2);
- }
-
- /**
- * Log a message at level INFO according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the INFO level.
- * </p>
- *
- * @param format
- * the format string
- * @param argArray
- * an array of arguments
- */
- public void info(String format, Object... argArray) {
- formatAndLog(Log.INFO, format, argArray);
- }
-
- /**
- * Log an exception (throwable) at the INFO level with an accompanying
- * message.
- *
- * @param msg
- * the message accompanying the exception
- * @param t
- * the exception (throwable) to log
- */
- public void info(String msg, Throwable t) {
- log(Log.INFO, msg, t);
- }
-
- /**
- * Is this logger instance enabled for the WARN level?
- *
- * @return True if this Logger is enabled for the WARN level, false
- * otherwise.
- */
- public boolean isWarnEnabled() {
- return isLoggable(Log.WARN);
- }
-
- /**
- * Log a message object at the WARN level.
- *
- * @param msg
- * - the message object to be logged
- */
- public void warn(String msg) {
- log(Log.WARN, msg, null);
- }
-
- /**
- * Log a message at the WARN level according to the specified format and
- * argument.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the WARN level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg
- * the argument
- */
- public void warn(String format, Object arg) {
- formatAndLog(Log.WARN, format, arg);
- }
-
- /**
- * Log a message at the WARN level according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the WARN level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg1
- * the first argument
- * @param arg2
- * the second argument
- */
- public void warn(String format, Object arg1, Object arg2) {
- formatAndLog(Log.WARN, format, arg1, arg2);
- }
-
- /**
- * Log a message at level WARN according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the WARN level.
- * </p>
- *
- * @param format
- * the format string
- * @param argArray
- * an array of arguments
- */
- public void warn(String format, Object... argArray) {
- formatAndLog(Log.WARN, format, argArray);
- }
-
- /**
- * Log an exception (throwable) at the WARN level with an accompanying
- * message.
- *
- * @param msg
- * the message accompanying the exception
- * @param t
- * the exception (throwable) to log
- */
- public void warn(String msg, Throwable t) {
- log(Log.WARN, msg, t);
- }
-
- /**
- * Is this logger instance enabled for level ERROR?
- *
- * @return True if this Logger is enabled for level ERROR, false otherwise.
- */
- public boolean isErrorEnabled() {
- return isLoggable(Log.ERROR);
- }
-
- /**
- * Log a message object at the ERROR level.
- *
- * @param msg
- * - the message object to be logged
- */
- public void error(String msg) {
- log(Log.ERROR, msg, null);
- }
-
- /**
- * Log a message at the ERROR level according to the specified format and
- * argument.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the ERROR level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg
- * the argument
- */
- public void error(String format, Object arg) {
- formatAndLog(Log.ERROR, format, arg);
- }
-
- /**
- * Log a message at the ERROR level according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the ERROR level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg1
- * the first argument
- * @param arg2
- * the second argument
- */
- public void error(String format, Object arg1, Object arg2) {
- formatAndLog(Log.ERROR, format, arg1, arg2);
- }
-
- /**
- * Log a message at level ERROR according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the ERROR level.
- * </p>
- *
- * @param format
- * the format string
- * @param argArray
- * an array of arguments
- */
- public void error(String format, Object... argArray) {
- formatAndLog(Log.ERROR, format, argArray);
- }
-
- /**
- * Log an exception (throwable) at the ERROR level with an accompanying
- * message.
- *
- * @param msg
- * the message accompanying the exception
- * @param t
- * the exception (throwable) to log
- */
- public void error(String msg, Throwable t) {
- log(Log.ERROR, msg, t);
- }
-
- private void formatAndLog(int priority, String format, Object... argArray) {
- if (isLoggable(priority)) {
- FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
- _log(priority, ft.getMessage(), ft.getThrowable());
- }
- }
-
- private void log(int priority, String message, Throwable throwable) {
- if (isLoggable(priority)) {
- _log(priority, message, throwable);
- }
- }
-
- private boolean isLoggable(int priority) {
- return Log.isLoggable(name, priority);
- }
-
- private void _log(int priority, String message, Throwable throwable) {
- if (throwable != null) {
- message += '\n' + Log.getStackTraceString(throwable);
- }
- Log.println(priority, name, message);
- }
-} \ No newline at end of file
diff --git a/slf4j-android/src/main/java/org/slf4j/impl/AndroidLoggerFactory.java b/slf4j-android/src/main/java/org/slf4j/impl/AndroidLoggerFactory.java
deleted file mode 100755
index f27ff551..00000000
--- a/slf4j-android/src/main/java/org/slf4j/impl/AndroidLoggerFactory.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2004-2013 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 org.slf4j.ILoggerFactory;
-import org.slf4j.Logger;
-
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-/**
- * AndroidLoggerFactory is an implementation of {@link ILoggerFactory} returning
- * the appropriately named {@link AndroidLoggerFactory} instance.
- *
- * @author Andrey Korzhevskiy <a.korzhevskiy@gmail.com>
- */
-class AndroidLoggerFactory implements ILoggerFactory {
- static final String ANONYMOUS_TAG = "null";
- static final int TAG_MAX_LENGTH = 23;
-
- private final ConcurrentMap<String, Logger> loggerMap = new ConcurrentHashMap<String, Logger>();
-
- /**
- * Return an appropriate {@link AndroidLoggerAdapter} instance by name.
- */
- public Logger getLogger(String name) {
- String tag = loggerNameToTag(name);
- Logger logger = loggerMap.get(tag);
- if (logger == null) {
- Logger newInstance = new AndroidLoggerAdapter(tag);
- Logger oldInstance = loggerMap.putIfAbsent(tag, newInstance);
- logger = oldInstance == null ? newInstance : oldInstance;
- }
- return logger;
- }
-
- /**
- * Tag names cannot be longer than {@value #TAG_MAX_LENGTH} characters on Android platform.
- *
- * Returns the short logger tag (up to {@value #TAG_MAX_LENGTH} characters) for the given logger name.
- * Traditionally loggers are named by fully-qualified Java classes; this
- * method attempts to return a concise identifying part of such names.
- *
- * See also:
- * android/system/core/include/cutils/property.h
- * android/frameworks/base/core/jni/android_util_Log.cpp
- * dalvik.system.DalvikLogging
- *
- */
- static String loggerNameToTag(String loggerName) {
- // Anonymous logger
- if (loggerName == null) {
- return ANONYMOUS_TAG;
- }
-
- int length = loggerName.length();
- if (length <= TAG_MAX_LENGTH) {
- return loggerName;
- }
-
- int tagLength = 0;
- int lastTokenIndex = 0;
- int lastPeriodIndex;
- StringBuilder tagName = new StringBuilder(TAG_MAX_LENGTH + 3);
- while ((lastPeriodIndex = loggerName.indexOf('.', lastTokenIndex)) != -1) {
- tagName.append(loggerName.charAt(lastTokenIndex));
- // token of one character appended as is otherwise truncate it to one character
- int tokenLength = lastPeriodIndex - lastTokenIndex;
- if (tokenLength > 1) {
- tagName.append('*');
- }
- tagName.append('.');
- lastTokenIndex = lastPeriodIndex + 1;
-
- // check if name is already too long
- tagLength = tagName.length();
- if (tagLength > TAG_MAX_LENGTH) {
- return getSimpleName(loggerName);
- }
- }
-
- // Either we had no useful dot location at all
- // or last token would exceed TAG_MAX_LENGTH
- int tokenLength = length - lastTokenIndex;
- if (tagLength == 0 || (tagLength + tokenLength) > TAG_MAX_LENGTH) {
- return getSimpleName(loggerName);
- }
-
- // last token (usually class name) appended as is
- tagName.append(loggerName, lastTokenIndex, length);
- return tagName.toString();
- }
-
- private static String getSimpleName(String loggerName) {
- // Take leading part and append '*' to indicate that it was truncated
- int length = loggerName.length();
- int lastPeriodIndex = loggerName.lastIndexOf('.');
- return lastPeriodIndex != -1 && length - (lastPeriodIndex + 1) <= TAG_MAX_LENGTH
- ? loggerName.substring(lastPeriodIndex + 1)
- : '*' + loggerName.substring(length - TAG_MAX_LENGTH + 1);
- }
-} \ No newline at end of file
diff --git a/slf4j-android/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/slf4j-android/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
deleted file mode 100644
index 7817d9bf..00000000
--- a/slf4j-android/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * Copyright (c) 2004-2013 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 org.slf4j.ILoggerFactory;
-import org.slf4j.LoggerFactory;
-import org.slf4j.spi.LoggerFactoryBinder;
-
-/**
- * The binding of {@link LoggerFactory} class with an actual instance of
- * {@link ILoggerFactory} is performed using information returned by this class.
- *
- * @author Ceki G&uuml;lc&uuml;
- * @author Andrey Korzhevskiy <a.korzhevskiy@gmail.com>
- */
-public class StaticLoggerBinder implements LoggerFactoryBinder {
-
- /**
- * The unique instance of this class.
- */
- private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
-
- /**
- * Return the singleton of this class.
- *
- * @return the StaticLoggerBinder singleton
- */
- public static StaticLoggerBinder getSingleton() {
- return SINGLETON;
- }
-
- /**
- * Declare the version of the SLF4J API this implementation is compiled against.
- * The value of this field is usually modified with each release.
- */
- // to avoid constant folding by the compiler, this field must *not* be final
- public static String REQUESTED_API_VERSION = "1.6.99"; // !final
-
-
- private static final String loggerFactoryClassStr = AndroidLoggerFactory.class.getName();
-
- /**
- * The ILoggerFactory instance returned by the {@link #getLoggerFactory} method
- * should always be the same object
- */
- private final ILoggerFactory loggerFactory;
-
- private StaticLoggerBinder() {
- loggerFactory = new AndroidLoggerFactory();
- }
-
- public ILoggerFactory getLoggerFactory() {
- return loggerFactory;
- }
-
- public String getLoggerFactoryClassStr() {
- return loggerFactoryClassStr;
- }
-}
diff --git a/slf4j-android/src/main/java/org/slf4j/impl/StaticMDCBinder.java b/slf4j-android/src/main/java/org/slf4j/impl/StaticMDCBinder.java
deleted file mode 100644
index a484c525..00000000
--- a/slf4j-android/src/main/java/org/slf4j/impl/StaticMDCBinder.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * Copyright (c) 2004-2013 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 org.slf4j.helpers.NOPMDCAdapter;
-import org.slf4j.spi.MDCAdapter;
-
-
-/**
- * This implementation is bound to {@link NOPMDCAdapter}.
- *
- * @author Ceki G&uuml;lc&uuml;
- * @author Andrey Korzhevskiy <a.korzhevskiy@gmail.com>
- */
-public class StaticMDCBinder {
-
- /**
- * The unique instance of this class.
- */
- public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
-
- private StaticMDCBinder() {
- }
-
- /**
- * Currently this method always returns an instance of
- * {@link NOPMDCAdapter}.
- */
- public MDCAdapter getMDCA() {
- return new NOPMDCAdapter();
- }
-
- public String getMDCAdapterClassStr() {
- return NOPMDCAdapter.class.getName();
- }
-}
diff --git a/slf4j-android/src/main/java/org/slf4j/impl/StaticMarkerBinder.java b/slf4j-android/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
deleted file mode 100644
index 52b05bac..00000000
--- a/slf4j-android/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * Copyright (c) 2004-2013 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 org.slf4j.IMarkerFactory;
-import org.slf4j.MarkerFactory;
-import org.slf4j.helpers.BasicMarkerFactory;
-import org.slf4j.spi.MarkerFactoryBinder;
-
-/**
- *
- * The binding of {@link MarkerFactory} class with an actual instance of
- * {@link IMarkerFactory} is performed using information returned by this class.
- *
- * @author Ceki G&uuml;lc&uuml;
- * @author Andrey Korzhevskiy <a.korzhevskiy@gmail.com>
- */
-public class StaticMarkerBinder implements MarkerFactoryBinder {
-
- /**
- * The unique instance of this class.
- */
- public static final StaticMarkerBinder SINGLETON = new StaticMarkerBinder();
-
- final IMarkerFactory markerFactory = new BasicMarkerFactory();
-
- private StaticMarkerBinder() {
- }
-
- /**
- * Currently this method always returns an instance of
- * {@link BasicMarkerFactory}.
- */
- public IMarkerFactory getMarkerFactory() {
- return markerFactory;
- }
-
- /**
- * Currently, this method returns the class name of
- * {@link BasicMarkerFactory}.
- */
- public String getMarkerFactoryClassStr() {
- return BasicMarkerFactory.class.getName();
- }
-}
diff --git a/slf4j-android/src/main/resources/META-INF/MANIFEST.MF b/slf4j-android/src/main/resources/META-INF/MANIFEST.MF
deleted file mode 100644
index d71f94cb..00000000
--- a/slf4j-android/src/main/resources/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,9 +0,0 @@
-Implementation-Title: slf4j-android
-Bundle-ManifestVersion: 2
-Bundle-SymbolicName: slf4j.android
-Bundle-Name: slf4j-android
-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}
-Fragment-Host: slf4j.api \ No newline at end of file
diff --git a/slf4j-android/src/test/java/org/slf4j/impl/AndroidLoggerFactoryTest.java b/slf4j-android/src/test/java/org/slf4j/impl/AndroidLoggerFactoryTest.java
deleted file mode 100644
index 5c854892..00000000
--- a/slf4j-android/src/test/java/org/slf4j/impl/AndroidLoggerFactoryTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2004-2013 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 org.junit.Test;
-
-import static junit.framework.Assert.assertEquals;
-
-public class AndroidLoggerFactoryTest {
- @Test
- public void shortLoggerNames() {
- assertEquals("o.test.p.TestClass", AndroidLoggerFactory.loggerNameToTag("o.test.p.TestClass"));
- assertEquals("ex.test.TestClass", AndroidLoggerFactory.loggerNameToTag("ex.test.TestClass"));
- assertEquals("MyClass", AndroidLoggerFactory.loggerNameToTag("MyClass"));
- }
-
- @Test
- public void emptyLoggerNames() {
- assertEquals(AndroidLoggerFactory.ANONYMOUS_TAG, AndroidLoggerFactory.loggerNameToTag(null));
- assertEquals("", AndroidLoggerFactory.loggerNameToTag(""));
- }
-
- @Test
- public void simpleLoggerName() {
- assertEquals("o*.t*.p*.TestClass", AndroidLoggerFactory.loggerNameToTag("org.test.package.TestClass"));
- }
-
- @Test
- public void loggerNameWithOneCharPackage() {
- assertEquals("o.t*.p*.p*.TestClass", AndroidLoggerFactory.loggerNameToTag("o.test.project.package.TestClass"));
- assertEquals("o.t*.p*.p.TestClass", AndroidLoggerFactory.loggerNameToTag("o.test.project.p.TestClass"));
- }
-
- @Test
- public void longLoggerName() {
- assertEquals("AndroidLoggerFactory", AndroidLoggerFactory.loggerNameToTag("org.slf4j.impl.AndroidLoggerFactory"));
- }
-
- @Test
- public void veryLongLoggerName() {
- assertEquals("*meAndShouldBeTruncated", AndroidLoggerFactory.loggerNameToTag("IAmAVeryLongLoggerNameAndShouldBeTruncated"));
- }
-
- @Test
- public void oneWordLoggerName() {
- assertEquals("TestClass", AndroidLoggerFactory.loggerNameToTag("TestClass"));
- }
-
- @Test
- public void weirdLoggerNames() {
- assertEquals("WeirdLoggerName.", AndroidLoggerFactory.loggerNameToTag("WeirdLoggerName."));
- assertEquals(".WeirdLoggerName", AndroidLoggerFactory.loggerNameToTag(".WeirdLoggerName"));
- assertEquals(".WeirdLoggerName.", AndroidLoggerFactory.loggerNameToTag(".WeirdLoggerName."));
- assertEquals(".", AndroidLoggerFactory.loggerNameToTag("."));
- assertEquals("..", AndroidLoggerFactory.loggerNameToTag(".."));
- }
-}
diff --git a/slf4j-api/Android.bp b/slf4j-api/Android.bp
new file mode 100644
index 00000000..a47edb0b
--- /dev/null
+++ b/slf4j-api/Android.bp
@@ -0,0 +1,25 @@
+//
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+java_library_host {
+ name: "slf4j-api",
+ srcs: ["src/main/java/**/*.java"],
+ target: {
+ windows: {
+ enabled: true,
+ },
+ },
+}
diff --git a/slf4j-api/LICENSE.txt b/slf4j-api/LICENSE.txt
index 508a2728..e4079f54 100644
--- a/slf4j-api/LICENSE.txt
+++ b/slf4j-api/LICENSE.txt
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2007 QOS.ch
+Copyright (c) 2004-2023 QOS.ch
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/slf4j-api/pom.xml b/slf4j-api/pom.xml
index 6d1f6ba7..e8460b21 100755
--- a/slf4j-api/pom.xml
+++ b/slf4j-api/pom.xml
@@ -1,5 +1,5 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
@@ -7,7 +7,8 @@
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
- <version>1.7.13-SNAPSHOT</version>
+ <version>2.0.12</version>
+ <relativePath>../parent/pom.xml</relativePath>
</parent>
<artifactId>slf4j-api</artifactId>
@@ -18,8 +19,9 @@
<url>http://www.slf4j.org</url>
- <dependencies>
- </dependencies>
+ <properties>
+ <module-name>org.slf4j</module-name>
+ </properties>
<build>
<plugins>
@@ -40,22 +42,12 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <archive>
- <manifestEntries>
- <Bundle-Version>${parsedVersion.osgiVersion}</Bundle-Version>
- <Bundle-Description>${project.description}</Bundle-Description>
- <Implementation-Version>${project.version}</Implementation-Version>
- </manifestEntries>
- <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
- </archive>
- </configuration>
+ <version>${maven-jar-plugin.version}</version>
<executions>
<execution>
<id>bundle-test-jar</id>
<phase>package</phase>
<goals>
- <goal>jar</goal>
<goal>test-jar</goal>
</goals>
</execution>
@@ -63,21 +55,22 @@
</plugin>
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-antrun-plugin</artifactId>
- <executions>
- <execution>
- <phase>process-classes</phase>
- <goals>
- <goal>run</goal>
- </goals>
- </execution>
- </executions>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
<configuration>
- <tasks>
- <echo>Removing slf4j-api's dummy StaticLoggerBinder and StaticMarkerBinder</echo>
- <delete dir="target/classes/org/slf4j/impl"/>
- </tasks>
+ <instructions>
+ <Import-Package>org.slf4j.spi;version="${range;[===,+);${version_cleanup;${project.version}}}"</Import-Package>
+ <!-- Export the client/user package of slf4j-api version 1 to make the slf4j-api bundle in version 2 usable for bundles that only import slf4j-1.x -->
+ <_exportcontents><![CDATA[
+ *,\
+ org.slf4j;version="${latest.1.version}",\
+ org.slf4j.helpers;version="${latest.1.version}"
+ ]]></_exportcontents>
+ <Require-Capability><![CDATA[
+ osgi.extender;filter:="(&(osgi.extender=osgi.serviceloader.processor)(version>=1.0.0)(!(version>=2.0.0)))",
+ osgi.serviceloader;filter:="(osgi.serviceloader=org.slf4j.spi.SLF4JServiceProvider)";osgi.serviceloader="org.slf4j.spi.SLF4JServiceProvider"
+ ]]></Require-Capability>
+ </instructions>
</configuration>
</plugin>
@@ -85,4 +78,4 @@
</build>
-</project> \ No newline at end of file
+</project>
diff --git a/slf4j-api/src/main/java/org/slf4j/ILoggerFactory.java b/slf4j-api/src/main/java/org/slf4j/ILoggerFactory.java
index 8ed82f3c..6fec242c 100644
--- a/slf4j-api/src/main/java/org/slf4j/ILoggerFactory.java
+++ b/slf4j-api/src/main/java/org/slf4j/ILoggerFactory.java
@@ -29,7 +29,7 @@ package org.slf4j;
* instances by name.
*
* <p>Most users retrieve {@link Logger} instances through the static
- * {@link LoggerFactory#getLogger(String)} method. An instance of of this
+ * {@link LoggerFactory#getLogger(String)} method. An instance of this
* interface is bound internally with {@link LoggerFactory} class at
* compile time.
*
diff --git a/slf4j-api/src/main/java/org/slf4j/Logger.java b/slf4j-api/src/main/java/org/slf4j/Logger.java
index 93dd9945..2803f782 100644
--- a/slf4j-api/src/main/java/org/slf4j/Logger.java
+++ b/slf4j-api/src/main/java/org/slf4j/Logger.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2004-2011 QOS.ch
+ * Copyright (c) 2004-2022 QOS.ch
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
@@ -25,12 +25,29 @@
package org.slf4j;
+import static org.slf4j.event.EventConstants.DEBUG_INT;
+import static org.slf4j.event.EventConstants.ERROR_INT;
+import static org.slf4j.event.EventConstants.INFO_INT;
+import static org.slf4j.event.EventConstants.TRACE_INT;
+import static org.slf4j.event.EventConstants.WARN_INT;
+import static org.slf4j.event.Level.DEBUG;
+import static org.slf4j.event.Level.ERROR;
+import static org.slf4j.event.Level.INFO;
+import static org.slf4j.event.Level.TRACE;
+import static org.slf4j.event.Level.WARN;
+
+import org.slf4j.event.Level;
+import org.slf4j.helpers.CheckReturnValue;
+import org.slf4j.spi.DefaultLoggingEventBuilder;
+import org.slf4j.spi.LoggingEventBuilder;
+import org.slf4j.spi.NOPLoggingEventBuilder;
+
/**
* The org.slf4j.Logger interface is the main user entry point of SLF4J API.
* It is expected that logging takes place through concrete implementations
* of this interface.
- * <p/>
- * <h3>Typical usage pattern:</h3>
+ *
+ * <H3>Typical usage pattern:</H3>
* <pre>
* import org.slf4j.Logger;
* import org.slf4j.LoggerFactory;
@@ -45,26 +62,29 @@ package org.slf4j;
* oldT = t;
* t = temperature;
* <span style="color:green">logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);</span>
- * if(temperature.intValue() > 50) {
+ * if (temperature.intValue() &gt; 50) {
* <span style="color:green">logger.info("Temperature has risen above 50 degrees.");</span>
* }
* }
* }
* </pre>
*
- * Be sure to read the FAQ entry relating to <a href="../../../faq.html#logging_performance">parameterized
+ * <p>Note that version 2.0 of the SLF4J API introduces a <a href="../../../manual.html#fluent">fluent api</a>,
+ * the most significant API change to occur in the last 20 years.
+ *
+ * <p>Be sure to read the FAQ entry relating to <a href="../../../faq.html#logging_performance">parameterized
* logging</a>. Note that logging statements can be parameterized in
* <a href="../../../faq.html#paramException">presence of an exception/throwable</a>.
*
* <p>Once you are comfortable using loggers, i.e. instances of this interface, consider using
- * <a href="MDC.html">MDC</a> as well as <a href="Marker.html">Markers</a>.</p>
+ * <a href="MDC.html">MDC</a> as well as <a href="Marker.html">Markers</a>.
*
* @author Ceki G&uuml;lc&uuml;
*/
public interface Logger {
/**
- * Case insensitive String constant used to retrieve the name of the root logger.
+ * Case-insensitive String constant used to retrieve the name of the root logger.
*
* @since 1.3
*/
@@ -77,6 +97,70 @@ public interface Logger {
public String getName();
/**
+ * <p>Make a new {@link LoggingEventBuilder} instance as appropriate for this logger implementation.
+ * This default implementation always returns a new instance of {@link DefaultLoggingEventBuilder}.</p>
+ * <p></p>
+ * <p>This method is intended to be used by logging systems implementing the SLF4J API and <b>not</b>
+ * by end users.</p>
+ * <p></p>
+ * <p>Also note that a {@link LoggingEventBuilder} instance should be built for all levels,
+ * independently of the level argument. In other words, this method is an <b>unconditional</b>
+ * constructor for the {@link LoggingEventBuilder} appropriate for this logger implementation.</p>
+ * <p></p>
+ * @param level desired level for the event builder
+ * @return a new {@link LoggingEventBuilder} instance as appropriate for <b>this</b> logger
+ * @since 2.0
+ */
+ default public LoggingEventBuilder makeLoggingEventBuilder(Level level) {
+ return new DefaultLoggingEventBuilder(this, level);
+ }
+
+ /**
+ * Make a new {@link LoggingEventBuilder} instance as appropriate for this logger and the
+ * desired {@link Level} passed as parameter. If this Logger is disabled for the given Level, then
+ * a {@link NOPLoggingEventBuilder} is returned.
+ *
+ *
+ * @param level desired level for the event builder
+ * @return a new {@link LoggingEventBuilder} instance as appropriate for this logger
+ * @since 2.0
+ */
+ @CheckReturnValue
+ default public LoggingEventBuilder atLevel(Level level) {
+ if (isEnabledForLevel(level)) {
+ return makeLoggingEventBuilder(level);
+ } else {
+ return NOPLoggingEventBuilder.singleton();
+ }
+ }
+
+
+
+ /**
+ * Returns whether this Logger is enabled for a given {@link Level}.
+ *
+ * @param level
+ * @return true if enabled, false otherwise.
+ */
+ default public boolean isEnabledForLevel(Level level) {
+ int levelInt = level.toInt();
+ switch (levelInt) {
+ case (TRACE_INT):
+ return isTraceEnabled();
+ case (DEBUG_INT):
+ return isDebugEnabled();
+ case (INFO_INT):
+ return isInfoEnabled();
+ case (WARN_INT):
+ return isWarnEnabled();
+ case (ERROR_INT):
+ return isErrorEnabled();
+ default:
+ throw new IllegalArgumentException("Level [" + level + "] not recognized.");
+ }
+ }
+
+ /**
* Is the logger instance enabled for the TRACE level?
*
* @return True if this Logger is enabled for the TRACE level,
@@ -96,9 +180,9 @@ public interface Logger {
/**
* Log a message at the TRACE level according to the specified format
* and argument.
- * <p/>
+ *
* <p>This form avoids superfluous object creation when the logger
- * is disabled for the TRACE level. </p>
+ * is disabled for the TRACE level.
*
* @param format the format string
* @param arg the argument
@@ -109,9 +193,9 @@ public interface Logger {
/**
* Log a message at the TRACE level according to the specified format
* and arguments.
- * <p/>
+ *
* <p>This form avoids superfluous object creation when the logger
- * is disabled for the TRACE level. </p>
+ * is disabled for the TRACE level.
*
* @param format the format string
* @param arg1 the first argument
@@ -123,12 +207,12 @@ public interface Logger {
/**
* Log a message at the TRACE level according to the specified format
* and arguments.
- * <p/>
+ *
* <p>This form avoids superfluous string concatenation when the logger
* is disabled for the TRACE level. However, this variant incurs the hidden
* (and relatively small) cost of creating an <code>Object[]</code> before invoking the method,
* even if this logger is disabled for TRACE. The variants taking {@link #trace(String, Object) one} and
- * {@link #trace(String, Object, Object) two} arguments exist solely in order to avoid this hidden cost.</p>
+ * {@link #trace(String, Object, Object) two} arguments exist solely in order to avoid this hidden cost.
*
* @param format the format string
* @param arguments a list of 3 or more arguments
@@ -159,6 +243,21 @@ public interface Logger {
public boolean isTraceEnabled(Marker marker);
/**
+ * Entry point for fluent-logging for {@link org.slf4j.event.Level#TRACE} level.
+ *
+ * @return LoggingEventBuilder instance as appropriate for level TRACE
+ * @since 2.0
+ */
+ @CheckReturnValue
+ default public LoggingEventBuilder atTrace() {
+ if (isTraceEnabled()) {
+ return makeLoggingEventBuilder(TRACE);
+ } else {
+ return NOPLoggingEventBuilder.singleton();
+ }
+ }
+
+ /**
* Log a message with the specific Marker at the TRACE level.
*
* @param marker the marker data specific to this log statement
@@ -232,9 +331,9 @@ public interface Logger {
/**
* Log a message at the DEBUG level according to the specified format
* and argument.
- * <p/>
+ *
* <p>This form avoids superfluous object creation when the logger
- * is disabled for the DEBUG level. </p>
+ * is disabled for the DEBUG level.
*
* @param format the format string
* @param arg the argument
@@ -244,9 +343,9 @@ public interface Logger {
/**
* Log a message at the DEBUG level according to the specified format
* and arguments.
- * <p/>
+ *
* <p>This form avoids superfluous object creation when the logger
- * is disabled for the DEBUG level. </p>
+ * is disabled for the DEBUG level.
*
* @param format the format string
* @param arg1 the first argument
@@ -257,13 +356,13 @@ public interface Logger {
/**
* Log a message at the DEBUG level according to the specified format
* and arguments.
- * <p/>
+ *
* <p>This form avoids superfluous string concatenation when the logger
* is disabled for the DEBUG level. However, this variant incurs the hidden
* (and relatively small) cost of creating an <code>Object[]</code> before invoking the method,
* even if this logger is disabled for DEBUG. The variants taking
* {@link #debug(String, Object) one} and {@link #debug(String, Object, Object) two}
- * arguments exist solely in order to avoid this hidden cost.</p>
+ * arguments exist solely in order to avoid this hidden cost.
*
* @param format the format string
* @param arguments a list of 3 or more arguments
@@ -341,6 +440,21 @@ public interface Logger {
public void debug(Marker marker, String msg, Throwable t);
/**
+ * Entry point for fluent-logging for {@link org.slf4j.event.Level#DEBUG} level.
+ *
+ * @return LoggingEventBuilder instance as appropriate for level DEBUG
+ * @since 2.0
+ */
+ @CheckReturnValue
+ default public LoggingEventBuilder atDebug() {
+ if (isDebugEnabled()) {
+ return makeLoggingEventBuilder(DEBUG);
+ } else {
+ return NOPLoggingEventBuilder.singleton();
+ }
+ }
+
+ /**
* Is the logger instance enabled for the INFO level?
*
* @return True if this Logger is enabled for the INFO level,
@@ -358,9 +472,9 @@ public interface Logger {
/**
* Log a message at the INFO level according to the specified format
* and argument.
- * <p/>
+ *
* <p>This form avoids superfluous object creation when the logger
- * is disabled for the INFO level. </p>
+ * is disabled for the INFO level.
*
* @param format the format string
* @param arg the argument
@@ -370,9 +484,9 @@ public interface Logger {
/**
* Log a message at the INFO level according to the specified format
* and arguments.
- * <p/>
+ *
* <p>This form avoids superfluous object creation when the logger
- * is disabled for the INFO level. </p>
+ * is disabled for the INFO level.
*
* @param format the format string
* @param arg1 the first argument
@@ -383,13 +497,13 @@ public interface Logger {
/**
* Log a message at the INFO level according to the specified format
* and arguments.
- * <p/>
+ *
* <p>This form avoids superfluous string concatenation when the logger
* is disabled for the INFO level. However, this variant incurs the hidden
* (and relatively small) cost of creating an <code>Object[]</code> before invoking the method,
* even if this logger is disabled for INFO. The variants taking
* {@link #info(String, Object) one} and {@link #info(String, Object, Object) two}
- * arguments exist solely in order to avoid this hidden cost.</p>
+ * arguments exist solely in order to avoid this hidden cost.
*
* @param format the format string
* @param arguments a list of 3 or more arguments
@@ -410,7 +524,8 @@ public interface Logger {
* data is also taken into consideration.
*
* @param marker The marker data to take into consideration
- * @return true if this logger is warn enabled, false otherwise
+ * @return true if this Logger is enabled for the INFO level,
+ * false otherwise.
*/
public boolean isInfoEnabled(Marker marker);
@@ -466,6 +581,21 @@ public interface Logger {
public void info(Marker marker, String msg, Throwable t);
/**
+ * Entry point for fluent-logging for {@link org.slf4j.event.Level#INFO} level.
+ *
+ * @return LoggingEventBuilder instance as appropriate for level INFO
+ * @since 2.0
+ */
+ @CheckReturnValue
+ default public LoggingEventBuilder atInfo() {
+ if (isInfoEnabled()) {
+ return makeLoggingEventBuilder(INFO);
+ } else {
+ return NOPLoggingEventBuilder.singleton();
+ }
+ }
+
+ /**
* Is the logger instance enabled for the WARN level?
*
* @return True if this Logger is enabled for the WARN level,
@@ -483,9 +613,9 @@ public interface Logger {
/**
* Log a message at the WARN level according to the specified format
* and argument.
- * <p/>
+ *
* <p>This form avoids superfluous object creation when the logger
- * is disabled for the WARN level. </p>
+ * is disabled for the WARN level.
*
* @param format the format string
* @param arg the argument
@@ -495,13 +625,13 @@ public interface Logger {
/**
* Log a message at the WARN level according to the specified format
* and arguments.
- * <p/>
+ *
* <p>This form avoids superfluous string concatenation when the logger
* is disabled for the WARN level. However, this variant incurs the hidden
* (and relatively small) cost of creating an <code>Object[]</code> before invoking the method,
* even if this logger is disabled for WARN. The variants taking
* {@link #warn(String, Object) one} and {@link #warn(String, Object, Object) two}
- * arguments exist solely in order to avoid this hidden cost.</p>
+ * arguments exist solely in order to avoid this hidden cost.
*
* @param format the format string
* @param arguments a list of 3 or more arguments
@@ -511,9 +641,9 @@ public interface Logger {
/**
* Log a message at the WARN level according to the specified format
* and arguments.
- * <p/>
+ *
* <p>This form avoids superfluous object creation when the logger
- * is disabled for the WARN level. </p>
+ * is disabled for the WARN level.
*
* @param format the format string
* @param arg1 the first argument
@@ -592,6 +722,21 @@ public interface Logger {
public void warn(Marker marker, String msg, Throwable t);
/**
+ * Entry point for fluent-logging for {@link org.slf4j.event.Level#WARN} level.
+ *
+ * @return LoggingEventBuilder instance as appropriate for level WARN
+ * @since 2.0
+ */
+ @CheckReturnValue
+ default public LoggingEventBuilder atWarn() {
+ if (isWarnEnabled()) {
+ return makeLoggingEventBuilder(WARN);
+ } else {
+ return NOPLoggingEventBuilder.singleton();
+ }
+ }
+
+ /**
* Is the logger instance enabled for the ERROR level?
*
* @return True if this Logger is enabled for the ERROR level,
@@ -609,9 +754,9 @@ public interface Logger {
/**
* Log a message at the ERROR level according to the specified format
* and argument.
- * <p/>
+ *
* <p>This form avoids superfluous object creation when the logger
- * is disabled for the ERROR level. </p>
+ * is disabled for the ERROR level.
*
* @param format the format string
* @param arg the argument
@@ -621,9 +766,9 @@ public interface Logger {
/**
* Log a message at the ERROR level according to the specified format
* and arguments.
- * <p/>
+ *
* <p>This form avoids superfluous object creation when the logger
- * is disabled for the ERROR level. </p>
+ * is disabled for the ERROR level.
*
* @param format the format string
* @param arg1 the first argument
@@ -634,13 +779,13 @@ public interface Logger {
/**
* Log a message at the ERROR level according to the specified format
* and arguments.
- * <p/>
+ *
* <p>This form avoids superfluous string concatenation when the logger
* is disabled for the ERROR level. However, this variant incurs the hidden
* (and relatively small) cost of creating an <code>Object[]</code> before invoking the method,
* even if this logger is disabled for ERROR. The variants taking
* {@link #error(String, Object) one} and {@link #error(String, Object, Object) two}
- * arguments exist solely in order to avoid this hidden cost.</p>
+ * arguments exist solely in order to avoid this hidden cost.
*
* @param format the format string
* @param arguments a list of 3 or more arguments
@@ -718,4 +863,19 @@ public interface Logger {
*/
public void error(Marker marker, String msg, Throwable t);
+ /**
+ * Entry point for fluent-logging for {@link org.slf4j.event.Level#ERROR} level.
+ *
+ * @return LoggingEventBuilder instance as appropriate for level ERROR
+ * @since 2.0
+ */
+ @CheckReturnValue
+ default public LoggingEventBuilder atError() {
+ if (isErrorEnabled()) {
+ return makeLoggingEventBuilder(ERROR);
+ } else {
+ return NOPLoggingEventBuilder.singleton();
+ }
+ }
+
}
diff --git a/slf4j-api/src/main/java/org/slf4j/LoggerFactory.java b/slf4j-api/src/main/java/org/slf4j/LoggerFactory.java
index 2f74c18b..4e1f0b0d 100755
--- a/slf4j-api/src/main/java/org/slf4j/LoggerFactory.java
+++ b/slf4j-api/src/main/java/org/slf4j/LoggerFactory.java
@@ -25,34 +25,41 @@
package org.slf4j;
import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.ServiceConfigurationError;
+import java.util.ServiceLoader;
import java.util.Set;
+import java.util.concurrent.LinkedBlockingQueue;
-import org.slf4j.helpers.NOPLoggerFactory;
+import org.slf4j.event.SubstituteLoggingEvent;
+import org.slf4j.helpers.NOP_FallbackServiceProvider;
+import org.slf4j.helpers.Reporter;
import org.slf4j.helpers.SubstituteLogger;
-import org.slf4j.helpers.SubstituteLoggerFactory;
+import org.slf4j.helpers.SubstituteServiceProvider;
import org.slf4j.helpers.Util;
-import org.slf4j.impl.StaticLoggerBinder;
+import org.slf4j.spi.SLF4JServiceProvider;
/**
* The <code>LoggerFactory</code> is a utility class producing Loggers for
- * various logging APIs, most notably for log4j, logback and JDK 1.4 logging.
- * Other implementations such as {@link org.slf4j.impl.NOPLogger NOPLogger} and
- * {@link org.slf4j.impl.SimpleLogger SimpleLogger} are also supported.
- * <p/>
- * <p/>
- * <code>LoggerFactory</code> is essentially a wrapper around an
- * {@link ILoggerFactory} instance bound with <code>LoggerFactory</code> at
- * compile time.
- * <p/>
- * <p/>
- * Please note that all methods in <code>LoggerFactory</code> are static.
+ * various logging APIs, e.g. logback, reload4j, log4j and JDK 1.4 logging.
+ * Other implementations such as {@link org.slf4j.helpers.NOPLogger NOPLogger} and
+ * SimpleLogger are also supported.
+ *
+ * <p><code>LoggerFactory</code> is essentially a wrapper around an
+ * {@link ILoggerFactory} instance provided by a {@link SLF4JServiceProvider}.
*
+ * <p>
+ * Please note that all methods in <code>LoggerFactory</code> are static.
*
* @author Alexander Dorokhine
* @author Robert Elliot
@@ -61,17 +68,27 @@ import org.slf4j.impl.StaticLoggerBinder;
*/
public final class LoggerFactory {
- static final String CODES_PREFIX = "http://www.slf4j.org/codes.html";
+ static final String CODES_PREFIX = "https://www.slf4j.org/codes.html";
+
+ static final String NO_PROVIDERS_URL = CODES_PREFIX + "#noProviders";
+ static final String IGNORED_BINDINGS_URL = CODES_PREFIX + "#ignoredBindings";
- static final String NO_STATICLOGGERBINDER_URL = CODES_PREFIX + "#StaticLoggerBinder";
static final String MULTIPLE_BINDINGS_URL = CODES_PREFIX + "#multiple_bindings";
- static final String NULL_LF_URL = CODES_PREFIX + "#null_LF";
static final String VERSION_MISMATCH = CODES_PREFIX + "#version_mismatch";
static final String SUBSTITUTE_LOGGER_URL = CODES_PREFIX + "#substituteLogger";
static final String LOGGER_NAME_MISMATCH_URL = CODES_PREFIX + "#loggerNameMismatch";
+ static final String REPLAY_URL = CODES_PREFIX + "#replay";
static final String UNSUCCESSFUL_INIT_URL = CODES_PREFIX + "#unsuccessfulInit";
- static final String UNSUCCESSFUL_INIT_MSG = "org.slf4j.LoggerFactory could not be successfully initialized. See also " + UNSUCCESSFUL_INIT_URL;
+ static final String UNSUCCESSFUL_INIT_MSG = "org.slf4j.LoggerFactory in failed state. Original exception was thrown EARLIER. See also "
+ + UNSUCCESSFUL_INIT_URL;
+ /**
+ * System property for explicitly setting the provider class. If set and the provider could be instantiated,
+ * then the service loading mechanism will be bypassed.
+ *
+ * @since 2.0.9
+ */
+ static final public String PROVIDER_PROPERTY_KEY = "slf4j.provider";
static final int UNINITIALIZED = 0;
static final int ONGOING_INITIALIZATION = 1;
@@ -79,22 +96,69 @@ public final class LoggerFactory {
static final int SUCCESSFUL_INITIALIZATION = 3;
static final int NOP_FALLBACK_INITIALIZATION = 4;
- static int INITIALIZATION_STATE = UNINITIALIZED;
- static SubstituteLoggerFactory TEMP_FACTORY = new SubstituteLoggerFactory();
- static NOPLoggerFactory NOP_FALLBACK_FACTORY = new NOPLoggerFactory();
+ static volatile int INITIALIZATION_STATE = UNINITIALIZED;
+ static final SubstituteServiceProvider SUBST_PROVIDER = new SubstituteServiceProvider();
+ static final NOP_FallbackServiceProvider NOP_FALLBACK_SERVICE_PROVIDER = new NOP_FallbackServiceProvider();
// Support for detecting mismatched logger names.
static final String DETECT_LOGGER_NAME_MISMATCH_PROPERTY = "slf4j.detectLoggerNameMismatch";
- static boolean DETECT_LOGGER_NAME_MISMATCH = Boolean.getBoolean(DETECT_LOGGER_NAME_MISMATCH_PROPERTY);
+ static final String JAVA_VENDOR_PROPERTY = "java.vendor.url";
+
+ static boolean DETECT_LOGGER_NAME_MISMATCH = Util.safeGetBooleanSystemProperty(DETECT_LOGGER_NAME_MISMATCH_PROPERTY);
+
+ static volatile SLF4JServiceProvider PROVIDER;
+
+ // Package access for tests
+ static List<SLF4JServiceProvider> findServiceProviders() {
+ List<SLF4JServiceProvider> providerList = new ArrayList<>();
+
+ // retain behaviour similar to that of 1.7 series and earlier. More specifically, use the class loader that
+ // loaded the present class to search for services
+ final ClassLoader classLoaderOfLoggerFactory = LoggerFactory.class.getClassLoader();
+
+ SLF4JServiceProvider explicitProvider = loadExplicitlySpecified(classLoaderOfLoggerFactory);
+ if(explicitProvider != null) {
+ providerList.add(explicitProvider);
+ return providerList;
+ }
+
+
+ ServiceLoader<SLF4JServiceProvider> serviceLoader = getServiceLoader(classLoaderOfLoggerFactory);
+
+ Iterator<SLF4JServiceProvider> iterator = serviceLoader.iterator();
+ while (iterator.hasNext()) {
+ safelyInstantiate(providerList, iterator);
+ }
+ return providerList;
+ }
+
+ private static ServiceLoader<SLF4JServiceProvider> getServiceLoader(final ClassLoader classLoaderOfLoggerFactory) {
+ ServiceLoader<SLF4JServiceProvider> serviceLoader;
+ SecurityManager securityManager = System.getSecurityManager();
+ if(securityManager == null) {
+ serviceLoader = ServiceLoader.load(SLF4JServiceProvider.class, classLoaderOfLoggerFactory);
+ } else {
+ final PrivilegedAction<ServiceLoader<SLF4JServiceProvider>> action = () -> ServiceLoader.load(SLF4JServiceProvider.class, classLoaderOfLoggerFactory);
+ serviceLoader = AccessController.doPrivileged(action);
+ }
+ return serviceLoader;
+ }
+
+ private static void safelyInstantiate(List<SLF4JServiceProvider> providerList, Iterator<SLF4JServiceProvider> iterator) {
+ try {
+ SLF4JServiceProvider provider = iterator.next();
+ providerList.add(provider);
+ } catch (ServiceConfigurationError e) {
+ Reporter.error("A service provider failed to instantiate:\n" + e.getMessage());
+ }
+ }
/**
* It is LoggerFactory's responsibility to track version changes and manage
* the compatibility list.
- * <p/>
- * <p/>
- * It is assumed that all versions in the 1.6 are mutually compatible.
+ * <p>
*/
- static private final String[] API_COMPATIBILITY_LIST = new String[] { "1.6", "1.7" };
+ static private final String[] API_COMPATIBILITY_LIST = new String[] { "2.0" };
// private constructor prevents instantiation
private LoggerFactory() {
@@ -102,18 +166,17 @@ public final class LoggerFactory {
/**
* Force LoggerFactory to consider itself uninitialized.
- * <p/>
- * <p/>
+ * <p>
+ * <p>
* This method is intended to be called by classes (in the same package) for
* testing purposes. This method is internal. It can be modified, renamed or
* removed at any time without notice.
- * <p/>
- * <p/>
+ * <p>
+ * <p>
* You are strongly discouraged from calling this method in production code.
*/
static void reset() {
INITIALIZATION_STATE = UNINITIALIZED;
- TEMP_FACTORY = new SubstituteLoggerFactory();
}
private final static void performInitialization() {
@@ -123,110 +186,77 @@ public final class LoggerFactory {
}
}
- private static boolean messageContainsOrgSlf4jImplStaticLoggerBinder(String msg) {
- if (msg == null)
- return false;
- if (msg.indexOf("org/slf4j/impl/StaticLoggerBinder") != -1)
- return true;
- if (msg.indexOf("org.slf4j.impl.StaticLoggerBinder") != -1)
- return true;
- return false;
- }
-
private final static void bind() {
try {
- Set<URL> staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
- reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
- // the next line does the binding
- StaticLoggerBinder.getSingleton();
- INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
- reportActualBinding(staticLoggerBinderPathSet);
- fixSubstitutedLoggers();
- } catch (NoClassDefFoundError ncde) {
- String msg = ncde.getMessage();
- if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
- INITIALIZATION_STATE = NOP_FALLBACK_INITIALIZATION;
- Util.report("Failed to load class \"org.slf4j.impl.StaticLoggerBinder\".");
- Util.report("Defaulting to no-operation (NOP) logger implementation");
- Util.report("See " + NO_STATICLOGGERBINDER_URL + " for further details.");
+ List<SLF4JServiceProvider> providersList = findServiceProviders();
+ reportMultipleBindingAmbiguity(providersList);
+ if (providersList != null && !providersList.isEmpty()) {
+ PROVIDER = providersList.get(0);
+ // SLF4JServiceProvider.initialize() is intended to be called here and nowhere else.
+ PROVIDER.initialize();
+ INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
+ reportActualBinding(providersList);
} else {
- failedBinding(ncde);
- throw ncde;
- }
- } catch (java.lang.NoSuchMethodError nsme) {
- String msg = nsme.getMessage();
- if (msg != null && msg.indexOf("org.slf4j.impl.StaticLoggerBinder.getSingleton()") != -1) {
- INITIALIZATION_STATE = FAILED_INITIALIZATION;
- Util.report("slf4j-api 1.6.x (or later) is incompatible with this binding.");
- Util.report("Your binding is version 1.5.5 or earlier.");
- Util.report("Upgrade your binding to version 1.6.x.");
+ INITIALIZATION_STATE = NOP_FALLBACK_INITIALIZATION;
+ Reporter.warn("No SLF4J providers were found.");
+ Reporter.warn("Defaulting to no-operation (NOP) logger implementation");
+ Reporter.warn("See " + NO_PROVIDERS_URL + " for further details.");
+
+ Set<URL> staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
+ reportIgnoredStaticLoggerBinders(staticLoggerBinderPathSet);
}
- throw nsme;
+ postBindCleanUp();
} catch (Exception e) {
failedBinding(e);
throw new IllegalStateException("Unexpected initialization failure", e);
}
}
- static void failedBinding(Throwable t) {
- INITIALIZATION_STATE = FAILED_INITIALIZATION;
- Util.report("Failed to instantiate SLF4J LoggerFactory", t);
+ static SLF4JServiceProvider loadExplicitlySpecified(ClassLoader classLoader) {
+ String explicitlySpecified = System.getProperty(PROVIDER_PROPERTY_KEY);
+ if (null == explicitlySpecified || explicitlySpecified.isEmpty()) {
+ return null;
+ }
+ try {
+ String message = String.format("Attempting to load provider \"%s\" specified via \"%s\" system property", explicitlySpecified, PROVIDER_PROPERTY_KEY);
+ Reporter.info(message);
+ Class<?> clazz = classLoader.loadClass(explicitlySpecified);
+ Constructor<?> constructor = clazz.getConstructor();
+ Object provider = constructor.newInstance();
+ return (SLF4JServiceProvider) provider;
+ } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
+ String message = String.format("Failed to instantiate the specified SLF4JServiceProvider (%s)", explicitlySpecified);
+ Reporter.error(message, e);
+ return null;
+ } catch (ClassCastException e) {
+ String message = String.format("Specified SLF4JServiceProvider (%s) does not implement SLF4JServiceProvider interface", explicitlySpecified);
+ Reporter.error(message, e);
+ return null;
+ }
}
- private final static void fixSubstitutedLoggers() {
- List<SubstituteLogger> loggers = TEMP_FACTORY.getLoggers();
-
- if (loggers.isEmpty()) {
+ private static void reportIgnoredStaticLoggerBinders(Set<URL> staticLoggerBinderPathSet) {
+ if (staticLoggerBinderPathSet.isEmpty()) {
return;
}
+ Reporter.warn("Class path contains SLF4J bindings targeting slf4j-api versions 1.7.x or earlier.");
- Util.report("The following set of substitute loggers may have been accessed");
- Util.report("during the initialization phase. Logging calls during this");
- Util.report("phase were not honored. However, subsequent logging calls to these");
- Util.report("loggers will work as normally expected.");
- Util.report("See also " + SUBSTITUTE_LOGGER_URL);
- for (SubstituteLogger subLogger : loggers) {
- subLogger.setDelegate(getLogger(subLogger.getName()));
- Util.report(subLogger.getName());
+ for (URL path : staticLoggerBinderPathSet) {
+ Reporter.warn("Ignoring binding found at [" + path + "]");
}
+ Reporter.warn("See " + IGNORED_BINDINGS_URL + " for an explanation.");
- TEMP_FACTORY.clear();
- }
-
- private final static void versionSanityCheck() {
- try {
- String requested = StaticLoggerBinder.REQUESTED_API_VERSION;
-
- boolean match = false;
- for (int i = 0; i < API_COMPATIBILITY_LIST.length; i++) {
- if (requested.startsWith(API_COMPATIBILITY_LIST[i])) {
- match = true;
- }
- }
- if (!match) {
- Util.report("The requested version " + requested + " by your slf4j binding is not compatible with "
- + Arrays.asList(API_COMPATIBILITY_LIST).toString());
- Util.report("See " + VERSION_MISMATCH + " for further details.");
- }
- } catch (java.lang.NoSuchFieldError nsfe) {
- // given our large user base and SLF4J's commitment to backward
- // compatibility, we cannot cry here. Only for implementations
- // which willingly declare a REQUESTED_API_VERSION field do we
- // emit compatibility warnings.
- } catch (Throwable e) {
- // we should never reach here
- Util.report("Unexpected problem occured during version sanity check", e);
- }
}
- // We need to use the name of the StaticLoggerBinder class, but we can't reference
- // the class itself.
- private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";
+ // We need to use the name of the StaticLoggerBinder class, but we can't
+ // reference the class itself.
+ private static final String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";
- private static Set<URL> findPossibleStaticLoggerBinderPathSet() {
+ static Set<URL> findPossibleStaticLoggerBinderPathSet() {
// use Set instead of list in order to deal with bug #138
- // LinkedHashSet appropriate here because it preserves insertion order during iteration
- Set<URL> staticLoggerBinderPathSet = new LinkedHashSet<URL>();
+ // LinkedHashSet appropriate here because it preserves insertion order
+ // during iteration
+ Set<URL> staticLoggerBinderPathSet = new LinkedHashSet<>();
try {
ClassLoader loggerFactoryClassLoader = LoggerFactory.class.getClassLoader();
Enumeration<URL> paths;
@@ -236,47 +266,155 @@ public final class LoggerFactory {
paths = loggerFactoryClassLoader.getResources(STATIC_LOGGER_BINDER_PATH);
}
while (paths.hasMoreElements()) {
- URL path = (URL) paths.nextElement();
+ URL path = paths.nextElement();
staticLoggerBinderPathSet.add(path);
}
} catch (IOException ioe) {
- Util.report("Error getting resources from path", ioe);
+ Reporter.error("Error getting resources from path", ioe);
}
return staticLoggerBinderPathSet;
}
- private static boolean isAmbiguousStaticLoggerBinderPathSet(Set<URL> staticLoggerBinderPathSet) {
- return staticLoggerBinderPathSet.size() > 1;
+ private static void postBindCleanUp() {
+ fixSubstituteLoggers();
+ replayEvents();
+ // release all resources in SUBST_FACTORY
+ SUBST_PROVIDER.getSubstituteLoggerFactory().clear();
+ }
+
+ private static void fixSubstituteLoggers() {
+ synchronized (SUBST_PROVIDER) {
+ SUBST_PROVIDER.getSubstituteLoggerFactory().postInitialization();
+ for (SubstituteLogger substLogger : SUBST_PROVIDER.getSubstituteLoggerFactory().getLoggers()) {
+ Logger logger = getLogger(substLogger.getName());
+ substLogger.setDelegate(logger);
+ }
+ }
+
+ }
+
+ static void failedBinding(Throwable t) {
+ INITIALIZATION_STATE = FAILED_INITIALIZATION;
+ Reporter.error("Failed to instantiate SLF4J LoggerFactory", t);
+ }
+
+ private static void replayEvents() {
+ final LinkedBlockingQueue<SubstituteLoggingEvent> queue = SUBST_PROVIDER.getSubstituteLoggerFactory().getEventQueue();
+ final int queueSize = queue.size();
+ int count = 0;
+ final int maxDrain = 128;
+ List<SubstituteLoggingEvent> eventList = new ArrayList<>(maxDrain);
+ while (true) {
+ int numDrained = queue.drainTo(eventList, maxDrain);
+ if (numDrained == 0)
+ break;
+ for (SubstituteLoggingEvent event : eventList) {
+ replaySingleEvent(event);
+ if (count++ == 0)
+ emitReplayOrSubstituionWarning(event, queueSize);
+ }
+ eventList.clear();
+ }
+ }
+
+ private static void emitReplayOrSubstituionWarning(SubstituteLoggingEvent event, int queueSize) {
+ if (event.getLogger().isDelegateEventAware()) {
+ emitReplayWarning(queueSize);
+ } else if (event.getLogger().isDelegateNOP()) {
+ // nothing to do
+ } else {
+ emitSubstitutionWarning();
+ }
+ }
+
+ private static void replaySingleEvent(SubstituteLoggingEvent event) {
+ if (event == null)
+ return;
+
+ SubstituteLogger substLogger = event.getLogger();
+ String loggerName = substLogger.getName();
+ if (substLogger.isDelegateNull()) {
+ throw new IllegalStateException("Delegate logger cannot be null at this state.");
+ }
+
+ if (substLogger.isDelegateNOP()) {
+ // nothing to do
+ } else if (substLogger.isDelegateEventAware()) {
+ if(substLogger.isEnabledForLevel(event.getLevel())) {
+ substLogger.log(event);
+ }
+ } else {
+ Reporter.warn(loggerName);
+ }
+ }
+
+ private static void emitSubstitutionWarning() {
+ Reporter.warn("The following set of substitute loggers may have been accessed");
+ Reporter.warn("during the initialization phase. Logging calls during this");
+ Reporter.warn("phase were not honored. However, subsequent logging calls to these");
+ Reporter.warn("loggers will work as normally expected.");
+ Reporter.warn("See also " + SUBSTITUTE_LOGGER_URL);
+ }
+
+ private static void emitReplayWarning(int eventCount) {
+ Reporter.warn("A number (" + eventCount + ") of logging calls during the initialization phase have been intercepted and are");
+ Reporter.warn("now being replayed. These are subject to the filtering rules of the underlying logging system.");
+ Reporter.warn("See also " + REPLAY_URL);
+ }
+
+ private final static void versionSanityCheck() {
+ try {
+ String requested = PROVIDER.getRequestedApiVersion();
+
+ boolean match = false;
+ for (String aAPI_COMPATIBILITY_LIST : API_COMPATIBILITY_LIST) {
+ if (requested.startsWith(aAPI_COMPATIBILITY_LIST)) {
+ match = true;
+ }
+ }
+ if (!match) {
+ Reporter.warn("The requested version " + requested + " by your slf4j provider is not compatible with "
+ + Arrays.asList(API_COMPATIBILITY_LIST).toString());
+ Reporter.warn("See " + VERSION_MISMATCH + " for further details.");
+ }
+ } catch (Throwable e) {
+ // we should never reach here
+ Reporter.error("Unexpected problem occurred during version sanity check", e);
+ }
+ }
+
+ private static boolean isAmbiguousProviderList(List<SLF4JServiceProvider> providerList) {
+ return providerList.size() > 1;
}
/**
- * Prints a warning message on the console if multiple bindings were found on the class path.
- * No reporting is done otherwise.
+ * Prints a warning message on the console if multiple bindings were found
+ * on the class path. No reporting is done otherwise.
*
*/
- private static void reportMultipleBindingAmbiguity(Set<URL> staticLoggerBinderPathSet) {
- if (isAmbiguousStaticLoggerBinderPathSet(staticLoggerBinderPathSet)) {
- Util.report("Class path contains multiple SLF4J bindings.");
- Iterator<URL> iterator = staticLoggerBinderPathSet.iterator();
- while (iterator.hasNext()) {
- URL path = (URL) iterator.next();
- Util.report("Found binding in [" + path + "]");
+ private static void reportMultipleBindingAmbiguity(List<SLF4JServiceProvider> providerList) {
+ if (isAmbiguousProviderList(providerList)) {
+ Reporter.warn("Class path contains multiple SLF4J providers.");
+ for (SLF4JServiceProvider provider : providerList) {
+ Reporter.warn("Found provider [" + provider + "]");
}
- Util.report("See " + MULTIPLE_BINDINGS_URL + " for an explanation.");
+ Reporter.warn("See " + MULTIPLE_BINDINGS_URL + " for an explanation.");
}
}
- private static void reportActualBinding(Set<URL> staticLoggerBinderPathSet) {
- if (isAmbiguousStaticLoggerBinderPathSet(staticLoggerBinderPathSet)) {
- Util.report("Actual binding is of type [" + StaticLoggerBinder.getSingleton().getLoggerFactoryClassStr() + "]");
+ private static void reportActualBinding(List<SLF4JServiceProvider> providerList) {
+ // binderPathSet can be null under Android
+ if (!providerList.isEmpty() && isAmbiguousProviderList(providerList)) {
+ Reporter.info("Actual provider is of type [" + providerList.get(0) + "]");
}
}
/**
- * Return a logger named according to the name parameter using the statically
- * bound {@link ILoggerFactory} instance.
+ * Return a logger named according to the name parameter using the
+ * statically bound {@link ILoggerFactory} instance.
*
- * @param name The name of the logger.
+ * @param name
+ * The name of the logger.
* @return logger
*/
public static Logger getLogger(String name) {
@@ -285,29 +423,34 @@ public final class LoggerFactory {
}
/**
- * Return a logger named corresponding to the class passed as parameter, using
- * the statically bound {@link ILoggerFactory} instance.
+ * Return a logger named corresponding to the class passed as parameter,
+ * using the statically bound {@link ILoggerFactory} instance.
+ *
+ * <p>
+ * In case the <code>clazz</code> parameter differs from the name of the
+ * caller as computed internally by SLF4J, a logger name mismatch warning
+ * will be printed but only if the
+ * <code>slf4j.detectLoggerNameMismatch</code> system property is set to
+ * true. By default, this property is not set and no warnings will be
+ * printed even in case of a logger name mismatch.
*
- * <p>In case the the <code>clazz</code> parameter differs from the name of
- * the caller as computed internally by SLF4J, a logger name mismatch warning will be
- * printed but only if the <code>slf4j.detectLoggerNameMismatch</code> system property is
- * set to true. By default, this property is not set and no warnings will be printed
- * even in case of a logger name mismatch.
- *
- * @param clazz the returned logger will be named after clazz
+ * @param clazz
+ * the returned logger will be named after clazz
* @return logger
*
*
- * @see <a href="http://www.slf4j.org/codes.html#loggerNameMismatch">Detected logger name mismatch</a>
+ * @see <a
+ * href="http://www.slf4j.org/codes.html#loggerNameMismatch">Detected
+ * logger name mismatch</a>
*/
public static Logger getLogger(Class<?> clazz) {
Logger logger = getLogger(clazz.getName());
if (DETECT_LOGGER_NAME_MISMATCH) {
Class<?> autoComputedCallingClass = Util.getCallingClass();
- if (nonMatchingClasses(clazz, autoComputedCallingClass)) {
- Util.report(String.format("Detected logger name mismatch. Given name: \"%s\"; computed name: \"%s\".", logger.getName(),
+ if (autoComputedCallingClass != null && nonMatchingClasses(clazz, autoComputedCallingClass)) {
+ Reporter.warn(String.format("Detected logger name mismatch. Given name: \"%s\"; computed name: \"%s\".", logger.getName(),
autoComputedCallingClass.getName()));
- Util.report("See " + LOGGER_NAME_MISMATCH_URL + " for an explanation");
+ Reporter.warn("See " + LOGGER_NAME_MISMATCH_URL + " for an explanation");
}
}
return logger;
@@ -319,28 +462,42 @@ public final class LoggerFactory {
/**
* Return the {@link ILoggerFactory} instance in use.
- * <p/>
- * <p/>
+ * <p>
+ * <p>
* ILoggerFactory instance is bound with this class at compile time.
*
* @return the ILoggerFactory instance in use
*/
public static ILoggerFactory getILoggerFactory() {
+ return getProvider().getLoggerFactory();
+ }
+
+ /**
+ * Return the {@link SLF4JServiceProvider} in use.
+
+ * @return provider in use
+ * @since 1.8.0
+ */
+ static SLF4JServiceProvider getProvider() {
if (INITIALIZATION_STATE == UNINITIALIZED) {
- INITIALIZATION_STATE = ONGOING_INITIALIZATION;
- performInitialization();
+ synchronized (LoggerFactory.class) {
+ if (INITIALIZATION_STATE == UNINITIALIZED) {
+ INITIALIZATION_STATE = ONGOING_INITIALIZATION;
+ performInitialization();
+ }
+ }
}
switch (INITIALIZATION_STATE) {
case SUCCESSFUL_INITIALIZATION:
- return StaticLoggerBinder.getSingleton().getLoggerFactory();
+ return PROVIDER;
case NOP_FALLBACK_INITIALIZATION:
- return NOP_FALLBACK_FACTORY;
+ return NOP_FALLBACK_SERVICE_PROVIDER;
case FAILED_INITIALIZATION:
throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);
case ONGOING_INITIALIZATION:
// support re-entrant behavior.
- // See also http://bugzilla.slf4j.org/show_bug.cgi?id=106
- return TEMP_FACTORY;
+ // See also http://jira.qos.ch/browse/SLF4J-97
+ return SUBST_PROVIDER;
}
throw new IllegalStateException("Unreachable code");
}
diff --git a/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMDCBinder.java b/slf4j-api/src/main/java/org/slf4j/LoggerFactoryFriend.java
index b35b89b0..06ca2017 100644..100755
--- a/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMDCBinder.java
+++ b/slf4j-api/src/main/java/org/slf4j/LoggerFactoryFriend.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2004-2011 QOS.ch
+ * Copyright (c) 2004-2021 QOS.ch
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
@@ -22,37 +22,34 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j.impl;
-
-import org.slf4j.helpers.NOPMDCAdapter;
-import org.slf4j.spi.MDCAdapter;
+package org.slf4j;
/**
- * This implementation is bound to {@link NOPMDCAdapter}.
+ * All methods in this class are reserved for internal use, for testing purposes.
+ *
+ * <p>They can be modified, renamed or removed at any time without notice.
+ *
+ * <p>You are strongly discouraged calling any of the methods of this class.
+ *
+ * @since 1.8.0
*
- * @author Ceki G&uuml;lc&uuml;
+ * @author Ceki G&uuml;lc&uuml;
*/
-public class StaticMDCBinder {
+public class LoggerFactoryFriend {
- /**
- * The unique instance of this class.
+ /*
+ * Force LoggerFactory to consider itself uninitialized.
*/
- public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
-
- private StaticMDCBinder() {
+ static public void reset() {
+ LoggerFactory.reset();
}
/**
- * Currently this method always returns an instance of
- * {@link NOPMDCAdapter}.
+ * Set LoggerFactory.DETECT_LOGGER_NAME_MISMATCH variable.
*
- * @return instance of NOPMDCAdapter
+ * @param enabled a boolean
*/
- public MDCAdapter getMDCA() {
- return new NOPMDCAdapter();
- }
-
- public String getMDCAdapterClassStr() {
- return NOPMDCAdapter.class.getName();
+ public static void setDetectLoggerNameMismatch(boolean enabled) {
+ LoggerFactory.DETECT_LOGGER_NAME_MISMATCH = enabled;
}
}
diff --git a/slf4j-api/src/main/java/org/slf4j/MDC.java b/slf4j-api/src/main/java/org/slf4j/MDC.java
index 06981772..6b0feded 100644
--- a/slf4j-api/src/main/java/org/slf4j/MDC.java
+++ b/slf4j-api/src/main/java/org/slf4j/MDC.java
@@ -25,13 +25,15 @@
package org.slf4j;
import java.io.Closeable;
+import java.util.Deque;
import java.util.Map;
-import org.slf4j.helpers.NOPMDCAdapter;
import org.slf4j.helpers.BasicMDCAdapter;
+import org.slf4j.helpers.NOPMDCAdapter;
+import org.slf4j.helpers.Reporter;
import org.slf4j.helpers.Util;
-import org.slf4j.impl.StaticMDCBinder;
import org.slf4j.spi.MDCAdapter;
+import org.slf4j.spi.SLF4JServiceProvider;
/**
* This class hides and serves as a substitute for the underlying logging
@@ -42,7 +44,7 @@ import org.slf4j.spi.MDCAdapter;
* i.e. this class, will delegate to the underlying system's MDC. Note that at
* this time, only two logging systems, namely log4j and logback, offer MDC
* functionality. For java.util.logging which does not support MDC,
- * {@link BasicMDCAdapter} will be used. For other systems, i.e slf4j-simple
+ * {@link BasicMDCAdapter} will be used. For other systems, i.e. slf4j-simple
* and slf4j-nop, {@link NOPMDCAdapter} will be used.
*
* <p>
@@ -64,6 +66,7 @@ import org.slf4j.spi.MDCAdapter;
public class MDC {
static final String NULL_MDCA_URL = "http://www.slf4j.org/codes.html#null_MDCA";
+ private static final String MDC_APAPTER_CANNOT_BE_NULL_MESSAGE = "MDCAdapter cannot be null. See also " + NULL_MDCA_URL;
static final String NO_STATIC_MDC_BINDER_URL = "http://www.slf4j.org/codes.html#no_static_mdc_binder";
static MDCAdapter mdcAdapter;
@@ -86,21 +89,16 @@ public class MDC {
}
static {
- try {
- mdcAdapter = StaticMDCBinder.SINGLETON.getMDCA();
- } catch (NoClassDefFoundError ncde) {
+ SLF4JServiceProvider provider = LoggerFactory.getProvider();
+ if (provider != null) {
+ // obtain and attach the MDCAdapter from the provider
+ // If you wish to change the adapter, Setting the MDC.mdcAdapter variable might not be enough as
+ // the provider might perform additional assignments that you would need to replicate/adapt.
+ mdcAdapter = provider.getMDCAdapter();
+ } else {
+ Reporter.error("Failed to find provider.");
+ Reporter.error("Defaulting to no-operation MDCAdapter implementation.");
mdcAdapter = new NOPMDCAdapter();
- String msg = ncde.getMessage();
- if (msg != null && msg.indexOf("StaticMDCBinder") != -1) {
- Util.report("Failed to load class \"org.slf4j.impl.StaticMDCBinder\".");
- Util.report("Defaulting to no-operation MDCAdapter implementation.");
- Util.report("See " + NO_STATIC_MDC_BINDER_URL + " for further details.");
- } else {
- throw ncde;
- }
- } catch (Exception e) {
- // we should never get here
- Util.report("MDC binding unsuccessful.", e);
}
}
@@ -124,7 +122,7 @@ public class MDC {
throw new IllegalArgumentException("key parameter cannot be null");
}
if (mdcAdapter == null) {
- throw new IllegalStateException("MDCAdapter cannot be null. See also " + NULL_MDCA_URL);
+ throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
}
mdcAdapter.put(key, val);
}
@@ -169,7 +167,7 @@ public class MDC {
* <p>
* This method delegates all work to the MDC of the underlying logging system.
*
- * @param key
+ * @param key a key
* @return the string value identified by the <code>key</code> parameter.
* @throws IllegalArgumentException
* in case the "key" parameter is null
@@ -180,7 +178,7 @@ public class MDC {
}
if (mdcAdapter == null) {
- throw new IllegalStateException("MDCAdapter cannot be null. See also " + NULL_MDCA_URL);
+ throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
}
return mdcAdapter.get(key);
}
@@ -191,7 +189,7 @@ public class MDC {
* cannot be null. This method does nothing if there is no previous value
* associated with <code>key</code>.
*
- * @param key
+ * @param key a key
* @throws IllegalArgumentException
* in case the "key" parameter is null
*/
@@ -201,7 +199,7 @@ public class MDC {
}
if (mdcAdapter == null) {
- throw new IllegalStateException("MDCAdapter cannot be null. See also " + NULL_MDCA_URL);
+ throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
}
mdcAdapter.remove(key);
}
@@ -211,7 +209,7 @@ public class MDC {
*/
public static void clear() {
if (mdcAdapter == null) {
- throw new IllegalStateException("MDCAdapter cannot be null. See also " + NULL_MDCA_URL);
+ throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
}
mdcAdapter.clear();
}
@@ -225,7 +223,7 @@ public class MDC {
*/
public static Map<String, String> getCopyOfContextMap() {
if (mdcAdapter == null) {
- throw new IllegalStateException("MDCAdapter cannot be null. See also " + NULL_MDCA_URL);
+ throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
}
return mdcAdapter.getCopyOfContextMap();
}
@@ -235,13 +233,15 @@ public class MDC {
* then copying the map passed as parameter. The context map passed as
* parameter must only contain keys and values of type String.
*
+ * Null valued argument is allowed (since SLF4J version 2.0.0).
+ *
* @param contextMap
* must contain only keys and values of type String
* @since 1.5.1
*/
public static void setContextMap(Map<String, String> contextMap) {
if (mdcAdapter == null) {
- throw new IllegalStateException("MDCAdapter cannot be null. See also " + NULL_MDCA_URL);
+ throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
}
mdcAdapter.setContextMap(contextMap);
}
@@ -256,4 +256,48 @@ public class MDC {
return mdcAdapter;
}
+
+
+ /**
+ * Push a value into the deque(stack) referenced by 'key'.
+ *
+ * @param key identifies the appropriate stack
+ * @param value the value to push into the stack
+ * @since 2.0.0
+ */
+ static public void pushByKey(String key, String value) {
+ if (mdcAdapter == null) {
+ throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
+ }
+ mdcAdapter.pushByKey(key, value);
+ }
+
+ /**
+ * Pop the stack referenced by 'key' and return the value possibly null.
+ *
+ * @param key identifies the deque(stack)
+ * @return the value just popped. May be null/
+ * @since 2.0.0
+ */
+ static public String popByKey(String key) {
+ if (mdcAdapter == null) {
+ throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
+ }
+ return mdcAdapter.popByKey(key);
+ }
+
+ /**
+ * Returns a copy of the deque(stack) referenced by 'key'. May be null.
+ *
+ * @param key identifies the stack
+ * @return copy of stack referenced by 'key'. May be null.
+ *
+ * @since 2.0.0
+ */
+ public Deque<String> getCopyOfDequeByKey(String key) {
+ if (mdcAdapter == null) {
+ throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
+ }
+ return mdcAdapter.getCopyOfDequeByKey(key);
+ }
}
diff --git a/slf4j-api/src/main/java/org/slf4j/Marker.java b/slf4j-api/src/main/java/org/slf4j/Marker.java
index c6bfd5e2..4a6dd100 100644
--- a/slf4j-api/src/main/java/org/slf4j/Marker.java
+++ b/slf4j-api/src/main/java/org/slf4j/Marker.java
@@ -29,14 +29,16 @@ import java.util.Iterator;
/**
* Markers are named objects used to enrich log statements. Conforming logging
- * system Implementations of SLF4J determine how information conveyed by markers
- * are used, if at all. In particular, many conforming logging systems ignore
- * marker data.
- *
- * <p>
- * Markers can contain references to other markers, which in turn may contain
- * references of their own.
- *
+ * system implementations of SLF4J should determine how information conveyed by
+ * any markers are used, if at all. Many conforming logging systems ignore marker
+ * data entirely.
+ *
+ * <p>Markers can contain references to nested markers, which in turn may
+ * contain references of their own. Note that the fluent API (new in 2.0) allows adding
+ * multiple markers to a logging statement. It is often preferable to use
+ * multiple markers instead of nested markers.
+ * </p>
+ *
* @author Ceki G&uuml;lc&uuml;
*/
public interface Marker extends Serializable {
@@ -60,7 +62,11 @@ public interface Marker extends Serializable {
/**
* Add a reference to another Marker.
- *
+ *
+ * <p>Note that the fluent API allows adding multiple markers to a logging statement.
+ * It is often preferable to use multiple markers instead of nested markers.
+ * </p>
+ *
* @param reference
* a reference to another marker
* @throws IllegalArgumentException
@@ -80,6 +86,7 @@ public interface Marker extends Serializable {
/**
* @deprecated Replaced by {@link #hasReferences()}.
*/
+ @Deprecated
public boolean hasChildren();
/**
diff --git a/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java b/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java
index 8d50698d..0b15d6ff 100644
--- a/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java
+++ b/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java
@@ -25,8 +25,9 @@
package org.slf4j;
import org.slf4j.helpers.BasicMarkerFactory;
+import org.slf4j.helpers.Reporter;
import org.slf4j.helpers.Util;
-import org.slf4j.impl.StaticMarkerBinder;
+import org.slf4j.spi.SLF4JServiceProvider;
/**
* MarkerFactory is a utility class producing {@link Marker} instances as
@@ -42,20 +43,20 @@ import org.slf4j.impl.StaticMarkerBinder;
* @author Ceki G&uuml;lc&uuml;
*/
public class MarkerFactory {
- static IMarkerFactory markerFactory;
+ static IMarkerFactory MARKER_FACTORY;
private MarkerFactory() {
}
+ // this is where the binding happens
static {
- try {
- markerFactory = StaticMarkerBinder.SINGLETON.getMarkerFactory();
- } catch (NoClassDefFoundError e) {
- markerFactory = new BasicMarkerFactory();
-
- } catch (Exception e) {
- // we should never get here
- Util.report("Unexpected failure while binding MarkerFactory", e);
+ SLF4JServiceProvider provider = LoggerFactory.getProvider();
+ if (provider != null) {
+ MARKER_FACTORY = provider.getMarkerFactory();
+ } else {
+ Reporter.error("Failed to find provider");
+ Reporter.error("Defaulting to BasicMarkerFactory.");
+ MARKER_FACTORY = new BasicMarkerFactory();
}
}
@@ -68,7 +69,7 @@ public class MarkerFactory {
* @return marker
*/
public static Marker getMarker(String name) {
- return markerFactory.getMarker(name);
+ return MARKER_FACTORY.getMarker(name);
}
/**
@@ -79,7 +80,7 @@ public class MarkerFactory {
* @since 1.5.1
*/
public static Marker getDetachedMarker(String name) {
- return markerFactory.getDetachedMarker(name);
+ return MARKER_FACTORY.getDetachedMarker(name);
}
/**
@@ -91,6 +92,6 @@ public class MarkerFactory {
* @return the IMarkerFactory instance in use
*/
public static IMarkerFactory getIMarkerFactory() {
- return markerFactory;
+ return MARKER_FACTORY;
}
} \ No newline at end of file
diff --git a/slf4j-api/src/main/java/org/slf4j/event/DefaultLoggingEvent.java b/slf4j-api/src/main/java/org/slf4j/event/DefaultLoggingEvent.java
new file mode 100755
index 00000000..5a101438
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/event/DefaultLoggingEvent.java
@@ -0,0 +1,140 @@
+package org.slf4j.event;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.Marker;
+
+/**
+ * A default implementation of {@link LoggingEvent}.
+ *
+ * @author Ceki G&uuml;lc&uuml;
+ *
+ * @since 2.0.0
+ */
+public class DefaultLoggingEvent implements LoggingEvent {
+
+ Logger logger;
+ Level level;
+
+ String message;
+ List<Marker> markers;
+ List<Object> arguments;
+ List<KeyValuePair> keyValuePairs;
+
+ Throwable throwable;
+ String threadName;
+ long timeStamp;
+
+ String callerBoundary;
+
+ public DefaultLoggingEvent(Level level, Logger logger) {
+ this.logger = logger;
+ this.level = level;
+ }
+
+ public void addMarker(Marker marker) {
+ if (markers == null) {
+ markers = new ArrayList<>(2);
+ }
+ markers.add(marker);
+ }
+
+ @Override
+ public List<Marker> getMarkers() {
+ return markers;
+ }
+
+ public void addArgument(Object p) {
+ getNonNullArguments().add(p);
+ }
+
+ public void addArguments(Object... args) {
+ getNonNullArguments().addAll(Arrays.asList(args));
+ }
+
+ private List<Object> getNonNullArguments() {
+ if (arguments == null) {
+ arguments = new ArrayList<>(3);
+ }
+ return arguments;
+ }
+
+ @Override
+ public List<Object> getArguments() {
+ return arguments;
+ }
+
+ @Override
+ public Object[] getArgumentArray() {
+ if (arguments == null)
+ return null;
+ return arguments.toArray();
+ }
+
+ public void addKeyValue(String key, Object value) {
+ getNonnullKeyValuePairs().add(new KeyValuePair(key, value));
+ }
+
+ private List<KeyValuePair> getNonnullKeyValuePairs() {
+ if (keyValuePairs == null) {
+ keyValuePairs = new ArrayList<>(4);
+ }
+ return keyValuePairs;
+ }
+
+ @Override
+ public List<KeyValuePair> getKeyValuePairs() {
+ return keyValuePairs;
+ }
+
+ public void setThrowable(Throwable cause) {
+ this.throwable = cause;
+ }
+
+ @Override
+ public Level getLevel() {
+ return level;
+ }
+
+ @Override
+ public String getLoggerName() {
+ return logger.getName();
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ @Override
+ public Throwable getThrowable() {
+ return throwable;
+ }
+
+ public String getThreadName() {
+ return threadName;
+ }
+
+ public long getTimeStamp() {
+ return timeStamp;
+ }
+
+ public void setTimeStamp(long timeStamp) {
+ this.timeStamp = timeStamp;
+ }
+
+ public void setCallerBoundary(String fqcn) {
+ this.callerBoundary = fqcn;
+ }
+
+ public String getCallerBoundary() {
+ return callerBoundary;
+ }
+}
diff --git a/slf4j-api/src/main/java/org/slf4j/event/EventConstants.java b/slf4j-api/src/main/java/org/slf4j/event/EventConstants.java
new file mode 100755
index 00000000..00975da2
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/event/EventConstants.java
@@ -0,0 +1,13 @@
+package org.slf4j.event;
+
+import org.slf4j.spi.LocationAwareLogger;
+
+public class EventConstants {
+ public static final int ERROR_INT = LocationAwareLogger.ERROR_INT;
+ public static final int WARN_INT = LocationAwareLogger.WARN_INT;
+ public static final int INFO_INT = LocationAwareLogger.INFO_INT;
+ public static final int DEBUG_INT = LocationAwareLogger.DEBUG_INT;
+ public static final int TRACE_INT = LocationAwareLogger.TRACE_INT;
+ public static final String NA_SUBST = "NA/SubstituteLogger";
+
+}
diff --git a/slf4j-api/src/main/java/org/slf4j/event/EventRecordingLogger.java b/slf4j-api/src/main/java/org/slf4j/event/EventRecordingLogger.java
new file mode 100755
index 00000000..b21a2e45
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/event/EventRecordingLogger.java
@@ -0,0 +1,84 @@
+package org.slf4j.event;
+
+import java.util.Queue;
+
+import org.slf4j.Marker;
+import org.slf4j.helpers.LegacyAbstractLogger;
+import org.slf4j.helpers.SubstituteLogger;
+
+/**
+ *
+ * This class is used to record events during the initialization phase of the
+ * underlying logging framework. It is called by {@link SubstituteLogger}.
+ *
+ *
+ * @author Ceki G&uuml;lc&uuml;
+ * @author Wessel van Norel
+ *
+ */
+public class EventRecordingLogger extends LegacyAbstractLogger {
+
+ private static final long serialVersionUID = -176083308134819629L;
+
+ String name;
+ SubstituteLogger logger;
+ Queue<SubstituteLoggingEvent> eventQueue;
+
+ // as an event recording logger we have no choice but to record all events
+ final static boolean RECORD_ALL_EVENTS = true;
+
+ public EventRecordingLogger(SubstituteLogger logger, Queue<SubstituteLoggingEvent> eventQueue) {
+ this.logger = logger;
+ this.name = logger.getName();
+ this.eventQueue = eventQueue;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean isTraceEnabled() {
+ return RECORD_ALL_EVENTS;
+ }
+
+ public boolean isDebugEnabled() {
+ return RECORD_ALL_EVENTS;
+ }
+
+ public boolean isInfoEnabled() {
+ return RECORD_ALL_EVENTS;
+ }
+
+ public boolean isWarnEnabled() {
+ return RECORD_ALL_EVENTS;
+ }
+
+ public boolean isErrorEnabled() {
+ return RECORD_ALL_EVENTS;
+ }
+
+ // WARNING: this method assumes that any throwable is properly extracted
+ protected void handleNormalizedLoggingCall(Level level, Marker marker, String msg, Object[] args, Throwable throwable) {
+ SubstituteLoggingEvent loggingEvent = new SubstituteLoggingEvent();
+ loggingEvent.setTimeStamp(System.currentTimeMillis());
+ loggingEvent.setLevel(level);
+ loggingEvent.setLogger(logger);
+ loggingEvent.setLoggerName(name);
+ if (marker != null) {
+ loggingEvent.addMarker(marker);
+ }
+ loggingEvent.setMessage(msg);
+ loggingEvent.setThreadName(Thread.currentThread().getName());
+
+ loggingEvent.setArgumentArray(args);
+ loggingEvent.setThrowable(throwable);
+
+ eventQueue.add(loggingEvent);
+
+ }
+
+ @Override
+ protected String getFullyQualifiedCallerName() {
+ return null;
+ }
+}
diff --git a/slf4j-api/src/main/java/org/slf4j/event/KeyValuePair.java b/slf4j-api/src/main/java/org/slf4j/event/KeyValuePair.java
new file mode 100755
index 00000000..9aebe198
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/event/KeyValuePair.java
@@ -0,0 +1,32 @@
+package org.slf4j.event;
+
+import java.util.Objects;
+
+public class KeyValuePair {
+
+ public final String key;
+ public final Object value;
+
+ public KeyValuePair(String key, Object value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(key) + "=\"" + String.valueOf(value) +"\"";
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if(this == o) return true;
+ if(o == null || getClass() != o.getClass()) return false;
+ KeyValuePair that = (KeyValuePair) o;
+ return Objects.equals(key, that.key) && Objects.equals(value, that.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(key, value);
+ }
+}
diff --git a/slf4j-api/src/main/java/org/slf4j/event/Level.java b/slf4j-api/src/main/java/org/slf4j/event/Level.java
new file mode 100755
index 00000000..a288b06b
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/event/Level.java
@@ -0,0 +1,56 @@
+package org.slf4j.event;
+
+import static org.slf4j.event.EventConstants.DEBUG_INT;
+import static org.slf4j.event.EventConstants.ERROR_INT;
+import static org.slf4j.event.EventConstants.INFO_INT;
+import static org.slf4j.event.EventConstants.TRACE_INT;
+import static org.slf4j.event.EventConstants.WARN_INT;
+
+/**
+ * SLF4J's internal representation of Level.
+ *
+ *
+ * @author Ceki G&uuml;lc&uuml;
+ * @since 1.7.15
+ */
+public enum Level {
+
+ ERROR(ERROR_INT, "ERROR"), WARN(WARN_INT, "WARN"), INFO(INFO_INT, "INFO"), DEBUG(DEBUG_INT, "DEBUG"), TRACE(TRACE_INT, "TRACE");
+
+ private final int levelInt;
+ private final String levelStr;
+
+ Level(int i, String s) {
+ levelInt = i;
+ levelStr = s;
+ }
+
+ public int toInt() {
+ return levelInt;
+ }
+
+ public static Level intToLevel(int levelInt) {
+ switch (levelInt) {
+ case (TRACE_INT):
+ return TRACE;
+ case (DEBUG_INT):
+ return DEBUG;
+ case (INFO_INT):
+ return INFO;
+ case (WARN_INT):
+ return WARN;
+ case (ERROR_INT):
+ return ERROR;
+ default:
+ throw new IllegalArgumentException("Level integer [" + levelInt + "] not recognized.");
+ }
+ }
+
+ /**
+ * Returns the string representation of this Level.
+ */
+ public String toString() {
+ return levelStr;
+ }
+
+}
diff --git a/slf4j-api/src/main/java/org/slf4j/event/LoggingEvent.java b/slf4j-api/src/main/java/org/slf4j/event/LoggingEvent.java
new file mode 100755
index 00000000..27bdf3e2
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/event/LoggingEvent.java
@@ -0,0 +1,45 @@
+package org.slf4j.event;
+
+import java.util.List;
+
+import org.slf4j.Marker;
+
+/**
+ * The minimal interface sufficient for the restitution of data passed
+ * by the user to the SLF4J API.
+ *
+ * @author Ceki G&uuml;lc&uuml;
+ * @since 1.7.15
+ */
+public interface LoggingEvent {
+
+ Level getLevel();
+
+ String getLoggerName();
+
+ String getMessage();
+
+ List<Object> getArguments();
+
+ Object[] getArgumentArray();
+
+ List<Marker> getMarkers();
+
+ List<KeyValuePair> getKeyValuePairs();
+
+ Throwable getThrowable();
+
+ long getTimeStamp();
+
+ String getThreadName();
+
+ /**
+ * Returns the presumed caller boundary provided by the logging library (not the user of the library).
+ * Null by default.
+ *
+ * @return presumed caller, null by default.
+ */
+ default String getCallerBoundary() {
+ return null;
+ }
+}
diff --git a/slf4j-api/src/main/java/org/slf4j/event/SubstituteLoggingEvent.java b/slf4j-api/src/main/java/org/slf4j/event/SubstituteLoggingEvent.java
new file mode 100755
index 00000000..4c8f7ad7
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/event/SubstituteLoggingEvent.java
@@ -0,0 +1,115 @@
+package org.slf4j.event;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.slf4j.Marker;
+import org.slf4j.helpers.SubstituteLogger;
+
+public class SubstituteLoggingEvent implements LoggingEvent {
+
+ Level level;
+ List<Marker> markers;
+ String loggerName;
+ SubstituteLogger logger;
+ String threadName;
+ String message;
+ Object[] argArray;
+ List<KeyValuePair> keyValuePairList;
+
+ long timeStamp;
+ Throwable throwable;
+
+ public Level getLevel() {
+ return level;
+ }
+
+ public void setLevel(Level level) {
+ this.level = level;
+ }
+
+ public List<Marker> getMarkers() {
+ return markers;
+ }
+
+ public void addMarker(Marker marker) {
+ if (marker == null)
+ return;
+
+ if (markers == null) {
+ markers = new ArrayList<>(2);
+ }
+
+ markers.add(marker);
+ }
+
+ public String getLoggerName() {
+ return loggerName;
+ }
+
+ public void setLoggerName(String loggerName) {
+ this.loggerName = loggerName;
+ }
+
+ public SubstituteLogger getLogger() {
+ return logger;
+ }
+
+ public void setLogger(SubstituteLogger logger) {
+ this.logger = logger;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public Object[] getArgumentArray() {
+ return argArray;
+ }
+
+ public void setArgumentArray(Object[] argArray) {
+ this.argArray = argArray;
+ }
+
+ @Override
+ public List<Object> getArguments() {
+ if (argArray == null) {
+ return null;
+ }
+ return Arrays.asList(argArray);
+ }
+
+ public long getTimeStamp() {
+ return timeStamp;
+ }
+
+ public void setTimeStamp(long timeStamp) {
+ this.timeStamp = timeStamp;
+ }
+
+ public String getThreadName() {
+ return threadName;
+ }
+
+ public void setThreadName(String threadName) {
+ this.threadName = threadName;
+ }
+
+ public Throwable getThrowable() {
+ return throwable;
+ }
+
+ public void setThrowable(Throwable throwable) {
+ this.throwable = throwable;
+ }
+
+ @Override
+ public List<KeyValuePair> getKeyValuePairs() {
+ return keyValuePairList;
+ }
+}
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/AbstractLogger.java b/slf4j-api/src/main/java/org/slf4j/helpers/AbstractLogger.java
new file mode 100644
index 00000000..0caaf810
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/AbstractLogger.java
@@ -0,0 +1,423 @@
+/**
+ * Copyright (c) 2004-2019 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+package org.slf4j.helpers;
+
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.Marker;
+import org.slf4j.event.Level;
+
+/**
+ * An abstract implementation which delegates actual logging work to the
+ * {@link #handleNormalizedLoggingCall(Level, Marker, String, Object[], Throwable)} method.
+ *
+ * @author Ceki G&uuml;lc&uuml;
+ * @since 2.0
+ */
+public abstract class AbstractLogger implements Logger, Serializable {
+
+ private static final long serialVersionUID = -2529255052481744503L;
+
+ protected String name;
+
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Replace this instance with a homonymous (same name) logger returned
+ * by LoggerFactory. Note that this method is only called during
+ * deserialization.
+ *
+ * <p>
+ * This approach will work well if the desired ILoggerFactory is the one
+ * referenced by {@link org.slf4j.LoggerFactory} However, if the user manages its logger hierarchy
+ * through a different (non-static) mechanism, e.g. dependency injection, then
+ * this approach would be mostly counterproductive.
+ *
+ * @return logger with same name as returned by LoggerFactory
+ * @throws ObjectStreamException
+ */
+ protected Object readResolve() throws ObjectStreamException {
+ // using getName() instead of this.name works even for
+ // NOPLogger
+ return LoggerFactory.getLogger(getName());
+ }
+
+ @Override
+ public void trace(String msg) {
+ if (isTraceEnabled()) {
+ handle_0ArgsCall(Level.TRACE, null, msg, null);
+ }
+ }
+
+ @Override
+ public void trace(String format, Object arg) {
+ if (isTraceEnabled()) {
+ handle_1ArgsCall(Level.TRACE, null, format, arg);
+ }
+ }
+
+ @Override
+ public void trace(String format, Object arg1, Object arg2) {
+ if (isTraceEnabled()) {
+ handle2ArgsCall(Level.TRACE, null, format, arg1, arg2);
+ }
+ }
+
+ @Override
+ public void trace(String format, Object... arguments) {
+ if (isTraceEnabled()) {
+ handleArgArrayCall(Level.TRACE, null, format, arguments);
+ }
+ }
+
+ @Override
+ public void trace(String msg, Throwable t) {
+ if (isTraceEnabled()) {
+ handle_0ArgsCall(Level.TRACE, null, msg, t);
+ }
+ }
+
+ @Override
+ public void trace(Marker marker, String msg) {
+ if (isTraceEnabled(marker)) {
+ handle_0ArgsCall(Level.TRACE, marker, msg, null);
+ }
+ }
+
+ @Override
+ public void trace(Marker marker, String format, Object arg) {
+ if (isTraceEnabled(marker)) {
+ handle_1ArgsCall(Level.TRACE, marker, format, arg);
+ }
+ }
+
+ @Override
+ public void trace(Marker marker, String format, Object arg1, Object arg2) {
+ if (isTraceEnabled(marker)) {
+ handle2ArgsCall(Level.TRACE, marker, format, arg1, arg2);
+ }
+ }
+
+ @Override
+ public void trace(Marker marker, String format, Object... argArray) {
+ if (isTraceEnabled(marker)) {
+ handleArgArrayCall(Level.TRACE, marker, format, argArray);
+ }
+ }
+
+ public void trace(Marker marker, String msg, Throwable t) {
+ if (isTraceEnabled(marker)) {
+ handle_0ArgsCall(Level.TRACE, marker, msg, t);
+ }
+ }
+
+ public void debug(String msg) {
+ if (isDebugEnabled()) {
+ handle_0ArgsCall(Level.DEBUG, null, msg, null);
+ }
+ }
+
+ public void debug(String format, Object arg) {
+ if (isDebugEnabled()) {
+ handle_1ArgsCall(Level.DEBUG, null, format, arg);
+ }
+ }
+
+ public void debug(String format, Object arg1, Object arg2) {
+ if (isDebugEnabled()) {
+ handle2ArgsCall(Level.DEBUG, null, format, arg1, arg2);
+ }
+ }
+
+ public void debug(String format, Object... arguments) {
+ if (isDebugEnabled()) {
+ handleArgArrayCall(Level.DEBUG, null, format, arguments);
+ }
+ }
+
+ public void debug(String msg, Throwable t) {
+ if (isDebugEnabled()) {
+ handle_0ArgsCall(Level.DEBUG, null, msg, t);
+ }
+ }
+
+ public void debug(Marker marker, String msg) {
+ if (isDebugEnabled(marker)) {
+ handle_0ArgsCall(Level.DEBUG, marker, msg, null);
+ }
+ }
+
+ public void debug(Marker marker, String format, Object arg) {
+ if (isDebugEnabled(marker)) {
+ handle_1ArgsCall(Level.DEBUG, marker, format, arg);
+ }
+ }
+
+ public void debug(Marker marker, String format, Object arg1, Object arg2) {
+ if (isDebugEnabled(marker)) {
+ handle2ArgsCall(Level.DEBUG, marker, format, arg1, arg2);
+ }
+ }
+
+ public void debug(Marker marker, String format, Object... arguments) {
+ if (isDebugEnabled(marker)) {
+ handleArgArrayCall(Level.DEBUG, marker, format, arguments);
+ }
+ }
+
+ public void debug(Marker marker, String msg, Throwable t) {
+ if (isDebugEnabled(marker)) {
+ handle_0ArgsCall(Level.DEBUG, marker, msg, t);
+ }
+ }
+
+ public void info(String msg) {
+ if (isInfoEnabled()) {
+ handle_0ArgsCall(Level.INFO, null, msg, null);
+ }
+ }
+
+ public void info(String format, Object arg) {
+ if (isInfoEnabled()) {
+ handle_1ArgsCall(Level.INFO, null, format, arg);
+ }
+ }
+
+ public void info(String format, Object arg1, Object arg2) {
+ if (isInfoEnabled()) {
+ handle2ArgsCall(Level.INFO, null, format, arg1, arg2);
+ }
+ }
+
+ public void info(String format, Object... arguments) {
+ if (isInfoEnabled()) {
+ handleArgArrayCall(Level.INFO, null, format, arguments);
+ }
+ }
+
+ public void info(String msg, Throwable t) {
+ if (isInfoEnabled()) {
+ handle_0ArgsCall(Level.INFO, null, msg, t);
+ }
+ }
+
+ public void info(Marker marker, String msg) {
+ if (isInfoEnabled(marker)) {
+ handle_0ArgsCall(Level.INFO, marker, msg, null);
+ }
+ }
+
+ public void info(Marker marker, String format, Object arg) {
+ if (isInfoEnabled(marker)) {
+ handle_1ArgsCall(Level.INFO, marker, format, arg);
+ }
+ }
+
+ public void info(Marker marker, String format, Object arg1, Object arg2) {
+ if (isInfoEnabled(marker)) {
+ handle2ArgsCall(Level.INFO, marker, format, arg1, arg2);
+ }
+ }
+
+ public void info(Marker marker, String format, Object... arguments) {
+ if (isInfoEnabled(marker)) {
+ handleArgArrayCall(Level.INFO, marker, format, arguments);
+ }
+ }
+
+ public void info(Marker marker, String msg, Throwable t) {
+ if (isInfoEnabled(marker)) {
+ handle_0ArgsCall(Level.INFO, marker, msg, t);
+ }
+ }
+
+ public void warn(String msg) {
+ if (isWarnEnabled()) {
+ handle_0ArgsCall(Level.WARN, null, msg, null);
+ }
+ }
+
+ public void warn(String format, Object arg) {
+ if (isWarnEnabled()) {
+ handle_1ArgsCall(Level.WARN, null, format, arg);
+ }
+ }
+
+ public void warn(String format, Object arg1, Object arg2) {
+ if (isWarnEnabled()) {
+ handle2ArgsCall(Level.WARN, null, format, arg1, arg2);
+ }
+ }
+
+ public void warn(String format, Object... arguments) {
+ if (isWarnEnabled()) {
+ handleArgArrayCall(Level.WARN, null, format, arguments);
+ }
+ }
+
+ public void warn(String msg, Throwable t) {
+ if (isWarnEnabled()) {
+ handle_0ArgsCall(Level.WARN, null, msg, t);
+ }
+ }
+
+ public void warn(Marker marker, String msg) {
+ if (isWarnEnabled(marker)) {
+ handle_0ArgsCall(Level.WARN, marker, msg, null);
+ }
+ }
+
+ public void warn(Marker marker, String format, Object arg) {
+ if (isWarnEnabled(marker)) {
+ handle_1ArgsCall(Level.WARN, marker, format, arg);
+ }
+ }
+
+ public void warn(Marker marker, String format, Object arg1, Object arg2) {
+ if (isWarnEnabled(marker)) {
+ handle2ArgsCall(Level.WARN, marker, format, arg1, arg2);
+ }
+ }
+
+ public void warn(Marker marker, String format, Object... arguments) {
+ if (isWarnEnabled(marker)) {
+ handleArgArrayCall(Level.WARN, marker, format, arguments);
+ }
+ }
+
+ public void warn(Marker marker, String msg, Throwable t) {
+ if (isWarnEnabled(marker)) {
+ handle_0ArgsCall(Level.WARN, marker, msg, t);
+ }
+ }
+
+ public void error(String msg) {
+ if (isErrorEnabled()) {
+ handle_0ArgsCall(Level.ERROR, null, msg, null);
+ }
+ }
+
+ public void error(String format, Object arg) {
+ if (isErrorEnabled()) {
+ handle_1ArgsCall(Level.ERROR, null, format, arg);
+ }
+ }
+
+ public void error(String format, Object arg1, Object arg2) {
+ if (isErrorEnabled()) {
+ handle2ArgsCall(Level.ERROR, null, format, arg1, arg2);
+ }
+ }
+
+ public void error(String format, Object... arguments) {
+ if (isErrorEnabled()) {
+ handleArgArrayCall(Level.ERROR, null, format, arguments);
+ }
+ }
+
+ public void error(String msg, Throwable t) {
+ if (isErrorEnabled()) {
+ handle_0ArgsCall(Level.ERROR, null, msg, t);
+ }
+ }
+
+ public void error(Marker marker, String msg) {
+ if (isErrorEnabled(marker)) {
+ handle_0ArgsCall(Level.ERROR, marker, msg, null);
+ }
+ }
+
+ public void error(Marker marker, String format, Object arg) {
+ if (isErrorEnabled(marker)) {
+ handle_1ArgsCall(Level.ERROR, marker, format, arg);
+ }
+ }
+
+ public void error(Marker marker, String format, Object arg1, Object arg2) {
+ if (isErrorEnabled(marker)) {
+ handle2ArgsCall(Level.ERROR, marker, format, arg1, arg2);
+ }
+ }
+
+ public void error(Marker marker, String format, Object... arguments) {
+ if (isErrorEnabled(marker)) {
+ handleArgArrayCall(Level.ERROR, marker, format, arguments);
+ }
+ }
+
+ public void error(Marker marker, String msg, Throwable t) {
+ if (isErrorEnabled(marker)) {
+ handle_0ArgsCall(Level.ERROR, marker, msg, t);
+ }
+ }
+
+ private void handle_0ArgsCall(Level level, Marker marker, String msg, Throwable t) {
+ handleNormalizedLoggingCall(level, marker, msg, null, t);
+ }
+
+ private void handle_1ArgsCall(Level level, Marker marker, String msg, Object arg1) {
+ handleNormalizedLoggingCall(level, marker, msg, new Object[] { arg1 }, null);
+ }
+
+ private void handle2ArgsCall(Level level, Marker marker, String msg, Object arg1, Object arg2) {
+ if (arg2 instanceof Throwable) {
+ handleNormalizedLoggingCall(level, marker, msg, new Object[] { arg1 }, (Throwable) arg2);
+ } else {
+ handleNormalizedLoggingCall(level, marker, msg, new Object[] { arg1, arg2 }, null);
+ }
+ }
+
+ private void handleArgArrayCall(Level level, Marker marker, String msg, Object[] args) {
+ Throwable throwableCandidate = MessageFormatter.getThrowableCandidate(args);
+ if (throwableCandidate != null) {
+ Object[] trimmedCopy = MessageFormatter.trimmedCopy(args);
+ handleNormalizedLoggingCall(level, marker, msg, trimmedCopy, throwableCandidate);
+ } else {
+ handleNormalizedLoggingCall(level, marker, msg, args, null);
+ }
+ }
+
+ abstract protected String getFullyQualifiedCallerName();
+
+ /**
+ * Given various arguments passed as parameters, perform actual logging.
+ *
+ * <p>This method assumes that the separation of the args array into actual
+ * objects and a throwable has been already operated.
+ *
+ * @param level the SLF4J level for this event
+ * @param marker The marker to be used for this event, may be null.
+ * @param messagePattern The message pattern which will be parsed and formatted
+ * @param arguments the array of arguments to be formatted, may be null
+ * @param throwable The exception whose stack trace should be logged, may be null
+ */
+ abstract protected void handleNormalizedLoggingCall(Level level, Marker marker, String messagePattern, Object[] arguments, Throwable throwable);
+
+}
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/BasicMDCAdapter.java b/slf4j-api/src/main/java/org/slf4j/helpers/BasicMDCAdapter.java
index 67ab9b5a..95cb904a 100644
--- a/slf4j-api/src/main/java/org/slf4j/helpers/BasicMDCAdapter.java
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/BasicMDCAdapter.java
@@ -27,45 +27,43 @@ package org.slf4j.helpers;
import org.slf4j.spi.MDCAdapter;
import java.util.*;
-import java.util.Map;
/**
* Basic MDC implementation, which can be used with logging systems that lack
* out-of-the-box MDC support.
- *
+ *
* This code was initially inspired by logback's LogbackMDCAdapter. However,
* LogbackMDCAdapter has evolved and is now considerably more sophisticated.
*
* @author Ceki Gulcu
* @author Maarten Bosteels
+ * @author Lukasz Cwik
*
* @since 1.5.0
*/
public class BasicMDCAdapter implements MDCAdapter {
- private InheritableThreadLocal<Map<String, String>> inheritableThreadLocal = new InheritableThreadLocal<Map<String, String>>();
+ private final ThreadLocalMapOfStacks threadLocalMapOfDeques = new ThreadLocalMapOfStacks();
- static boolean isJDK14() {
- try {
- String javaVersion = System.getProperty("java.version");
- return javaVersion.startsWith("1.4");
- } catch (SecurityException se) {
- // punt and assume JDK 1.5 or later
- return false;
+ private final InheritableThreadLocal<Map<String, String>> inheritableThreadLocalMap = new InheritableThreadLocal<Map<String, String>>() {
+ @Override
+ protected Map<String, String> childValue(Map<String, String> parentValue) {
+ if (parentValue == null) {
+ return null;
+ }
+ return new HashMap<>(parentValue);
}
- }
-
- static boolean IS_JDK14 = isJDK14();
+ };
/**
* Put a context value (the <code>val</code> parameter) as identified with
* the <code>key</code> parameter into the current thread's context map.
* Note that contrary to log4j, the <code>val</code> parameter can be null.
- *
+ *
* <p>
* If the current thread does not have a context map it is created as a side
* effect of this call.
- *
+ *
* @throws IllegalArgumentException
* in case the "key" parameter is null
*/
@@ -73,10 +71,10 @@ public class BasicMDCAdapter implements MDCAdapter {
if (key == null) {
throw new IllegalArgumentException("key cannot be null");
}
- Map<String, String> map = (Map<String, String>) inheritableThreadLocal.get();
+ Map<String, String> map = inheritableThreadLocalMap.get();
if (map == null) {
- map = Collections.<String, String> synchronizedMap(new HashMap<String, String>());
- inheritableThreadLocal.set(map);
+ map = new HashMap<>();
+ inheritableThreadLocalMap.set(map);
}
map.put(key, val);
}
@@ -85,19 +83,19 @@ public class BasicMDCAdapter implements MDCAdapter {
* Get the context identified by the <code>key</code> parameter.
*/
public String get(String key) {
- Map<String, String> Map = (Map<String, String>) inheritableThreadLocal.get();
- if ((Map != null) && (key != null)) {
- return (String) Map.get(key);
+ Map<String, String> map = inheritableThreadLocalMap.get();
+ if ((map != null) && (key != null)) {
+ return map.get(key);
} else {
return null;
}
}
/**
- * Remove the the context identified by the <code>key</code> parameter.
+ * Remove the context identified by the <code>key</code> parameter.
*/
public void remove(String key) {
- Map<String, String> map = (Map<String, String>) inheritableThreadLocal.get();
+ Map<String, String> map = inheritableThreadLocalMap.get();
if (map != null) {
map.remove(key);
}
@@ -107,27 +105,21 @@ public class BasicMDCAdapter implements MDCAdapter {
* Clear all entries in the MDC.
*/
public void clear() {
- Map<String, String> map = (Map<String, String>) inheritableThreadLocal.get();
+ Map<String, String> map = inheritableThreadLocalMap.get();
if (map != null) {
map.clear();
- // the InheritableThreadLocal.remove method was introduced in JDK 1.5
- // Thus, invoking clear() on previous JDK 1.4 will fail
- if (isJDK14()) {
- inheritableThreadLocal.set(null);
- } else {
- inheritableThreadLocal.remove();
- }
+ inheritableThreadLocalMap.remove();
}
}
/**
* Returns the keys in the MDC as a {@link Set} of {@link String}s The
* returned value can be null.
- *
+ *
* @return the keys in the MDC
*/
public Set<String> getKeys() {
- Map<String, String> map = (Map<String, String>) inheritableThreadLocal.get();
+ Map<String, String> map = inheritableThreadLocalMap.get();
if (map != null) {
return map.keySet();
} else {
@@ -136,26 +128,43 @@ public class BasicMDCAdapter implements MDCAdapter {
}
/**
- * Return a copy of the current thread's context map.
+ * Return a copy of the current thread's context map.
* Returned value may be null.
- *
+ *
*/
public Map<String, String> getCopyOfContextMap() {
- Map<String, String> oldMap = (Map<String, String>) inheritableThreadLocal.get();
+ Map<String, String> oldMap = inheritableThreadLocalMap.get();
if (oldMap != null) {
- Map<String, String> newMap = Collections.<String, String> synchronizedMap(new HashMap<String, String>());
- synchronized (oldMap) {
- newMap.putAll(oldMap);
- }
- return newMap;
+ return new HashMap<>(oldMap);
} else {
return null;
}
}
public void setContextMap(Map<String, String> contextMap) {
- Map<String, String> map = Collections.<String, String> synchronizedMap(new HashMap<String, String>(contextMap));
- inheritableThreadLocal.set(map);
+ Map<String, String> copy = null;
+ if (contextMap != null) {
+ copy = new HashMap<>(contextMap);
+ }
+ inheritableThreadLocalMap.set(copy);
+ }
+
+ @Override
+ public void pushByKey(String key, String value) {
+ threadLocalMapOfDeques.pushByKey(key, value);
}
+ @Override
+ public String popByKey(String key) {
+ return threadLocalMapOfDeques.popByKey(key);
+ }
+
+ @Override
+ public Deque<String> getCopyOfDequeByKey(String key) {
+ return threadLocalMapOfDeques.getCopyOfDequeByKey(key);
+ }
+ @Override
+ public void clearDequeByKey(String key) {
+ threadLocalMapOfDeques.clearDequeByKey(key);
+ }
}
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/BasicMarker.java b/slf4j-api/src/main/java/org/slf4j/helpers/BasicMarker.java
index b296d5d2..9e3a6aee 100755
--- a/slf4j-api/src/main/java/org/slf4j/helpers/BasicMarker.java
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/BasicMarker.java
@@ -24,10 +24,9 @@
*/
package org.slf4j.helpers;
-import java.util.Collections;
import java.util.Iterator;
import java.util.List;
-import java.util.Vector;
+import java.util.concurrent.CopyOnWriteArrayList;
import org.slf4j.Marker;
@@ -39,10 +38,9 @@ import org.slf4j.Marker;
*/
public class BasicMarker implements Marker {
- private static final long serialVersionUID = 1803952589649545191L;
-
+ private static final long serialVersionUID = -2849567615646933777L;
private final String name;
- private List<Marker> referenceList;
+ private final List<Marker> referenceList = new CopyOnWriteArrayList<>();
BasicMarker(String name) {
if (name == null) {
@@ -55,7 +53,7 @@ public class BasicMarker implements Marker {
return name;
}
- public synchronized void add(Marker reference) {
+ public void add(Marker reference) {
if (reference == null) {
throw new IllegalArgumentException("A null value cannot be added to a Marker as reference.");
}
@@ -65,49 +63,28 @@ public class BasicMarker implements Marker {
return;
} else if (reference.contains(this)) { // avoid recursion
- // a potential reference should not its future "parent" as a reference
+ // a potential reference should not hold its future "parent" as a reference
return;
} else {
- // let's add the reference
- if (referenceList == null) {
- referenceList = new Vector<Marker>();
- }
referenceList.add(reference);
}
-
}
- public synchronized boolean hasReferences() {
- return ((referenceList != null) && (referenceList.size() > 0));
+ public boolean hasReferences() {
+ return (referenceList.size() > 0);
}
+ @Deprecated
public boolean hasChildren() {
return hasReferences();
}
- public synchronized Iterator<Marker> iterator() {
- if (referenceList != null) {
- return referenceList.iterator();
- } else {
- List<Marker> emptyList = Collections.emptyList();
- return emptyList.iterator();
- }
+ public Iterator<Marker> iterator() {
+ return referenceList.iterator();
}
- public synchronized boolean remove(Marker referenceToRemove) {
- if (referenceList == null) {
- return false;
- }
-
- int size = referenceList.size();
- for (int i = 0; i < size; i++) {
- Marker m = (Marker) referenceList.get(i);
- if (referenceToRemove.equals(m)) {
- referenceList.remove(i);
- return true;
- }
- }
- return false;
+ public boolean remove(Marker referenceToRemove) {
+ return referenceList.remove(referenceToRemove);
}
public boolean contains(Marker other) {
@@ -120,8 +97,7 @@ public class BasicMarker implements Marker {
}
if (hasReferences()) {
- for (int i = 0; i < referenceList.size(); i++) {
- Marker ref = (Marker) referenceList.get(i);
+ for (Marker ref : referenceList) {
if (ref.contains(other)) {
return true;
}
@@ -143,8 +119,7 @@ public class BasicMarker implements Marker {
}
if (hasReferences()) {
- for (int i = 0; i < referenceList.size(); i++) {
- Marker ref = (Marker) referenceList.get(i);
+ for (Marker ref : referenceList) {
if (ref.contains(name)) {
return true;
}
@@ -153,9 +128,9 @@ public class BasicMarker implements Marker {
return false;
}
- private static String OPEN = "[ ";
- private static String CLOSE = " ]";
- private static String SEP = ", ";
+ private static final String OPEN = "[ ";
+ private static final String CLOSE = " ]";
+ private static final String SEP = ", ";
public boolean equals(Object obj) {
if (this == obj)
@@ -182,7 +157,7 @@ public class BasicMarker implements Marker {
StringBuilder sb = new StringBuilder(this.getName());
sb.append(' ').append(OPEN);
while (it.hasNext()) {
- reference = (Marker) it.next();
+ reference = it.next();
sb.append(reference.getName());
if (it.hasNext()) {
sb.append(SEP);
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/BasicMarkerFactory.java b/slf4j-api/src/main/java/org/slf4j/helpers/BasicMarkerFactory.java
index 5139bb66..06b0ec58 100644
--- a/slf4j-api/src/main/java/org/slf4j/helpers/BasicMarkerFactory.java
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/BasicMarkerFactory.java
@@ -41,7 +41,7 @@ import org.slf4j.Marker;
*/
public class BasicMarkerFactory implements IMarkerFactory {
- private final ConcurrentMap<String, Marker> markerMap = new ConcurrentHashMap<String, Marker>();
+ private final ConcurrentMap<String, Marker> markerMap = new ConcurrentHashMap<>();
/**
* Regular users should <em>not</em> create
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/CheckReturnValue.java b/slf4j-api/src/main/java/org/slf4j/helpers/CheckReturnValue.java
new file mode 100644
index 00000000..e1c9803a
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/CheckReturnValue.java
@@ -0,0 +1,30 @@
+package org.slf4j.helpers;
+
+
+import org.slf4j.Marker;
+
+import java.lang.annotation.*;
+
+/**
+ * <p>Used to annotate methods in the {@link org.slf4j.spi.LoggingEventBuilder} interface
+ * which return an instance of LoggingEventBuilder (usually as <code>this</code>). Such
+ * methods should be followed by one of the terminating <code>log()</code> methods returning
+ * <code>void</code>.</p>
+ * <p></p>
+ * <p>IntelliJ IDEA supports a check for annotations named as <code>CheckReturnValue</code>
+ * regardless of the containing package. For more information on this feature in IntelliJ IDEA,
+ * select File &#8594; Setting &#8594; Editor &#8594; Inspections and then Java &#8594; Probable Bugs &#8594;
+ * Result of method call ignored. </p>
+ * <p></p>
+ *
+ * <p>As for Eclipse, this feature has been requested in
+ * <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=572496">bug 572496</a></p>
+ *
+ * @author Ceki G&uuml;lc&uuml;
+ * @since 2.0.0-beta1
+ */
+@Documented
+@Target( { ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface CheckReturnValue {
+}
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/FormattingTuple.java b/slf4j-api/src/main/java/org/slf4j/helpers/FormattingTuple.java
index 8d49ba45..a416e1d4 100644
--- a/slf4j-api/src/main/java/org/slf4j/helpers/FormattingTuple.java
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/FormattingTuple.java
@@ -33,9 +33,9 @@ public class FormattingTuple {
static public FormattingTuple NULL = new FormattingTuple(null);
- private String message;
- private Throwable throwable;
- private Object[] argArray;
+ private final String message;
+ private final Throwable throwable;
+ private final Object[] argArray;
public FormattingTuple(String message) {
this(message, null, null);
@@ -44,21 +44,7 @@ public class FormattingTuple {
public FormattingTuple(String message, Object[] argArray, Throwable throwable) {
this.message = message;
this.throwable = throwable;
- if (throwable == null) {
- this.argArray = argArray;
- } else {
- this.argArray = trimmedCopy(argArray);
- }
- }
-
- static Object[] trimmedCopy(Object[] argArray) {
- if (argArray == null || argArray.length == 0) {
- throw new IllegalStateException("non-sensical empty or null argument array");
- }
- final int trimemdLen = argArray.length - 1;
- Object[] trimmed = new Object[trimemdLen];
- System.arraycopy(argArray, 0, trimmed, 0, trimemdLen);
- return trimmed;
+ this.argArray = argArray;
}
public String getMessage() {
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/LegacyAbstractLogger.java b/slf4j-api/src/main/java/org/slf4j/helpers/LegacyAbstractLogger.java
new file mode 100644
index 00000000..dcc90009
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/LegacyAbstractLogger.java
@@ -0,0 +1,39 @@
+package org.slf4j.helpers;
+
+import org.slf4j.Marker;
+
+/**
+ * Provides minimal default implementations for {@link #isTraceEnabled(Marker)}, {@link #isDebugEnabled(Marker)} and other similar methods.
+ *
+ * @since 2.0
+ */
+abstract public class LegacyAbstractLogger extends AbstractLogger {
+
+ private static final long serialVersionUID = -7041884104854048950L;
+
+ @Override
+ public boolean isTraceEnabled(Marker marker) {
+ return isTraceEnabled();
+ }
+
+ @Override
+ public boolean isDebugEnabled(Marker marker) {
+ return isDebugEnabled();
+ }
+
+ @Override
+ public boolean isInfoEnabled(Marker marker) {
+ return isInfoEnabled();
+ }
+
+ @Override
+ public boolean isWarnEnabled(Marker marker) {
+ return isWarnEnabled();
+ }
+
+ @Override
+ public boolean isErrorEnabled(Marker marker) {
+ return isErrorEnabled();
+ }
+
+}
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/MarkerIgnoringBase.java b/slf4j-api/src/main/java/org/slf4j/helpers/MarkerIgnoringBase.java
index dd765384..715cec75 100644
--- a/slf4j-api/src/main/java/org/slf4j/helpers/MarkerIgnoringBase.java
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/MarkerIgnoringBase.java
@@ -34,6 +34,7 @@ import org.slf4j.Marker;
* any marker data passed as argument.
*
* @author Ceki Gulcu
+ * @deprecated
*/
public abstract class MarkerIgnoringBase extends NamedLoggerBase implements Logger {
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/MessageFormatter.java b/slf4j-api/src/main/java/org/slf4j/helpers/MessageFormatter.java
index cbecbfc6..47f95daa 100755
--- a/slf4j-api/src/main/java/org/slf4j/helpers/MessageFormatter.java
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/MessageFormatter.java
@@ -33,14 +33,14 @@ import java.util.Map;
/**
* Formats messages according to very simple substitution rules. Substitutions
* can be made 1, 2 or more arguments.
- *
+ *
* <p>
* For example,
- *
+ *
* <pre>
* MessageFormatter.format(&quot;Hi {}.&quot;, &quot;there&quot;)
* </pre>
- *
+ *
* will return the string "Hi there.".
* <p>
* The {} pair is called the <em>formatting anchor</em>. It serves to designate
@@ -50,48 +50,48 @@ import java.util.Map;
* In case your message contains the '{' or the '}' character, you do not have
* to do anything special unless the '}' character immediately follows '{'. For
* example,
- *
+ *
* <pre>
* MessageFormatter.format(&quot;Set {1,2,3} is not equal to {}.&quot;, &quot;1,2&quot;);
* </pre>
- *
+ *
* will return the string "Set {1,2,3} is not equal to 1,2.".
- *
+ *
* <p>
* If for whatever reason you need to place the string "{}" in the message
* without its <em>formatting anchor</em> meaning, then you need to escape the
* '{' character with '\', that is the backslash character. Only the '{'
* character should be escaped. There is no need to escape the '}' character.
* For example,
- *
+ *
* <pre>
* MessageFormatter.format(&quot;Set \\{} is not equal to {}.&quot;, &quot;1,2&quot;);
* </pre>
- *
+ *
* will return the string "Set {} is not equal to 1,2.".
- *
+ *
* <p>
* The escaping behavior just described can be overridden by escaping the escape
* character '\'. Calling
- *
+ *
* <pre>
* MessageFormatter.format(&quot;File name is C:\\\\{}.&quot;, &quot;file.zip&quot;);
* </pre>
- *
+ *
* will return the string "File name is C:\file.zip".
- *
+ *
* <p>
- * The formatting conventions are different than those of {@link MessageFormat}
+ * The formatting conventions are different from those of {@link MessageFormat}
* which ships with the Java platform. This is justified by the fact that
* SLF4J's implementation is 10 times faster than that of {@link MessageFormat}.
* This local performance difference is both measurable and significant in the
* larger context of the complete logging processing chain.
- *
+ *
* <p>
* See also {@link #format(String, Object)},
* {@link #format(String, Object, Object)} and
* {@link #arrayFormat(String, Object[])} methods for more details.
- *
+ *
* @author Ceki G&uuml;lc&uuml;
* @author Joern Huxhorn
*/
@@ -106,17 +106,17 @@ final public class MessageFormatter {
* parameter.
* <p>
* For example,
- *
+ *
* <pre>
* MessageFormatter.format(&quot;Hi {}.&quot;, &quot;there&quot;);
* </pre>
- *
+ *
* will return the string "Hi there.".
* <p>
- *
+ *
* @param messagePattern
* The message pattern which will be parsed and formatted
- * @param argument
+ * @param arg
* The argument to be substituted in place of the formatting anchor
* @return The formatted message
*/
@@ -125,18 +125,18 @@ final public class MessageFormatter {
}
/**
- *
+ *
* Performs a two argument substitution for the 'messagePattern' passed as
* parameter.
* <p>
* For example,
- *
+ *
* <pre>
* MessageFormatter.format(&quot;Hi {}. My name is {}.&quot;, &quot;Alice&quot;, &quot;Bob&quot;);
* </pre>
- *
+ *
* will return the string "Hi Alice. My name is Bob.".
- *
+ *
* @param messagePattern
* The message pattern which will be parsed and formatted
* @param arg1
@@ -151,36 +151,34 @@ final public class MessageFormatter {
return arrayFormat(messagePattern, new Object[] { arg1, arg2 });
}
- static final Throwable getThrowableCandidate(Object[] argArray) {
- if (argArray == null || argArray.length == 0) {
- return null;
- }
-
- final Object lastEntry = argArray[argArray.length - 1];
- if (lastEntry instanceof Throwable) {
- return (Throwable) lastEntry;
+ final public static FormattingTuple arrayFormat(final String messagePattern, final Object[] argArray) {
+ Throwable throwableCandidate = MessageFormatter.getThrowableCandidate(argArray);
+ Object[] args = argArray;
+ if (throwableCandidate != null) {
+ args = MessageFormatter.trimmedCopy(argArray);
}
- return null;
+ return arrayFormat(messagePattern, args, throwableCandidate);
}
/**
- * Same principle as the {@link #format(String, Object)} and
- * {@link #format(String, Object, Object)} methods except that any number of
- * arguments can be passed in an array.
+ * Assumes that argArray only contains arguments with no throwable as last element.
*
* @param messagePattern
- * The message pattern which will be parsed and formatted
* @param argArray
- * An array of arguments to be substituted in place of formatting
- * anchors
- * @return The formatted message
*/
- final public static FormattingTuple arrayFormat(final String messagePattern, final Object[] argArray) {
+ final public static String basicArrayFormat(final String messagePattern, final Object[] argArray) {
+ FormattingTuple ft = arrayFormat(messagePattern, argArray, null);
+ return ft.getMessage();
+ }
- Throwable throwableCandidate = getThrowableCandidate(argArray);
+ public static String basicArrayFormat(NormalizedParameters np) {
+ return basicArrayFormat(np.getMessage(), np.getArguments());
+ }
+
+ final public static FormattingTuple arrayFormat(final String messagePattern, final Object[] argArray, Throwable throwable) {
if (messagePattern == null) {
- return new FormattingTuple(null, argArray, throwableCandidate);
+ return new FormattingTuple(null, argArray, throwable);
}
if (argArray == null) {
@@ -200,42 +198,38 @@ final public class MessageFormatter {
if (j == -1) {
// no more variables
if (i == 0) { // this is a simple string
- return new FormattingTuple(messagePattern, argArray, throwableCandidate);
+ return new FormattingTuple(messagePattern, argArray, throwable);
} else { // add the tail string which contains no variables and return
// the result.
- sbuf.append(messagePattern.substring(i, messagePattern.length()));
- return new FormattingTuple(sbuf.toString(), argArray, throwableCandidate);
+ sbuf.append(messagePattern, i, messagePattern.length());
+ return new FormattingTuple(sbuf.toString(), argArray, throwable);
}
} else {
if (isEscapedDelimeter(messagePattern, j)) {
if (!isDoubleEscaped(messagePattern, j)) {
L--; // DELIM_START was escaped, thus should not be incremented
- sbuf.append(messagePattern.substring(i, j - 1));
+ sbuf.append(messagePattern, i, j - 1);
sbuf.append(DELIM_START);
i = j + 1;
} else {
// The escape character preceding the delimiter start is
// itself escaped: "abc x:\\{}"
// we have to consume one backward slash
- sbuf.append(messagePattern.substring(i, j - 1));
- deeplyAppendParameter(sbuf, argArray[L], new HashMap<Object[], Object>());
+ sbuf.append(messagePattern, i, j - 1);
+ deeplyAppendParameter(sbuf, argArray[L], new HashMap<>());
i = j + 2;
}
} else {
// normal case
- sbuf.append(messagePattern.substring(i, j));
- deeplyAppendParameter(sbuf, argArray[L], new HashMap<Object[], Object>());
+ sbuf.append(messagePattern, i, j);
+ deeplyAppendParameter(sbuf, argArray[L], new HashMap<>());
i = j + 2;
}
}
}
// append the characters following the last {} pair.
- sbuf.append(messagePattern.substring(i, messagePattern.length()));
- if (L < argArray.length - 1) {
- return new FormattingTuple(sbuf.toString(), argArray, throwableCandidate);
- } else {
- return new FormattingTuple(sbuf.toString(), argArray, null);
- }
+ sbuf.append(messagePattern, i, messagePattern.length());
+ return new FormattingTuple(sbuf.toString(), argArray, throwable);
}
final static boolean isEscapedDelimeter(String messagePattern, int delimeterStartIndex) {
@@ -297,8 +291,7 @@ final public class MessageFormatter {
String oAsString = o.toString();
sbuf.append(oAsString);
} catch (Throwable t) {
- System.err.println("SLF4J: Failed toString() invocation on an object of type [" + o.getClass().getName() + "]");
- t.printStackTrace();
+ Reporter.error("Failed toString() invocation on an object of type [" + o.getClass().getName() + "]", t);
sbuf.append("[FAILED toString()]");
}
@@ -409,4 +402,29 @@ final public class MessageFormatter {
}
sbuf.append(']');
}
+
+ /**
+ * Helper method to determine if an {@link Object} array contains a {@link Throwable} as last element
+ *
+ * @param argArray
+ * The arguments off which we want to know if it contains a {@link Throwable} as last element
+ * @return if the last {@link Object} in argArray is a {@link Throwable} this method will return it,
+ * otherwise it returns null
+ */
+ public static Throwable getThrowableCandidate(final Object[] argArray) {
+ return NormalizedParameters.getThrowableCandidate(argArray);
+ }
+
+ /**
+ * Helper method to get all but the last element of an array
+ *
+ * @param argArray
+ * The arguments from which we want to remove the last element
+ *
+ * @return a copy of the array without the last element
+ */
+ public static Object[] trimmedCopy(final Object[] argArray) {
+ return NormalizedParameters.trimmedCopy(argArray);
+ }
+
}
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/NOPLogger.java b/slf4j-api/src/main/java/org/slf4j/helpers/NOPLogger.java
index 5e0909d8..4b9a3597 100644
--- a/slf4j-api/src/main/java/org/slf4j/helpers/NOPLogger.java
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/NOPLogger.java
@@ -25,14 +25,14 @@
package org.slf4j.helpers;
import org.slf4j.Logger;
-import org.slf4j.helpers.MarkerIgnoringBase;
+import org.slf4j.Marker;
/**
* A direct NOP (no operation) implementation of {@link Logger}.
*
* @author Ceki G&uuml;lc&uuml;
*/
-public class NOPLogger extends MarkerIgnoringBase {
+public class NOPLogger extends NamedLoggerBase implements Logger {
private static final long serialVersionUID = -517220405410904473L;
@@ -42,8 +42,9 @@ public class NOPLogger extends MarkerIgnoringBase {
public static final NOPLogger NOP_LOGGER = new NOPLogger();
/**
- * There is no point in creating multiple instances of NOPLOgger,
- * except by derived classes, hence the protected access for the constructor.
+ * There is no point in creating multiple instances of NOPLogger.
+ *
+ * The present constructor should be "private" but we are leaving it as "protected" for compatibility.
*/
protected NOPLogger() {
}
@@ -51,6 +52,7 @@ public class NOPLogger extends MarkerIgnoringBase {
/**
* Always returns the string value "NOP".
*/
+ @Override
public String getName() {
return "NOP";
}
@@ -59,31 +61,37 @@ public class NOPLogger extends MarkerIgnoringBase {
* Always returns false.
* @return always false
*/
+ @Override
final public boolean isTraceEnabled() {
return false;
}
/** A NOP implementation. */
+ @Override
final public void trace(String msg) {
// NOP
}
/** A NOP implementation. */
+ @Override
final public void trace(String format, Object arg) {
// NOP
}
/** A NOP implementation. */
+ @Override
public final void trace(String format, Object arg1, Object arg2) {
// NOP
}
/** A NOP implementation. */
+ @Override
public final void trace(String format, Object... argArray) {
// NOP
}
/** A NOP implementation. */
+ @Override
final public void trace(String msg, Throwable t) {
// NOP
}
@@ -107,12 +115,12 @@ public class NOPLogger extends MarkerIgnoringBase {
}
/** A NOP implementation. */
- public final void debug(String format, Object arg1, Object arg2) {
+ final public void debug(String format, Object arg1, Object arg2) {
// NOP
}
/** A NOP implementation. */
- public final void debug(String format, Object... argArray) {
+ final public void debug(String format, Object... argArray) {
// NOP
}
@@ -146,7 +154,7 @@ public class NOPLogger extends MarkerIgnoringBase {
}
/** A NOP implementation. */
- public final void info(String format, Object... argArray) {
+ final public void info(String format, Object... argArray) {
// NOP
}
@@ -179,7 +187,7 @@ public class NOPLogger extends MarkerIgnoringBase {
}
/** A NOP implementation. */
- public final void warn(String format, Object... argArray) {
+ final public void warn(String format, Object... argArray) {
// NOP
}
@@ -209,7 +217,7 @@ public class NOPLogger extends MarkerIgnoringBase {
}
/** A NOP implementation. */
- public final void error(String format, Object... argArray) {
+ final public void error(String format, Object... argArray) {
// NOP
}
@@ -217,4 +225,203 @@ public class NOPLogger extends MarkerIgnoringBase {
final public void error(String msg, Throwable t) {
// NOP
}
+
+ // ============================================================
+ // Added NOP methods since MarkerIgnoringBase is now deprecated
+ // ============================================================
+ /**
+ * Always returns false.
+ * @return always false
+ */
+ final public boolean isTraceEnabled(Marker marker) {
+ // NOP
+ return false;
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void trace(Marker marker, String msg) {
+ // NOP
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void trace(Marker marker, String format, Object arg) {
+ // NOP
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void trace(Marker marker, String format, Object arg1, Object arg2) {
+ // NOP
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void trace(Marker marker, String format, Object... argArray) {
+ // NOP
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void trace(Marker marker, String msg, Throwable t) {
+ // NOP
+ }
+
+ /**
+ * Always returns false.
+ * @return always false
+ */
+ final public boolean isDebugEnabled(Marker marker) {
+ return false;
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void debug(Marker marker, String msg) {
+ // NOP
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void debug(Marker marker, String format, Object arg) {
+ // NOP
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void debug(Marker marker, String format, Object arg1, Object arg2) {
+ // NOP
+ }
+
+ @Override
+ final public void debug(Marker marker, String format, Object... arguments) {
+ // NOP
+ }
+
+ @Override
+ final public void debug(Marker marker, String msg, Throwable t) {
+ // NOP
+ }
+
+ /**
+ * Always returns false.
+ * @return always false
+ */
+ @Override
+ public boolean isInfoEnabled(Marker marker) {
+ return false;
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void info(Marker marker, String msg) {
+ // NOP
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void info(Marker marker, String format, Object arg) {
+ // NOP
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void info(Marker marker, String format, Object arg1, Object arg2) {
+ // NOP
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void info(Marker marker, String format, Object... arguments) {
+ // NOP
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void info(Marker marker, String msg, Throwable t) {
+ // NOP
+ }
+
+ /**
+ * Always returns false.
+ * @return always false
+ */
+ @Override
+ final public boolean isWarnEnabled(Marker marker) {
+ return false;
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void warn(Marker marker, String msg) {
+ // NOP
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void warn(Marker marker, String format, Object arg) {
+ // NOP
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void warn(Marker marker, String format, Object arg1, Object arg2) {
+ // NOP
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void warn(Marker marker, String format, Object... arguments) {
+ // NOP
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void warn(Marker marker, String msg, Throwable t) {
+ // NOP
+ }
+
+ /**
+ * Always returns false.
+ * @return always false
+ */
+ @Override
+ final public boolean isErrorEnabled(Marker marker) {
+ return false;
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void error(Marker marker, String msg) {
+ // NOP
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void error(Marker marker, String format, Object arg) {
+ // NOP
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void error(Marker marker, String format, Object arg1, Object arg2) {
+ // NOP
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void error(Marker marker, String format, Object... arguments) {
+ // NOP
+ }
+
+ /** A NOP implementation. */
+ @Override
+ final public void error(Marker marker, String msg, Throwable t) {
+ // NOP
+ }
+ // ===================================================================
+ // End of added NOP methods since MarkerIgnoringBase is now deprecated
+ // ===================================================================
+
}
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/NOPLoggerFactory.java b/slf4j-api/src/main/java/org/slf4j/helpers/NOPLoggerFactory.java
index b8a55dc9..7cc83914 100644
--- a/slf4j-api/src/main/java/org/slf4j/helpers/NOPLoggerFactory.java
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/NOPLoggerFactory.java
@@ -26,10 +26,9 @@ package org.slf4j.helpers;
import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
-import org.slf4j.helpers.NOPLogger;
/**
- * NOPLoggerFactory is an trivial implementation of {@link
+ * NOPLoggerFactory is a trivial implementation of {@link
* ILoggerFactory} which always returns the unique instance of
* NOPLogger.
*
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/NOPMDCAdapter.java b/slf4j-api/src/main/java/org/slf4j/helpers/NOPMDCAdapter.java
index 22f3ea45..7c34fca0 100644
--- a/slf4j-api/src/main/java/org/slf4j/helpers/NOPMDCAdapter.java
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/NOPMDCAdapter.java
@@ -24,6 +24,7 @@
*/
package org.slf4j.helpers;
+import java.util.Deque;
import java.util.Map;
import org.slf4j.spi.MDCAdapter;
@@ -60,4 +61,21 @@ public class NOPMDCAdapter implements MDCAdapter {
// NOP
}
+ @Override
+ public void pushByKey(String key, String value) {
+ }
+
+ @Override
+ public String popByKey(String key) {
+ return null;
+ }
+
+ @Override
+ public Deque<String> getCopyOfDequeByKey(String key) {
+ return null;
+ }
+
+ public void clearDequeByKey(String key) {
+ }
+
}
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/NOP_FallbackServiceProvider.java b/slf4j-api/src/main/java/org/slf4j/helpers/NOP_FallbackServiceProvider.java
new file mode 100755
index 00000000..87d287a6
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/NOP_FallbackServiceProvider.java
@@ -0,0 +1,47 @@
+package org.slf4j.helpers;
+
+import org.slf4j.ILoggerFactory;
+import org.slf4j.IMarkerFactory;
+import org.slf4j.spi.MDCAdapter;
+import org.slf4j.spi.SLF4JServiceProvider;
+
+public class NOP_FallbackServiceProvider implements SLF4JServiceProvider {
+
+ /**
+ * Declare the version of the SLF4J API this implementation is compiled
+ * against. The value of this field is modified with each major release.
+ */
+ // to avoid constant folding by the compiler, this field must *not* be final
+ public static String REQUESTED_API_VERSION = "2.0.99"; // !final
+
+ private final ILoggerFactory loggerFactory = new NOPLoggerFactory();
+ private final IMarkerFactory markerFactory = new BasicMarkerFactory();
+ private final MDCAdapter mdcAdapter = new NOPMDCAdapter();
+
+
+ @Override
+ public ILoggerFactory getLoggerFactory() {
+ return loggerFactory;
+ }
+
+ @Override
+ public IMarkerFactory getMarkerFactory() {
+ return markerFactory;
+ }
+
+
+ @Override
+ public MDCAdapter getMDCAdapter() {
+ return mdcAdapter;
+ }
+
+ @Override
+ public String getRequestedApiVersion() {
+ return REQUESTED_API_VERSION;
+ }
+
+ @Override
+ public void initialize() {
+ // already initialized
+ }
+}
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/NamedLoggerBase.java b/slf4j-api/src/main/java/org/slf4j/helpers/NamedLoggerBase.java
index 184c3942..97b31837 100644
--- a/slf4j-api/src/main/java/org/slf4j/helpers/NamedLoggerBase.java
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/NamedLoggerBase.java
@@ -32,9 +32,10 @@ import org.slf4j.LoggerFactory;
/**
* Serves as base class for named logger implementation. More significantly, this
- * class establishes deserialization behavior. See @see #readResolve.
+ * class establishes deserialization behavior.
*
* @author Ceki Gulcu
+ * @see #readResolve
* @since 1.5.3
*/
abstract class NamedLoggerBase implements Logger, Serializable {
@@ -54,7 +55,7 @@ abstract class NamedLoggerBase implements Logger, Serializable {
*
* <p>
* This approach will work well if the desired ILoggerFactory is the one
- * references by LoggerFactory. However, if the user manages its logger hierarchy
+ * referenced by LoggerFactory. However, if the user manages its logger hierarchy
* through a different (non-static) mechanism, e.g. dependency injection, then
* this approach would be mostly counterproductive.
*
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/NormalizedParameters.java b/slf4j-api/src/main/java/org/slf4j/helpers/NormalizedParameters.java
new file mode 100644
index 00000000..ec278f46
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/NormalizedParameters.java
@@ -0,0 +1,116 @@
+package org.slf4j.helpers;
+
+import org.slf4j.event.LoggingEvent;
+
+/**
+ * Holds normalized call parameters.
+ *
+ * Includes utility methods such as {@link #normalize(String, Object[], Throwable)} to help the normalization of parameters.
+ *
+ * @author ceki
+ * @since 2.0
+ */
+public class NormalizedParameters {
+
+ final String message;
+ final Object[] arguments;
+ final Throwable throwable;
+
+ public NormalizedParameters(String message, Object[] arguments, Throwable throwable) {
+ this.message = message;
+ this.arguments = arguments;
+ this.throwable = throwable;
+ }
+
+ public NormalizedParameters(String message, Object[] arguments) {
+ this(message, arguments, null);
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public Object[] getArguments() {
+ return arguments;
+ }
+
+ public Throwable getThrowable() {
+ return throwable;
+ }
+
+ /**
+ * Helper method to determine if an {@link Object} array contains a
+ * {@link Throwable} as last element
+ *
+ * @param argArray The arguments off which we want to know if it contains a
+ * {@link Throwable} as last element
+ * @return if the last {@link Object} in argArray is a {@link Throwable} this
+ * method will return it, otherwise it returns null
+ */
+ public static Throwable getThrowableCandidate(final Object[] argArray) {
+ if (argArray == null || argArray.length == 0) {
+ return null;
+ }
+
+ final Object lastEntry = argArray[argArray.length - 1];
+ if (lastEntry instanceof Throwable) {
+ return (Throwable) lastEntry;
+ }
+
+ return null;
+ }
+
+ /**
+ * Helper method to get all but the last element of an array
+ *
+ * @param argArray The arguments from which we want to remove the last element
+ *
+ * @return a copy of the array without the last element
+ */
+ public static Object[] trimmedCopy(final Object[] argArray) {
+ if (argArray == null || argArray.length == 0) {
+ throw new IllegalStateException("non-sensical empty or null argument array");
+ }
+
+ final int trimmedLen = argArray.length - 1;
+
+ Object[] trimmed = new Object[trimmedLen];
+
+ if (trimmedLen > 0) {
+ System.arraycopy(argArray, 0, trimmed, 0, trimmedLen);
+ }
+
+ return trimmed;
+ }
+
+ /**
+ * This method serves to normalize logging call invocation parameters.
+ *
+ * More specifically, if a throwable argument is not supplied directly, it
+ * attempts to extract it from the argument array.
+ */
+ public static NormalizedParameters normalize(String msg, Object[] arguments, Throwable t) {
+
+ if (t != null) {
+ return new NormalizedParameters(msg, arguments, t);
+ }
+
+ if (arguments == null || arguments.length == 0) {
+ return new NormalizedParameters(msg, arguments, t);
+ }
+
+ Throwable throwableCandidate = NormalizedParameters.getThrowableCandidate(arguments);
+ if (throwableCandidate != null) {
+ Object[] trimmedArguments = MessageFormatter.trimmedCopy(arguments);
+ return new NormalizedParameters(msg, trimmedArguments, throwableCandidate);
+ } else {
+ return new NormalizedParameters(msg, arguments);
+ }
+
+ }
+
+ public static NormalizedParameters normalize(LoggingEvent event) {
+ return normalize(event.getMessage(), event.getArgumentArray(), event.getThrowable());
+ }
+
+}
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/Reporter.java b/slf4j-api/src/main/java/org/slf4j/helpers/Reporter.java
new file mode 100644
index 00000000..2f269969
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/Reporter.java
@@ -0,0 +1,181 @@
+package org.slf4j.helpers;
+
+import java.io.PrintStream;
+
+/**
+ * An internally used class for reporting internal messages generated by SLF4J itself during initialization.
+ *
+ * <p>
+ * Internal reporting is performed by calling the {@link #info(String)}, {@link #warn(String)} (String)}
+ * {@link #error(String)} (String)} and {@link #error(String, Throwable)} methods.
+ * </p>
+ * <p>See {@link #SLF4J_INTERNAL_VERBOSITY_KEY} and {@link #SLF4J_INTERNAL_REPORT_STREAM_KEY} for
+ * configuration options.</p>
+ * <p>
+ * <p>
+ * Note that this system is independent of the logging back-end in use.
+ *
+ * @since 2.0.10
+ */
+public class Reporter {
+
+ /**
+ * this class is used internally by Reporter
+ */
+ private enum Level {
+ INFO(1), WARN(2), ERROR(3);
+
+ int levelInt;
+
+ private Level(int levelInt) {
+ this.levelInt = levelInt;
+ }
+
+ private int getLevelInt() {
+ return levelInt;
+ }
+ }
+
+ private enum TargetChoice {
+ Stderr, Stdout;
+ }
+
+ static final String SLF4J_INFO_PREFIX = "SLF4J(I): ";
+ static final String SLF4J_WARN_PREFIX = "SLF4J(W): ";
+ static final String SLF4J_ERROR_PREFIX = "SLF4J(E): ";
+
+
+ /**
+ * This system property controls the target for internal reports output by SLF4J.
+ * Recognized values for this key are "System.out", "stdout", "sysout", "System.err",
+ * "stderr" and "syserr".
+ *
+ * <p>By default, output is directed to "stderr".</p>
+ */
+ public static final String SLF4J_INTERNAL_REPORT_STREAM_KEY = "slf4j.internal.report.stream";
+ static private final String[] SYSOUT_KEYS = {"System.out", "stdout", "sysout"};
+
+ /**
+ * This system property controls the internal level of chattiness
+ * of SLF4J. Recognized settings are "INFO", "WARN" and "ERROR". The default value is "INFO".
+ */
+ public static final String SLF4J_INTERNAL_VERBOSITY_KEY = "slf4j.internal.verbosity";
+
+
+ static private final TargetChoice TARGET_CHOICE = initTargetChoice();
+
+ static private final Level INTERNAL_VERBOSITY = initVerbosity();
+
+ static private TargetChoice initTargetChoice() {
+ String reportStreamStr = System.getProperty(SLF4J_INTERNAL_REPORT_STREAM_KEY);
+
+ if(reportStreamStr == null || reportStreamStr.isEmpty()) {
+ return TargetChoice.Stderr;
+ }
+
+ for(String s : SYSOUT_KEYS) {
+ if(s.equalsIgnoreCase(reportStreamStr))
+ return TargetChoice.Stdout;
+ }
+ return TargetChoice.Stderr;
+ }
+
+
+ static private Level initVerbosity() {
+ String verbosityStr = System.getProperty(SLF4J_INTERNAL_VERBOSITY_KEY);
+
+ if(verbosityStr == null || verbosityStr.isEmpty()) {
+ return Level.INFO;
+ }
+
+ if(verbosityStr.equalsIgnoreCase("ERROR")) {
+ return Level.ERROR;
+ }
+
+
+ if(verbosityStr.equalsIgnoreCase("WARN")) {
+ return Level.WARN;
+ }
+
+ return Level.INFO;
+ }
+
+ static boolean isEnabledFor(Level level) {
+ return (level.levelInt >= INTERNAL_VERBOSITY.levelInt);
+ }
+
+ static private PrintStream getTarget() {
+ switch(TARGET_CHOICE) {
+ case Stdout:
+ return System.out;
+ case Stderr:
+ default:
+ return System.err;
+ }
+ }
+
+ /**
+ * Report an internal message of level INFO. Message text is prefixed with the string "SLF4J(I)", with
+ * (I) standing as a shorthand for INFO.
+ *
+ * <p>Messages of level INFO are be enabled when the {@link #SLF4J_INTERNAL_VERBOSITY_KEY} system property is
+ * set to "INFO" and disabled when set to "WARN" or "ERROR". By default, {@link #SLF4J_INTERNAL_VERBOSITY_KEY} is
+ * set to "INFO".</p>
+ *
+ * @param msg the message text
+ */
+ public static void info(String msg) {
+ if(isEnabledFor(Level.INFO)) {
+ getTarget().println(SLF4J_INFO_PREFIX + msg);
+ }
+ }
+
+
+ /**
+ * Report an internal message of level "WARN". Message text is prefixed with the string "SLF4J(W)", with
+ * (W) standing as a shorthand for WARN.
+ *
+ * <p>Messages of level WARN are be enabled when the {@link #SLF4J_INTERNAL_VERBOSITY_KEY} system property is
+ * set to "INFO" or "WARN" and disabled when set to "ERROR". By default, {@link #SLF4J_INTERNAL_VERBOSITY_KEY} is
+ * set to "INFO".</p>
+ *
+ * @param msg the message text
+ */
+ static final public void warn(String msg) {
+ if(isEnabledFor(Level.WARN)) {
+ getTarget().println(SLF4J_WARN_PREFIX + msg);
+ }
+ }
+
+
+ /**
+ * Report an internal message of level "ERROR accompanied by a {@link Throwable}.
+ * Message text is prefixed with the string "SLF4J(E)", with (E) standing as a shorthand for ERROR.
+ *
+ * <p>Messages of level ERROR are always enabled.
+ *
+ * @param msg the message text
+ * @param t a Throwable
+ */
+ static final public void error(String msg, Throwable t) {
+ // error cannot be disabled
+ getTarget().println(SLF4J_ERROR_PREFIX + msg);
+ getTarget().println(SLF4J_ERROR_PREFIX + "Reported exception:");
+ t.printStackTrace(getTarget());
+ }
+
+
+ /**
+ * Report an internal message of level "ERROR". Message text is prefixed with the string "SLF4J(E)", with
+ * (E) standing as a shorthand for ERROR.
+ *
+ * <p>Messages of level ERROR are always enabled.
+ *
+ * @param msg the message text
+ */
+
+ static final public void error(String msg) {
+ // error cannot be disabled
+ getTarget().println(SLF4J_ERROR_PREFIX + msg);
+ }
+}
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/SubstituteLogger.java b/slf4j-api/src/main/java/org/slf4j/helpers/SubstituteLogger.java
index 1c37977e..b9e160d7 100644
--- a/slf4j-api/src/main/java/org/slf4j/helpers/SubstituteLogger.java
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/SubstituteLogger.java
@@ -24,196 +24,286 @@
*/
package org.slf4j.helpers;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Queue;
+
import org.slf4j.Logger;
import org.slf4j.Marker;
+import org.slf4j.event.EventRecordingLogger;
+import org.slf4j.event.Level;
+import org.slf4j.event.LoggingEvent;
+import org.slf4j.event.SubstituteLoggingEvent;
+import org.slf4j.spi.LoggingEventBuilder;
/**
* A logger implementation which logs via a delegate logger. By default, the delegate is a
- * {@link NOPLogger}. However, a different delegate can be set at anytime.
- * <p/>
- * See also the <a href="http://www.slf4j.org/codes.html#substituteLogger">relevant
+ * {@link NOPLogger}. However, a different delegate can be set at any time.
+ *
+ * <p>See also the <a href="http://www.slf4j.org/codes.html#substituteLogger">relevant
* error code</a> documentation.
*
* @author Chetan Mehrotra
+ * @author Ceki Gulcu
*/
public class SubstituteLogger implements Logger {
private final String name;
-
private volatile Logger _delegate;
+ private Boolean delegateEventAware;
+ private Method logMethodCache;
+ private EventRecordingLogger eventRecordingLogger;
+ private final Queue<SubstituteLoggingEvent> eventQueue;
+
+ public final boolean createdPostInitialization;
- public SubstituteLogger(String name) {
+ public SubstituteLogger(String name, Queue<SubstituteLoggingEvent> eventQueue, boolean createdPostInitialization) {
this.name = name;
+ this.eventQueue = eventQueue;
+ this.createdPostInitialization = createdPostInitialization;
}
+ @Override
public String getName() {
return name;
}
+
+ @Override
+ public LoggingEventBuilder makeLoggingEventBuilder(Level level) {
+ return delegate().makeLoggingEventBuilder(level);
+ }
+ @Override
+ public LoggingEventBuilder atLevel(Level level) {
+ return delegate().atLevel(level);
+ }
+
+ @Override
+ public boolean isEnabledForLevel(Level level) {
+ return delegate().isEnabledForLevel(level);
+ }
+
+ @Override
public boolean isTraceEnabled() {
return delegate().isTraceEnabled();
}
-
+
+ @Override
public void trace(String msg) {
delegate().trace(msg);
}
-
+
+ @Override
public void trace(String format, Object arg) {
delegate().trace(format, arg);
}
-
+
+ @Override
public void trace(String format, Object arg1, Object arg2) {
delegate().trace(format, arg1, arg2);
}
-
+
+ @Override
public void trace(String format, Object... arguments) {
delegate().trace(format, arguments);
- }
-
+ }
+
+ @Override
public void trace(String msg, Throwable t) {
delegate().trace(msg, t);
}
-
+
+ @Override
public boolean isTraceEnabled(Marker marker) {
return delegate().isTraceEnabled(marker);
}
-
+
+ @Override
public void trace(Marker marker, String msg) {
delegate().trace(marker, msg);
}
-
+
+ @Override
public void trace(Marker marker, String format, Object arg) {
delegate().trace(marker, format, arg);
}
-
+
+ @Override
public void trace(Marker marker, String format, Object arg1, Object arg2) {
delegate().trace(marker, format, arg1, arg2);
}
-
+ @Override
public void trace(Marker marker, String format, Object... arguments) {
delegate().trace(marker, format, arguments);
}
-
+ @Override
public void trace(Marker marker, String msg, Throwable t) {
delegate().trace(marker, msg, t);
}
-
+
+ @Override
+ public LoggingEventBuilder atTrace() {
+ return delegate().atTrace();
+ }
+
+ @Override
public boolean isDebugEnabled() {
return delegate().isDebugEnabled();
}
-
+
+ @Override
public void debug(String msg) {
delegate().debug(msg);
}
-
+
+ @Override
public void debug(String format, Object arg) {
delegate().debug(format, arg);
}
-
+
+ @Override
public void debug(String format, Object arg1, Object arg2) {
delegate().debug(format, arg1, arg2);
}
-
+
+ @Override
public void debug(String format, Object... arguments) {
delegate().debug(format, arguments);
}
-
+
+ @Override
public void debug(String msg, Throwable t) {
delegate().debug(msg, t);
}
-
+
+ @Override
public boolean isDebugEnabled(Marker marker) {
return delegate().isDebugEnabled(marker);
}
-
+
+ @Override
public void debug(Marker marker, String msg) {
delegate().debug(marker, msg);
}
-
+
+ @Override
public void debug(Marker marker, String format, Object arg) {
delegate().debug(marker, format, arg);
}
-
+
+ @Override
public void debug(Marker marker, String format, Object arg1, Object arg2) {
delegate().debug(marker, format, arg1, arg2);
}
-
+
+ @Override
public void debug(Marker marker, String format, Object... arguments) {
delegate().debug(marker, format, arguments);
}
-
+
+ @Override
public void debug(Marker marker, String msg, Throwable t) {
delegate().debug(marker, msg, t);
}
-
+
+ @Override
+ public LoggingEventBuilder atDebug() {
+ return delegate().atDebug();
+ }
+
+ @Override
public boolean isInfoEnabled() {
return delegate().isInfoEnabled();
}
+
+ @Override
public void info(String msg) {
delegate().info(msg);
}
-
+
+ @Override
public void info(String format, Object arg) {
delegate().info(format, arg);
}
-
+
+ @Override
public void info(String format, Object arg1, Object arg2) {
delegate().info(format, arg1, arg2);
}
-
+
+ @Override
public void info(String format, Object... arguments) {
delegate().info(format, arguments);
}
-
+
+ @Override
public void info(String msg, Throwable t) {
delegate().info(msg, t);
}
-
+
+ @Override
public boolean isInfoEnabled(Marker marker) {
return delegate().isInfoEnabled(marker);
}
-
+
+ @Override
public void info(Marker marker, String msg) {
delegate().info(marker, msg);
}
-
+
+ @Override
public void info(Marker marker, String format, Object arg) {
delegate().info(marker, format, arg);
}
-
+
+ @Override
public void info(Marker marker, String format, Object arg1, Object arg2) {
delegate().info(marker, format, arg1, arg2);
}
-
+
+ @Override
public void info(Marker marker, String format, Object... arguments) {
delegate().info(marker, format, arguments);
}
-
+
+ @Override
public void info(Marker marker, String msg, Throwable t) {
delegate().info(marker, msg, t);
}
+
+ @Override
+ public LoggingEventBuilder atInfo() {
+ return delegate().atInfo();
+ }
+
+ @Override
public boolean isWarnEnabled() {
return delegate().isWarnEnabled();
}
-
+
+ @Override
public void warn(String msg) {
delegate().warn(msg);
}
-
+
+ @Override
public void warn(String format, Object arg) {
delegate().warn(format, arg);
}
-
+
+ @Override
public void warn(String format, Object arg1, Object arg2) {
delegate().warn(format, arg1, arg2);
}
-
+
+ @Override
public void warn(String format, Object... arguments) {
delegate().warn(format, arguments);
}
-
+
+ @Override
public void warn(String msg, Throwable t) {
delegate().warn(msg, t);
}
@@ -221,76 +311,105 @@ public class SubstituteLogger implements Logger {
public boolean isWarnEnabled(Marker marker) {
return delegate().isWarnEnabled(marker);
}
-
+
+ @Override
public void warn(Marker marker, String msg) {
delegate().warn(marker, msg);
}
-
+
+ @Override
public void warn(Marker marker, String format, Object arg) {
delegate().warn(marker, format, arg);
}
-
+
+ @Override
public void warn(Marker marker, String format, Object arg1, Object arg2) {
delegate().warn(marker, format, arg1, arg2);
}
-
+
+ @Override
public void warn(Marker marker, String format, Object... arguments) {
delegate().warn(marker, format, arguments);
}
-
+
+ @Override
public void warn(Marker marker, String msg, Throwable t) {
delegate().warn(marker, msg, t);
}
+
+ @Override
+ public LoggingEventBuilder atWarn() {
+ return delegate().atWarn();
+ }
+
+
+ @Override
public boolean isErrorEnabled() {
return delegate().isErrorEnabled();
}
-
+
+ @Override
public void error(String msg) {
delegate().error(msg);
}
-
+
+ @Override
public void error(String format, Object arg) {
delegate().error(format, arg);
}
-
+
+ @Override
public void error(String format, Object arg1, Object arg2) {
delegate().error(format, arg1, arg2);
}
-
+
+ @Override
public void error(String format, Object... arguments) {
delegate().error(format, arguments);
}
-
+
+ @Override
public void error(String msg, Throwable t) {
delegate().error(msg, t);
}
-
+
+ @Override
public boolean isErrorEnabled(Marker marker) {
return delegate().isErrorEnabled(marker);
}
-
+
+ @Override
public void error(Marker marker, String msg) {
delegate().error(marker, msg);
}
-
+
+ @Override
public void error(Marker marker, String format, Object arg) {
delegate().error(marker, format, arg);
}
-
+
+ @Override
public void error(Marker marker, String format, Object arg1, Object arg2) {
delegate().error(marker, format, arg1, arg2);
}
-
+
+ @Override
public void error(Marker marker, String format, Object... arguments) {
delegate().error(marker, format, arguments);
}
-
+
+ @Override
public void error(Marker marker, String msg, Throwable t) {
delegate().error(marker, msg, t);
}
@Override
+ public LoggingEventBuilder atError() {
+ return delegate().atError();
+ }
+
+ @Override
public boolean equals(Object o) {
if (this == o)
return true;
@@ -314,8 +433,22 @@ public class SubstituteLogger implements Logger {
* Return the delegate logger instance if set. Otherwise, return a {@link NOPLogger}
* instance.
*/
- Logger delegate() {
- return _delegate != null ? _delegate : NOPLogger.NOP_LOGGER;
+ public Logger delegate() {
+ if (_delegate != null) {
+ return _delegate;
+ }
+ if (createdPostInitialization) {
+ return NOPLogger.NOP_LOGGER;
+ } else {
+ return getEventRecordingLogger();
+ }
+ }
+
+ private Logger getEventRecordingLogger() {
+ if (eventRecordingLogger == null) {
+ eventRecordingLogger = new EventRecordingLogger(this, eventQueue);
+ }
+ return eventRecordingLogger;
}
/**
@@ -325,4 +458,36 @@ public class SubstituteLogger implements Logger {
public void setDelegate(Logger delegate) {
this._delegate = delegate;
}
+
+ public boolean isDelegateEventAware() {
+ if (delegateEventAware != null)
+ return delegateEventAware;
+
+ try {
+ logMethodCache = _delegate.getClass().getMethod("log", LoggingEvent.class);
+ delegateEventAware = Boolean.TRUE;
+ } catch (NoSuchMethodException e) {
+ delegateEventAware = Boolean.FALSE;
+ }
+ return delegateEventAware;
+ }
+
+ public void log(LoggingEvent event) {
+ if (isDelegateEventAware()) {
+ try {
+ logMethodCache.invoke(_delegate, event);
+ } catch (IllegalAccessException e) {
+ } catch (IllegalArgumentException e) {
+ } catch (InvocationTargetException e) {
+ }
+ }
+ }
+
+ public boolean isDelegateNull() {
+ return _delegate == null;
+ }
+
+ public boolean isDelegateNOP() {
+ return _delegate instanceof NOPLogger;
+ }
}
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/SubstituteLoggerFactory.java b/slf4j-api/src/main/java/org/slf4j/helpers/SubstituteLoggerFactory.java
index 0697e39f..8a9d5dd3 100755
--- a/slf4j-api/src/main/java/org/slf4j/helpers/SubstituteLoggerFactory.java
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/SubstituteLoggerFactory.java
@@ -24,13 +24,15 @@
*/
package org.slf4j.helpers;
-import org.slf4j.ILoggerFactory;
-import org.slf4j.Logger;
-
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import org.slf4j.ILoggerFactory;
+import org.slf4j.Logger;
+import org.slf4j.event.SubstituteLoggingEvent;
/**
* SubstituteLoggerFactory manages instances of {@link SubstituteLogger}.
@@ -40,28 +42,39 @@ import java.util.concurrent.ConcurrentMap;
*/
public class SubstituteLoggerFactory implements ILoggerFactory {
- final ConcurrentMap<String, SubstituteLogger> loggers = new ConcurrentHashMap<String, SubstituteLogger>();
+ volatile boolean postInitialization = false;
- public Logger getLogger(String name) {
+ final Map<String, SubstituteLogger> loggers = new ConcurrentHashMap<>();
+
+ final LinkedBlockingQueue<SubstituteLoggingEvent> eventQueue = new LinkedBlockingQueue<>();
+
+ synchronized public Logger getLogger(String name) {
SubstituteLogger logger = loggers.get(name);
if (logger == null) {
- logger = new SubstituteLogger(name);
- SubstituteLogger oldLogger = loggers.putIfAbsent(name, logger);
- if (oldLogger != null)
- logger = oldLogger;
+ logger = new SubstituteLogger(name, eventQueue, postInitialization);
+ loggers.put(name, logger);
}
return logger;
}
public List<String> getLoggerNames() {
- return new ArrayList<String>(loggers.keySet());
+ return new ArrayList<>(loggers.keySet());
}
public List<SubstituteLogger> getLoggers() {
- return new ArrayList<SubstituteLogger>(loggers.values());
+ return new ArrayList<>(loggers.values());
+ }
+
+ public LinkedBlockingQueue<SubstituteLoggingEvent> getEventQueue() {
+ return eventQueue;
+ }
+
+ public void postInitialization() {
+ postInitialization = true;
}
public void clear() {
loggers.clear();
+ eventQueue.clear();
}
}
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/SubstituteServiceProvider.java b/slf4j-api/src/main/java/org/slf4j/helpers/SubstituteServiceProvider.java
new file mode 100755
index 00000000..2c59530d
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/SubstituteServiceProvider.java
@@ -0,0 +1,41 @@
+package org.slf4j.helpers;
+
+import org.slf4j.ILoggerFactory;
+import org.slf4j.IMarkerFactory;
+import org.slf4j.spi.MDCAdapter;
+import org.slf4j.spi.SLF4JServiceProvider;
+
+public class SubstituteServiceProvider implements SLF4JServiceProvider {
+ private final SubstituteLoggerFactory loggerFactory = new SubstituteLoggerFactory();
+ private final IMarkerFactory markerFactory = new BasicMarkerFactory();
+ private final MDCAdapter mdcAdapter = new BasicMDCAdapter();
+
+ @Override
+ public ILoggerFactory getLoggerFactory() {
+ return loggerFactory;
+ }
+
+ public SubstituteLoggerFactory getSubstituteLoggerFactory() {
+ return loggerFactory;
+ }
+
+ @Override
+ public IMarkerFactory getMarkerFactory() {
+ return markerFactory;
+ }
+
+ @Override
+ public MDCAdapter getMDCAdapter() {
+ return mdcAdapter;
+ }
+
+ @Override
+ public String getRequestedApiVersion() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void initialize() {
+
+ }
+}
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/ThreadLocalMapOfStacks.java b/slf4j-api/src/main/java/org/slf4j/helpers/ThreadLocalMapOfStacks.java
new file mode 100644
index 00000000..89ddee0e
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/ThreadLocalMapOfStacks.java
@@ -0,0 +1,89 @@
+package org.slf4j.helpers;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * A simple implementation of ThreadLocal backed Map containing values of type
+ * Deque<String>.
+ *
+ * @author Ceki Guuml;c&uuml;
+ * @since 2.0.0
+ */
+public class ThreadLocalMapOfStacks {
+
+ // BEWARE: Keys or values placed in a ThreadLocal should not be of a type/class
+ // not included in the JDK. See also https://jira.qos.ch/browse/LOGBACK-450
+
+ final ThreadLocal<Map<String, Deque<String>>> tlMapOfStacks = new ThreadLocal<>();
+
+ public void pushByKey(String key, String value) {
+ if (key == null)
+ return;
+
+ Map<String, Deque<String>> map = tlMapOfStacks.get();
+
+ if (map == null) {
+ map = new HashMap<>();
+ tlMapOfStacks.set(map);
+ }
+
+ Deque<String> deque = map.get(key);
+ if (deque == null) {
+ deque = new ArrayDeque<>();
+ }
+ deque.push(value);
+ map.put(key, deque);
+ }
+
+ public String popByKey(String key) {
+ if (key == null)
+ return null;
+
+ Map<String, Deque<String>> map = tlMapOfStacks.get();
+ if (map == null)
+ return null;
+ Deque<String> deque = map.get(key);
+ if (deque == null)
+ return null;
+ return deque.pop();
+ }
+
+ public Deque<String> getCopyOfDequeByKey(String key) {
+ if (key == null)
+ return null;
+
+ Map<String, Deque<String>> map = tlMapOfStacks.get();
+ if (map == null)
+ return null;
+ Deque<String> deque = map.get(key);
+ if (deque == null)
+ return null;
+
+ return new ArrayDeque<String>(deque);
+ }
+
+ /**
+ * Clear the deque(stack) referenced by 'key'.
+ *
+ * @param key identifies the stack
+ *
+ * @since 2.0.0
+ */
+ public void clearDequeByKey(String key) {
+ if (key == null)
+ return;
+
+ Map<String, Deque<String>> map = tlMapOfStacks.get();
+ if (map == null)
+ return;
+ Deque<String> deque = map.get(key);
+ if (deque == null)
+ return;
+ deque.clear();
+ }
+
+}
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/Util.java b/slf4j-api/src/main/java/org/slf4j/helpers/Util.java
index 91a09837..98858315 100755
--- a/slf4j-api/src/main/java/org/slf4j/helpers/Util.java
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/Util.java
@@ -35,6 +35,27 @@ public final class Util {
private Util() {
}
+ public static String safeGetSystemProperty(String key) {
+ if (key == null)
+ throw new IllegalArgumentException("null input");
+
+ String result = null;
+ try {
+ result = System.getProperty(key);
+ } catch (java.lang.SecurityException sm) {
+ ; // ignore
+ }
+ return result;
+ }
+
+ public static boolean safeGetBooleanSystemProperty(String key) {
+ String value = safeGetSystemProperty(key);
+ if (value == null)
+ return false;
+ else
+ return value.equalsIgnoreCase("true");
+ }
+
/**
* In order to call {@link SecurityManager#getClassContext()}, which is a
* protected method, we add this wrapper which allows the method to be visible
@@ -46,7 +67,28 @@ public final class Util {
}
}
- private static final ClassContextSecurityManager SECURITY_MANAGER = new ClassContextSecurityManager();
+ private static ClassContextSecurityManager SECURITY_MANAGER;
+ private static boolean SECURITY_MANAGER_CREATION_ALREADY_ATTEMPTED = false;
+
+ private static ClassContextSecurityManager getSecurityManager() {
+ if (SECURITY_MANAGER != null)
+ return SECURITY_MANAGER;
+ else if (SECURITY_MANAGER_CREATION_ALREADY_ATTEMPTED)
+ return null;
+ else {
+ SECURITY_MANAGER = safeCreateSecurityManager();
+ SECURITY_MANAGER_CREATION_ALREADY_ATTEMPTED = true;
+ return SECURITY_MANAGER;
+ }
+ }
+
+ private static ClassContextSecurityManager safeCreateSecurityManager() {
+ try {
+ return new ClassContextSecurityManager();
+ } catch (java.lang.SecurityException sm) {
+ return null;
+ }
+ }
/**
* Returns the name of the class which called the invoking method.
@@ -54,7 +96,10 @@ public final class Util {
* @return the name of the class which called the invoking method.
*/
public static Class<?> getCallingClass() {
- Class<?>[] trace = SECURITY_MANAGER.getClassContext();
+ ClassContextSecurityManager securityManager = getSecurityManager();
+ if (securityManager == null)
+ return null;
+ Class<?>[] trace = securityManager.getClassContext();
String thisClassName = Util.class.getName();
// Advance until Util is found
@@ -72,13 +117,28 @@ public final class Util {
return trace[i + 2];
}
+ /**
+ * See {@link Reporter#error(String, Throwable)} class for alternative.
+ *
+ * @deprecated replaced by the {@link Reporter#error(String, Throwable)} method.
+ * @param msg message to print
+ * @param t throwable to print
+ */
static final public void report(String msg, Throwable t) {
System.err.println(msg);
System.err.println("Reported exception:");
t.printStackTrace();
}
+ /**
+ * See {@link Reporter} class for alternatives.
+ *
+ * @deprecated replaced by one of {@link Reporter#info(String)},
+ * {@link Reporter#warn(String)} or {@link Reporter#error(String)} methods.
+ * @param msg message to print
+ */
static final public void report(String msg) {
System.err.println("SLF4J: " + msg);
}
+
}
diff --git a/slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
deleted file mode 100644
index e6747e53..00000000
--- a/slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
+++ /dev/null
@@ -1,73 +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 org.slf4j.ILoggerFactory;
-
-/**
- * The binding of {@link LoggerFactory} class with an actual instance of
- * {@link ILoggerFactory} is performed using information returned by this class.
- *
- * This class is meant to provide a dummy StaticLoggerBinder to the slf4j-api module.
- * Real implementations are found in each SLF4J binding project, e.g. slf4j-nop,
- * slf4j-log4j12 etc.
- *
- * @author Ceki G&uuml;lc&uuml;
- */
-public class StaticLoggerBinder {
-
- /**
- * The unique instance of this class.
- */
- private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
-
- /**
- * Return the singleton of this class.
- *
- * @return the StaticLoggerBinder singleton
- */
- public static final StaticLoggerBinder getSingleton() {
- return SINGLETON;
- }
-
- /**
- * Declare the version of the SLF4J API this implementation is compiled against.
- * The value of this field is usually modified with each release.
- */
- // to avoid constant folding by the compiler, this field must *not* be final
- public static String REQUESTED_API_VERSION = "1.6.99"; // !final
-
- private StaticLoggerBinder() {
- throw new UnsupportedOperationException("This code should have never made it into slf4j-api.jar");
- }
-
- public ILoggerFactory getLoggerFactory() {
- throw new UnsupportedOperationException("This code should never make it into slf4j-api.jar");
- }
-
- public String getLoggerFactoryClassStr() {
- throw new UnsupportedOperationException("This code should never make it into slf4j-api.jar");
- }
-}
diff --git a/slf4j-api/src/main/java/org/slf4j/impl/StaticMDCBinder.java b/slf4j-api/src/main/java/org/slf4j/impl/StaticMDCBinder.java
deleted file mode 100644
index 4fd65f40..00000000
--- a/slf4j-api/src/main/java/org/slf4j/impl/StaticMDCBinder.java
+++ /dev/null
@@ -1,57 +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 org.slf4j.spi.MDCAdapter;
-
-/**
- * This class is only a stub. Real implementations are found in
- * each SLF4J binding project, e.g. slf4j-nop, slf4j-log4j12 etc.
- *
- * @author Ceki G&uuml;lc&uuml;
- */
-public class StaticMDCBinder {
-
- /**
- * The unique instance of this class.
- */
- public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
-
- private StaticMDCBinder() {
- throw new UnsupportedOperationException("This code should never make it into the jar");
- }
-
- /**
- * Currently this method always returns an instance of
- * {@link StaticMDCBinder}.
- */
- public MDCAdapter getMDCA() {
- throw new UnsupportedOperationException("This code should never make it into the jar");
- }
-
- public String getMDCAdapterClassStr() {
- throw new UnsupportedOperationException("This code should never make it into the jar");
- }
-}
diff --git a/slf4j-api/src/main/java/org/slf4j/impl/StaticMarkerBinder.java b/slf4j-api/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
deleted file mode 100644
index 0823b827..00000000
--- a/slf4j-api/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
+++ /dev/null
@@ -1,70 +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 org.slf4j.IMarkerFactory;
-import org.slf4j.MarkerFactory;
-import org.slf4j.helpers.BasicMarkerFactory;
-import org.slf4j.spi.MarkerFactoryBinder;
-
-/**
- *
- * The binding of {@link MarkerFactory} class with an actual instance of
- * {@link IMarkerFactory} is performed using information returned by this class.
- *
- * This class is meant to provide a *dummy* StaticMarkerBinder to the slf4j-api module.
- * Real implementations are found in each SLF4J binding project, e.g. slf4j-nop,
- * slf4j-simple, slf4j-log4j12 etc.
- *
- * @author Ceki G&uuml;lc&uuml;
- */
-public class StaticMarkerBinder implements MarkerFactoryBinder {
-
- /**
- * The unique instance of this class.
- */
- public static final StaticMarkerBinder SINGLETON = new StaticMarkerBinder();
-
- private StaticMarkerBinder() {
- throw new UnsupportedOperationException("This code should never make it into the jar");
- }
-
- /**
- * Currently this method always returns an instance of
- * {@link BasicMarkerFactory}.
- */
- public IMarkerFactory getMarkerFactory() {
- throw new UnsupportedOperationException("This code should never make it into the jar");
- }
-
- /**
- * Currently, this method returns the class name of
- * {@link BasicMarkerFactory}.
- */
- public String getMarkerFactoryClassStr() {
- throw new UnsupportedOperationException("This code should never make it into the jar");
- }
-
-}
diff --git a/slf4j-api/src/main/java/org/slf4j/impl/package.html b/slf4j-api/src/main/java/org/slf4j/impl/package.html
deleted file mode 100644
index 6b84bada..00000000
--- a/slf4j-api/src/main/java/org/slf4j/impl/package.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-
-
-<html>
- <head>
- <title></title>
- </head>
-
-
- <body>
-
- <p>Implementations of core logging interfaces defined in the {@link
- org.slf4j} package.</p>
-
- <hr/>
- </body>
-</html>
diff --git a/slf4j-api/src/main/java/org/slf4j/package.html b/slf4j-api/src/main/java/org/slf4j/package.html
index e50b3ee2..323bac21 100644
--- a/slf4j-api/src/main/java/org/slf4j/package.html
+++ b/slf4j-api/src/main/java/org/slf4j/package.html
@@ -11,6 +11,6 @@
<p>Core logging interfaces.</p>
- <hr/>
+ <hr>
</body>
</html>
diff --git a/slf4j-api/src/main/java/org/slf4j/spi/CallerBoundaryAware.java b/slf4j-api/src/main/java/org/slf4j/spi/CallerBoundaryAware.java
new file mode 100644
index 00000000..e1a2de95
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/spi/CallerBoundaryAware.java
@@ -0,0 +1,25 @@
+package org.slf4j.spi;
+
+import org.slf4j.event.LoggingEvent;
+
+/**
+ * Additional interface to {@link LoggingEventBuilder} and
+ * {@link org.slf4j.event.LoggingEvent LoggingEvent}.
+ *
+ * Implementations of {@link LoggingEventBuilder} and {@link LoggingEvent} may optionally
+ * implement {@link CallerBoundaryAware} in order to support caller info extraction.
+ *
+ * This interface is intended for use by logging backends or logging bridges.
+ *
+ * @author Ceki Gulcu
+ *
+ */
+public interface CallerBoundaryAware {
+
+ /**
+ * Add a fqcn (fully qualified class name) to this event, presumed to be the caller boundary.
+ *
+ * @param fqcn
+ */
+ void setCallerBoundary(String fqcn);
+}
diff --git a/slf4j-api/src/main/java/org/slf4j/spi/DefaultLoggingEventBuilder.java b/slf4j-api/src/main/java/org/slf4j/spi/DefaultLoggingEventBuilder.java
new file mode 100755
index 00000000..66652b07
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/spi/DefaultLoggingEventBuilder.java
@@ -0,0 +1,246 @@
+/**
+ * Copyright (c) 2004-2022 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.spi;
+
+import java.util.function.Supplier;
+
+import org.slf4j.Logger;
+import org.slf4j.Marker;
+import org.slf4j.event.DefaultLoggingEvent;
+import org.slf4j.event.KeyValuePair;
+import org.slf4j.event.Level;
+import org.slf4j.event.LoggingEvent;
+
+/**
+ * Default implementation of {@link LoggingEventBuilder}
+ */
+public class DefaultLoggingEventBuilder implements LoggingEventBuilder, CallerBoundaryAware {
+
+
+ // The caller boundary when the log() methods are invoked, is this class itself.
+
+ static String DLEB_FQCN = DefaultLoggingEventBuilder.class.getName();
+
+ protected DefaultLoggingEvent loggingEvent;
+ protected Logger logger;
+
+ public DefaultLoggingEventBuilder(Logger logger, Level level) {
+ this.logger = logger;
+ loggingEvent = new DefaultLoggingEvent(level, logger);
+ }
+
+ /**
+ * Add a marker to the current logging event being built.
+ *
+ * It is possible to add multiple markers to the same logging event.
+ *
+ * @param marker the marker to add
+ */
+ @Override
+ public LoggingEventBuilder addMarker(Marker marker) {
+ loggingEvent.addMarker(marker);
+ return this;
+ }
+
+ @Override
+ public LoggingEventBuilder setCause(Throwable t) {
+ loggingEvent.setThrowable(t);
+ return this;
+ }
+
+ @Override
+ public LoggingEventBuilder addArgument(Object p) {
+ loggingEvent.addArgument(p);
+ return this;
+ }
+
+ @Override
+ public LoggingEventBuilder addArgument(Supplier<?> objectSupplier) {
+ loggingEvent.addArgument(objectSupplier.get());
+ return this;
+ }
+
+ @Override
+ public void setCallerBoundary(String fqcn) {
+ loggingEvent.setCallerBoundary(fqcn);
+ }
+
+ @Override
+ public void log() {
+ log(loggingEvent);
+ }
+
+ @Override
+ public LoggingEventBuilder setMessage(String message) {
+ loggingEvent.setMessage(message);
+ return this;
+ }
+ @Override
+ public LoggingEventBuilder setMessage(Supplier<String> messageSupplier) {
+ loggingEvent.setMessage(messageSupplier.get());
+ return this;
+ }
+
+ @Override
+ public void log(String message) {
+ loggingEvent.setMessage(message);
+ log(loggingEvent);
+ }
+
+ @Override
+ public void log(String message, Object arg) {
+ loggingEvent.setMessage(message);
+ loggingEvent.addArgument(arg);
+ log(loggingEvent);
+ }
+
+ @Override
+ public void log(String message, Object arg0, Object arg1) {
+ loggingEvent.setMessage(message);
+ loggingEvent.addArgument(arg0);
+ loggingEvent.addArgument(arg1);
+ log(loggingEvent);
+ }
+
+ @Override
+ public void log(String message, Object... args) {
+ loggingEvent.setMessage(message);
+ loggingEvent.addArguments(args);
+
+ log(loggingEvent);
+ }
+
+ @Override
+ public void log(Supplier<String> messageSupplier) {
+ if (messageSupplier == null) {
+ log((String) null);
+ } else {
+ log(messageSupplier.get());
+ }
+ }
+
+ protected void log(LoggingEvent aLoggingEvent) {
+ setCallerBoundary(DLEB_FQCN);
+ if (logger instanceof LoggingEventAware) {
+ ((LoggingEventAware) logger).log(aLoggingEvent);
+ } else {
+ logViaPublicSLF4JLoggerAPI(aLoggingEvent);
+ }
+ }
+
+ private void logViaPublicSLF4JLoggerAPI(LoggingEvent aLoggingEvent) {
+ Object[] argArray = aLoggingEvent.getArgumentArray();
+ int argLen = argArray == null ? 0 : argArray.length;
+
+ Throwable t = aLoggingEvent.getThrowable();
+ int tLen = t == null ? 0 : 1;
+
+ String msg = aLoggingEvent.getMessage();
+
+ Object[] combinedArguments = new Object[argLen + tLen];
+
+ if (argArray != null) {
+ System.arraycopy(argArray, 0, combinedArguments, 0, argLen);
+ }
+ if (t != null) {
+ combinedArguments[argLen] = t;
+ }
+
+ msg = mergeMarkersAndKeyValuePairs(aLoggingEvent, msg);
+
+ switch (aLoggingEvent.getLevel()) {
+ case TRACE:
+ logger.trace(msg, combinedArguments);
+ break;
+ case DEBUG:
+ logger.debug(msg, combinedArguments);
+ break;
+ case INFO:
+ logger.info(msg, combinedArguments);
+ break;
+ case WARN:
+ logger.warn(msg, combinedArguments);
+ break;
+ case ERROR:
+ logger.error(msg, combinedArguments);
+ break;
+ }
+
+ }
+
+ /**
+ * Prepend markers and key-value pairs to the message.
+ *
+ * @param aLoggingEvent
+ * @param msg
+ * @return
+ */
+ private String mergeMarkersAndKeyValuePairs(LoggingEvent aLoggingEvent, String msg) {
+
+ StringBuilder sb = null;
+
+ if (aLoggingEvent.getMarkers() != null) {
+ sb = new StringBuilder();
+ for (Marker marker : aLoggingEvent.getMarkers()) {
+ sb.append(marker);
+ sb.append(' ');
+ }
+ }
+
+ if (aLoggingEvent.getKeyValuePairs() != null) {
+ if (sb == null) {
+ sb = new StringBuilder();
+ }
+ for (KeyValuePair kvp : aLoggingEvent.getKeyValuePairs()) {
+ sb.append(kvp.key);
+ sb.append('=');
+ sb.append(kvp.value);
+ sb.append(' ');
+ }
+ }
+
+ if (sb != null) {
+ sb.append(msg);
+ return sb.toString();
+ } else {
+ return msg;
+ }
+ }
+
+
+
+ @Override
+ public LoggingEventBuilder addKeyValue(String key, Object value) {
+ loggingEvent.addKeyValue(key, value);
+ return this;
+ }
+
+ @Override
+ public LoggingEventBuilder addKeyValue(String key, Supplier<Object> value) {
+ loggingEvent.addKeyValue(key, value.get());
+ return this;
+ }
+
+}
diff --git a/slf4j-api/src/main/java/org/slf4j/spi/LocationAwareLogger.java b/slf4j-api/src/main/java/org/slf4j/spi/LocationAwareLogger.java
index 8e0a2070..d0d1a31b 100644
--- a/slf4j-api/src/main/java/org/slf4j/spi/LocationAwareLogger.java
+++ b/slf4j-api/src/main/java/org/slf4j/spi/LocationAwareLogger.java
@@ -34,11 +34,13 @@ import org.slf4j.Marker;
* which need to provide hints so that the underlying logging system can extract
* the correct location information (method name, line number).
*
- * @author Ceki Gulcu
+ * @author Ceki G&uuml;lc&uuml;
* @since 1.3
*/
public interface LocationAwareLogger extends Logger {
+ // these constants should be in EventConstants. However, in order to preserve binary backward compatibility
+ // we keep these constants here. {@link EventConstants} redefines these constants using the values below.
final public int TRACE_INT = 00;
final public int DEBUG_INT = 10;
final public int INFO_INT = 20;
@@ -49,9 +51,12 @@ public interface LocationAwareLogger extends Logger {
* Printing method with support for location information.
*
* @param marker The marker to be used for this event, may be null.
+ *
* @param fqcn The fully qualified class name of the <b>logger instance</b>,
* typically the logger class, logger bridge or a logger wrapper.
+ *
* @param level One of the level integers defined in this interface
+ *
* @param message The message for the log event
* @param t Throwable associated with the log event, may be null.
*/
diff --git a/slf4j-api/src/main/java/org/slf4j/spi/LoggerFactoryBinder.java b/slf4j-api/src/main/java/org/slf4j/spi/LoggerFactoryBinder.java
index c0c2ca05..169691f3 100644
--- a/slf4j-api/src/main/java/org/slf4j/spi/LoggerFactoryBinder.java
+++ b/slf4j-api/src/main/java/org/slf4j/spi/LoggerFactoryBinder.java
@@ -31,6 +31,7 @@ import org.slf4j.ILoggerFactory;
* class bind with the appropriate {@link ILoggerFactory} instance.
*
* @author Ceki G&uuml;lc&uuml;
+ * @deprecated
*/
public interface LoggerFactoryBinder {
@@ -47,9 +48,9 @@ public interface LoggerFactoryBinder {
* The String form of the {@link ILoggerFactory} object that this
* <code>LoggerFactoryBinder</code> instance is <em>intended</em> to return.
*
- * <p>This method allows the developer to intterogate this binder's intention
+ * <p>This method allows the developer to interrogate this binder's intention
* which may be different from the {@link ILoggerFactory} instance it is able to
- * yield in practice. The discrepency should only occur in case of errors.
+ * yield in practice. The discrepancy should only occur in case of errors.
*
* @return the class name of the intended {@link ILoggerFactory} instance
*/
diff --git a/slf4j-api/src/main/java/org/slf4j/spi/LoggingEventAware.java b/slf4j-api/src/main/java/org/slf4j/spi/LoggingEventAware.java
new file mode 100644
index 00000000..b833e40c
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/spi/LoggingEventAware.java
@@ -0,0 +1,23 @@
+package org.slf4j.spi;
+
+import org.slf4j.event.LoggingEvent;
+
+/**
+ * A logger capable of logging from org.slf4j.event.LoggingEvent implements this interface.
+ *
+ * <p>Please note that when the {@link #log(LoggingEvent)} method assumes that
+ * the event was filtered beforehand and no further filtering needs to occur by the method itself.
+ * <p>
+ *
+ * <p>Implementations of this interface <b>may</b> apply further filtering but they are not
+ * required to do so. In other words, {@link #log(LoggingEvent)} method is free to assume that
+ * the event was filtered beforehand and no further filtering needs to occur in the method itself.</p>
+ *
+ * See also https://jira.qos.ch/browse/SLF4J-575
+ *
+ * @author Ceki Gulcu
+ * @since 2.0.0
+ */
+public interface LoggingEventAware {
+ void log(LoggingEvent event);
+}
diff --git a/slf4j-api/src/main/java/org/slf4j/spi/LoggingEventBuilder.java b/slf4j-api/src/main/java/org/slf4j/spi/LoggingEventBuilder.java
new file mode 100755
index 00000000..55e24cfb
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/spi/LoggingEventBuilder.java
@@ -0,0 +1,169 @@
+/**
+ * Copyright (c) 2004-2021 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.spi;
+
+import java.util.function.Supplier;
+
+import org.slf4j.Marker;
+
+import org.slf4j.helpers.CheckReturnValue;
+
+/**
+ * This is the main interface in slf4j's fluent API for creating
+ * {@link org.slf4j.event.LoggingEvent logging events}.
+ *
+ * @author Ceki G&uuml;lc&uuml;
+ * @since 2.0.0
+ */
+public interface LoggingEventBuilder {
+
+ /**
+ * Set the cause for the logging event being built.
+ * @param cause a throwable
+ * @return a LoggingEventBuilder, usually <b>this</b>.
+ */
+ @CheckReturnValue
+ LoggingEventBuilder setCause(Throwable cause);
+
+ /**
+ * A {@link Marker marker} to the event being built.
+ *
+ * @param marker a Marker instance to add.
+ * @return a LoggingEventBuilder, usually <b>this</b>.
+ */
+ @CheckReturnValue
+ LoggingEventBuilder addMarker(Marker marker);
+
+ /**
+ * Add an argument to the event being built.
+ *
+ * @param p an Object to add.
+ * @return a LoggingEventBuilder, usually <b>this</b>.
+ */
+ @CheckReturnValue
+ LoggingEventBuilder addArgument(Object p);
+
+ /**
+ * Add an argument supplier to the event being built.
+ *
+ * @param objectSupplier an Object supplier to add.
+ * @return a LoggingEventBuilder, usually <b>this</b>.
+ */
+ @CheckReturnValue
+ LoggingEventBuilder addArgument(Supplier<?> objectSupplier);
+
+
+ /**
+ * Add a {@link org.slf4j.event.KeyValuePair key value pair} to the event being built.
+ *
+ * @param key the key of the key value pair.
+ * @param value the value of the key value pair.
+ * @return a LoggingEventBuilder, usually <b>this</b>.
+ */
+ @CheckReturnValue
+ LoggingEventBuilder addKeyValue(String key, Object value);
+
+ /**
+ * Add a {@link org.slf4j.event.KeyValuePair key value pair} to the event being built.
+ *
+ * @param key the key of the key value pair.
+ * @param valueSupplier a supplier of a value for the key value pair.
+ * @return a LoggingEventBuilder, usually <b>this</b>.
+ */
+ @CheckReturnValue
+ LoggingEventBuilder addKeyValue(String key, Supplier<Object> valueSupplier);
+
+ /**
+ * Sets the message of the logging event.
+ *
+ * @since 2.0.0-beta0
+ */
+ @CheckReturnValue
+ LoggingEventBuilder setMessage(String message);
+
+ /**
+ * Sets the message of the event via a message supplier.
+ *
+ * @param messageSupplier supplies a String to be used as the message for the event
+ * @since 2.0.0-beta0
+ */
+ @CheckReturnValue
+ LoggingEventBuilder setMessage(Supplier<String> messageSupplier);
+
+ /**
+ * After the logging event is built, performs actual logging. This method must be called
+ * for logging to occur.
+ *
+ * If the call to {@link #log()} is omitted, a {@link org.slf4j.event.LoggingEvent LoggingEvent}
+ * will be built but no logging will occur.
+ *
+ * @since 2.0.0-beta0
+ */
+ void log();
+
+ /**
+ * Equivalent to calling {@link #setMessage(String)} followed by {@link #log()};
+ *
+ * @param message the message to log
+ */
+ void log(String message);
+
+ /**
+ * Equivalent to calling {@link #setMessage(String)} followed by {@link #addArgument(Object)}}
+ * and then {@link #log()}
+ *
+ * @param message the message to log
+ * @param arg an argument to be used with the message to log
+ */
+ void log(String message, Object arg);
+
+ /**
+ * Equivalent to calling {@link #setMessage(String)} followed by two calls to
+ * {@link #addArgument(Object)} and then {@link #log()}
+ *
+ * @param message the message to log
+ * @param arg0 first argument to be used with the message to log
+ * @param arg1 second argument to be used with the message to log
+ */
+ void log(String message, Object arg0, Object arg1);
+
+
+ /**
+ * Equivalent to calling {@link #setMessage(String)} followed by zero or more calls to
+ * {@link #addArgument(Object)} (depending on the size of args array) and then {@link #log()}
+ *
+ * @param message the message to log
+ * @param args a list (actually an array) of arguments to be used with the message to log
+ */
+ void log(String message, Object... args);
+
+ /**
+ * Equivalent to calling {@link #setMessage(Supplier)} followed by {@link #log()}
+ *
+ * @param messageSupplier a Supplier returning a message of type String
+ */
+ void log(Supplier<String> messageSupplier);
+
+}
diff --git a/slf4j-api/src/main/java/org/slf4j/spi/MDCAdapter.java b/slf4j-api/src/main/java/org/slf4j/spi/MDCAdapter.java
index 2e637cbe..924849d1 100644
--- a/slf4j-api/src/main/java/org/slf4j/spi/MDCAdapter.java
+++ b/slf4j-api/src/main/java/org/slf4j/spi/MDCAdapter.java
@@ -24,6 +24,7 @@
*/
package org.slf4j.spi;
+import java.util.Deque;
import java.util.Map;
/**
@@ -38,7 +39,7 @@ public interface MDCAdapter {
/**
* Put a context value (the <code>val</code> parameter) as identified with
* the <code>key</code> parameter into the current thread's context map.
- * The <code>key</code> parameter cannot be null. The code>val</code> parameter
+ * The <code>key</code> parameter cannot be null. The <code>val</code> parameter
* can be null only if the underlying implementation supports it.
*
* <p>If the current thread does not have a context map it is created as a side
@@ -55,7 +56,7 @@ public interface MDCAdapter {
public String get(String key);
/**
- * Remove the the context identified by the <code>key</code> parameter.
+ * Remove the context identified by the <code>key</code> parameter.
* The <code>key</code> parameter cannot be null.
*
* <p>
@@ -83,9 +84,50 @@ public interface MDCAdapter {
* map and then copying the map passed as parameter. The context map
* parameter must only contain keys and values of type String.
*
+ * Implementations must support null valued map passed as parameter.
+ *
* @param contextMap must contain only keys and values of type String
*
* @since 1.5.1
*/
public void setContextMap(Map<String, String> contextMap);
+
+ /**
+ * Push a value into the deque(stack) referenced by 'key'.
+ *
+ * @param key identifies the appropriate stack
+ * @param value the value to push into the stack
+ * @since 2.0.0
+ */
+ public void pushByKey(String key, String value);
+
+ /**
+ * Pop the stack referenced by 'key' and return the value possibly null.
+ *
+ * @param key identifies the deque(stack)
+ * @return the value just popped. May be null/
+ * @since 2.0.0
+ */
+ public String popByKey(String key);
+
+ /**
+ * Returns a copy of the deque(stack) referenced by 'key'. May be null.
+ *
+ * @param key identifies the stack
+ * @return copy of stack referenced by 'key'. May be null.
+ *
+ * @since 2.0.0
+ */
+ public Deque<String> getCopyOfDequeByKey(String key);
+
+
+ /**
+ * Clear the deque(stack) referenced by 'key'.
+ *
+ * @param key identifies the stack
+ *
+ * @since 2.0.0
+ */
+ public void clearDequeByKey(String key);
+
}
diff --git a/slf4j-api/src/main/java/org/slf4j/spi/MarkerFactoryBinder.java b/slf4j-api/src/main/java/org/slf4j/spi/MarkerFactoryBinder.java
index a71140c9..0502ffad 100644
--- a/slf4j-api/src/main/java/org/slf4j/spi/MarkerFactoryBinder.java
+++ b/slf4j-api/src/main/java/org/slf4j/spi/MarkerFactoryBinder.java
@@ -31,6 +31,7 @@ import org.slf4j.IMarkerFactory;
* class bind with the appropriate {@link IMarkerFactory} instance.
*
* @author Ceki G&uuml;lc&uuml;
+ * @deprecated
*/
public interface MarkerFactoryBinder {
@@ -47,9 +48,9 @@ public interface MarkerFactoryBinder {
* The String form of the {@link IMarkerFactory} object that this
* <code>MarkerFactoryBinder</code> instance is <em>intended</em> to return.
*
- * <p>This method allows the developer to intterogate this binder's intention
+ * <p>This method allows the developer to interrogate this binder's intention
* which may be different from the {@link IMarkerFactory} instance it is able to
- * return. Such a discrepency should only occur in case of errors.
+ * return. Such a discrepancy should only occur in case of errors.
*
* @return the class name of the intended {@link IMarkerFactory} instance
*/
diff --git a/slf4j-api/src/main/java/org/slf4j/spi/NOPLoggingEventBuilder.java b/slf4j-api/src/main/java/org/slf4j/spi/NOPLoggingEventBuilder.java
new file mode 100755
index 00000000..e356b47f
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/spi/NOPLoggingEventBuilder.java
@@ -0,0 +1,100 @@
+package org.slf4j.spi;
+
+import java.util.function.Supplier;
+
+import org.slf4j.Marker;
+import org.slf4j.event.Level;
+
+/**
+ * <p>A no-operation implementation of {@link LoggingEventBuilder}.</p>
+ *
+ * <p>As the name indicates, the method in this class do nothing, except when a return value is expected
+ * in which case a singleton, i.e. the unique instance of this class is returned.
+ * </p
+ *
+ * @author Ceki G&uuml;lc&uuml;
+ * @since 2.0.0
+ *
+ */
+public class NOPLoggingEventBuilder implements LoggingEventBuilder {
+
+ static final NOPLoggingEventBuilder SINGLETON = new NOPLoggingEventBuilder();
+
+ private NOPLoggingEventBuilder() {
+ }
+
+ /**
+ * <p>Returns the singleton instance of this class.
+ * Used by {@link org.slf4j.Logger#makeLoggingEventBuilder(Level) makeLoggingEventBuilder(Level)}.</p>
+ *
+ * @return the singleton instance of this class
+ */
+ public static LoggingEventBuilder singleton() {
+ return SINGLETON;
+ }
+
+ @Override
+ public LoggingEventBuilder addMarker(Marker marker) {
+ return singleton();
+ }
+
+ @Override
+ public LoggingEventBuilder addArgument(Object p) {
+ return singleton();
+ }
+
+ @Override
+ public LoggingEventBuilder addArgument(Supplier<?> objectSupplier) {
+ return singleton();
+ }
+
+ @Override
+ public LoggingEventBuilder addKeyValue(String key, Object value) {
+ return singleton();
+ }
+
+ @Override
+ public LoggingEventBuilder addKeyValue(String key, Supplier<Object> value) {
+ return singleton();
+ }
+
+ @Override
+ public LoggingEventBuilder setCause(Throwable cause) {
+ return singleton();
+ }
+
+ @Override
+ public void log() {
+ }
+
+ @Override
+ public LoggingEventBuilder setMessage(String message) {
+ return this;
+ }
+ @Override
+ public LoggingEventBuilder setMessage(Supplier<String> messageSupplier) {
+ return this;
+ }
+
+ @Override
+ public void log(String message) {
+ }
+
+ @Override
+ public void log(Supplier<String> messageSupplier) {
+ }
+
+ @Override
+ public void log(String message, Object arg) {
+ }
+
+ @Override
+ public void log(String message, Object arg0, Object arg1) {
+ }
+
+ @Override
+ public void log(String message, Object... args) {
+
+ }
+
+}
diff --git a/slf4j-api/src/main/java/org/slf4j/spi/SLF4JServiceProvider.java b/slf4j-api/src/main/java/org/slf4j/spi/SLF4JServiceProvider.java
new file mode 100755
index 00000000..83e08741
--- /dev/null
+++ b/slf4j-api/src/main/java/org/slf4j/spi/SLF4JServiceProvider.java
@@ -0,0 +1,60 @@
+package org.slf4j.spi;
+
+import org.slf4j.ILoggerFactory;
+import org.slf4j.IMarkerFactory;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+
+/**
+ * This interface based on {@link java.util.ServiceLoader} paradigm.
+ *
+ * <p>It replaces the old static-binding mechanism used in SLF4J versions 1.0.x to 1.7.x.
+ *
+ * @author Ceki G&uml;lc&uml;
+ * @since 1.8
+ */
+public interface SLF4JServiceProvider {
+
+ /**
+ * Return the instance of {@link ILoggerFactory} that
+ * {@link org.slf4j.LoggerFactory} class should bind to.
+ *
+ * @return instance of {@link ILoggerFactory}
+ */
+ public ILoggerFactory getLoggerFactory();
+
+ /**
+ * Return the instance of {@link IMarkerFactory} that
+ * {@link org.slf4j.MarkerFactory} class should bind to.
+ *
+ * @return instance of {@link IMarkerFactory}
+ */
+ public IMarkerFactory getMarkerFactory();
+
+ /**
+ * Return the instance of {@link MDCAdapter} that
+ * {@link MDC} should bind to.
+ *
+ * @return instance of {@link MDCAdapter}
+ */
+ public MDCAdapter getMDCAdapter();
+
+ /**
+ * Return the maximum API version for SLF4J that the logging
+ * implementation supports.
+ *
+ * <p>For example: {@code "2.0.1"}.
+ *
+ * @return the string API version.
+ */
+ public String getRequestedApiVersion();
+
+ /**
+ * Initialize the logging back-end.
+ *
+ * <p><b>WARNING:</b> This method is intended to be called once by
+ * {@link LoggerFactory} class and from nowhere else.
+ *
+ */
+ public void initialize();
+}
diff --git a/slf4j-api/src/main/java9/module-info.java b/slf4j-api/src/main/java9/module-info.java
new file mode 100755
index 00000000..96f08f29
--- /dev/null
+++ b/slf4j-api/src/main/java9/module-info.java
@@ -0,0 +1,8 @@
+module org.slf4j {
+ exports org.slf4j;
+ exports org.slf4j.spi;
+ exports org.slf4j.event;
+ exports org.slf4j.helpers;
+ uses org.slf4j.spi.SLF4JServiceProvider;
+requires java.base;
+}
diff --git a/slf4j-api/src/main/resources/META-INF/MANIFEST.MF b/slf4j-api/src/main/resources/META-INF/MANIFEST.MF
deleted file mode 100644
index 2940ef8f..00000000
--- a/slf4j-api/src/main/resources/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,8 +0,0 @@
-Implementation-Title: slf4j-api
-Bundle-ManifestVersion: 2
-Bundle-SymbolicName: slf4j.api
-Bundle-Name: slf4j-api
-Bundle-Vendor: SLF4J.ORG
-Bundle-RequiredExecutionEnvironment: J2SE-1.5
-Export-Package: org.slf4j;version=${parsedVersion.osgiVersion}, org.slf4j.spi;version=${parsedVersion.osgiVersion}, org.slf4j.helpers;version=${parsedVersion.osgiVersion}
-Import-Package: org.slf4j.impl;version=${slf4j.api.minimum.compatible.version}
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 100755
index 00000000..30ab5705
--- /dev/null
+++ b/slf4j-api/src/test/java/org/slf4j/LoggerAccessingThread.java
@@ -0,0 +1,62 @@
+/**
+ * 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.List;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class LoggerAccessingThread extends Thread {
+ private static final int LOOP_LEN = 32;
+
+ final CyclicBarrier barrier;
+ final int count;
+ final AtomicLong eventCount;
+ List<Logger> loggerList;
+
+ public LoggerAccessingThread(final CyclicBarrier barrier, List<Logger> loggerList, final int count, final AtomicLong eventCount) {
+ this.barrier = barrier;
+ this.loggerList = loggerList;
+ this.count = count;
+ this.eventCount = eventCount;
+ }
+
+ public void run() {
+ try {
+ barrier.await();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ String loggerNamePrefix = this.getClass().getName();
+ for (int i = 0; i < LOOP_LEN; i++) {
+ Logger logger = LoggerFactory.getLogger(loggerNamePrefix + "-" + count + "-" + i);
+ loggerList.add(logger);
+ Thread.yield();
+ logger.info("in run method");
+ eventCount.getAndIncrement();
+ }
+ }
+}
diff --git a/slf4j-api/src/test/java/org/slf4j/LoggerFactoryTest.java b/slf4j-api/src/test/java/org/slf4j/LoggerFactoryTest.java
new file mode 100644
index 00000000..ed618171
--- /dev/null
+++ b/slf4j-api/src/test/java/org/slf4j/LoggerFactoryTest.java
@@ -0,0 +1,91 @@
+package org.slf4j;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.spi.MDCAdapter;
+import org.slf4j.spi.SLF4JServiceProvider;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.*;
+
+public class LoggerFactoryTest {
+ private PrintStream rawSyserr;
+ private ByteArrayOutputStream mockedSyserr;
+
+ final ClassLoader classLoaderOfLoggerFactory = LoggerFactory.class.getClassLoader();
+
+ @Before
+ public void setUp() {
+ rawSyserr = System.err;
+ mockedSyserr = new ByteArrayOutputStream();
+ System.setErr(new PrintStream(mockedSyserr));
+ }
+
+ @After
+ public void cleanUp() {
+ System.clearProperty(LoggerFactory.PROVIDER_PROPERTY_KEY);
+ System.setErr(rawSyserr);
+ }
+
+ @Test
+ public void testExplicitlySpecified() {
+ System.setProperty(LoggerFactory.PROVIDER_PROPERTY_KEY, "org.slf4j.LoggerFactoryTest$TestingProvider");
+ SLF4JServiceProvider provider = LoggerFactory.loadExplicitlySpecified(classLoaderOfLoggerFactory);
+ assertTrue("provider should be instance of TestingProvider class", provider instanceof TestingProvider);
+ assertTrue(mockedSyserr.toString().contains(" Attempting to load provider \"org.slf4j.LoggerFactoryTest$TestingProvider\" specified via \"slf4j.provider\" system property"));
+ System.out.println(mockedSyserr.toString());
+
+
+ }
+
+ @Test
+ public void testExplicitlySpecifiedNull() {
+ assertNull(LoggerFactory.loadExplicitlySpecified(classLoaderOfLoggerFactory));
+ }
+
+ @Test
+ public void testExplicitlySpecifyMissingServiceProvider() {
+ System.setProperty(LoggerFactory.PROVIDER_PROPERTY_KEY, "com.example.ServiceProvider");
+ SLF4JServiceProvider provider = LoggerFactory.loadExplicitlySpecified(classLoaderOfLoggerFactory);
+ assertNull(provider);
+ assertTrue(mockedSyserr.toString().contains("Failed to instantiate the specified SLF4JServiceProvider (com.example.ServiceProvider)"));
+ }
+
+ @Test
+ public void testExplicitlySpecifyNonServiceProvider() {
+ System.setProperty(LoggerFactory.PROVIDER_PROPERTY_KEY, "java.lang.String");
+ assertNull(LoggerFactory.loadExplicitlySpecified(classLoaderOfLoggerFactory));
+ assertTrue(mockedSyserr.toString().contains("Specified SLF4JServiceProvider (java.lang.String) does not implement SLF4JServiceProvider interface"));
+ }
+
+ public static class TestingProvider implements SLF4JServiceProvider {
+ @Override
+ public ILoggerFactory getLoggerFactory() {
+ return null;
+ }
+
+ @Override
+ public IMarkerFactory getMarkerFactory() {
+ return null;
+ }
+
+ @Override
+ public MDCAdapter getMDCAdapter() {
+ return null;
+ }
+
+ @Override
+ public String getRequestedApiVersion() {
+ return null;
+ }
+
+ @Override
+ public void initialize() {
+
+ }
+ }
+}
diff --git a/slf4j-api/src/test/java/org/slf4j/BasicMarkerTest.java b/slf4j-api/src/test/java/org/slf4j/basicTests/BasicMarkerTest.java
index 50471b59..5ce33471 100644
--- a/slf4j-api/src/test/java/org/slf4j/BasicMarkerTest.java
+++ b/slf4j-api/src/test/java/org/slf4j/basicTests/BasicMarkerTest.java
@@ -22,12 +22,15 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j;
+package org.slf4j.basicTests;
-import java.util.Iterator;
+import static org.junit.Assert.*;
-import junit.framework.TestCase;
+import java.util.Iterator;
+import org.junit.Test;
+import org.slf4j.IMarkerFactory;
+import org.slf4j.Marker;
import org.slf4j.helpers.BasicMarkerFactory;
/**
@@ -36,7 +39,7 @@ import org.slf4j.helpers.BasicMarkerFactory;
* @author Ceki G&uuml;lc&uuml;
* @author Joern Huxhorn
*/
-public class BasicMarkerTest extends TestCase {
+public class BasicMarkerTest {
static final String BLUE_STR = "BLUE";
static final String RED_STR = "RED";
static final String GREEN_STR = "GREEN";
@@ -69,6 +72,7 @@ public class BasicMarkerTest extends TestCase {
multiComp.add(comp);
}
+ @Test
public void testPrimitive() {
assertEquals(BLUE_STR, blue.getName());
assertTrue(blue.contains(blue));
@@ -80,20 +84,24 @@ public class BasicMarkerTest extends TestCase {
assertTrue(blue2.contains(blue));
}
+ @Test
public void testPrimitiveByName() {
assertTrue(blue.contains(BLUE_STR));
}
+ @Test
public void testComposite() {
assertTrue(comp.contains(comp));
assertTrue(comp.contains(blue));
}
+ @Test
public void testCompositeByName() {
assertTrue(comp.contains(COMP_STR));
assertTrue(comp.contains(BLUE_STR));
}
+ @Test
public void testMultiComposite() {
assertTrue(multiComp.contains(comp));
assertTrue(multiComp.contains(blue));
@@ -101,6 +109,7 @@ public class BasicMarkerTest extends TestCase {
assertFalse(multiComp.contains(red));
}
+ @Test
public void testMultiCompositeByName() {
assertTrue(multiComp.contains(COMP_STR));
assertTrue(multiComp.contains(BLUE_STR));
@@ -108,6 +117,7 @@ public class BasicMarkerTest extends TestCase {
assertFalse(multiComp.contains(RED_STR));
}
+ @Test
public void testMultiAdd() {
Marker parent = factory.getMarker(PARENT_MARKER_STR);
Marker child = factory.getMarker(CHILD_MARKER_STR);
@@ -122,6 +132,7 @@ public class BasicMarkerTest extends TestCase {
assertFalse(iterator.hasNext());
}
+ @Test
public void testAddRemove() {
final String NEW_PREFIX = "NEW_";
Marker parent = factory.getMarker(NEW_PREFIX + PARENT_MARKER_STR);
@@ -142,6 +153,7 @@ public class BasicMarkerTest extends TestCase {
assertFalse(parent.remove(child));
}
+ @Test
public void testSelfRecursion() {
final String diffPrefix = "NEW_" + diff;
final String PARENT_NAME = diffPrefix + PARENT_MARKER_STR;
@@ -155,6 +167,7 @@ public class BasicMarkerTest extends TestCase {
assertFalse(parent.contains(NOT_CONTAINED_MARKER_STR));
}
+ @Test
public void testIndirectRecursion() {
final String diffPrefix = "NEW_" + diff;
final String PARENT_NAME = diffPrefix + PARENT_MARKER_STR;
@@ -175,6 +188,7 @@ public class BasicMarkerTest extends TestCase {
assertFalse(parent.contains(NOT_CONTAINED_MARKER_STR));
}
+ @Test
public void testHomonyms() {
final String diffPrefix = "homonym" + diff;
final String PARENT_NAME = diffPrefix + PARENT_MARKER_STR;
diff --git a/slf4j-api/src/test/java/org/slf4j/Differentiator.java b/slf4j-api/src/test/java/org/slf4j/basicTests/Differentiator.java
index 09b9a35a..fe2a72ee 100644
--- a/slf4j-api/src/test/java/org/slf4j/Differentiator.java
+++ b/slf4j-api/src/test/java/org/slf4j/basicTests/Differentiator.java
@@ -23,7 +23,7 @@
*
*/
-package org.slf4j;
+package org.slf4j.basicTests;
import java.util.Random;
diff --git a/slf4j-api/src/test/java/org/slf4j/basicTests/DoubleCheckedInt.java b/slf4j-api/src/test/java/org/slf4j/basicTests/DoubleCheckedInt.java
new file mode 100755
index 00000000..42a39e64
--- /dev/null
+++ b/slf4j-api/src/test/java/org/slf4j/basicTests/DoubleCheckedInt.java
@@ -0,0 +1,141 @@
+package org.slf4j.basicTests;
+
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+
+/**
+ * This class demonstrates that threads accessing the STATE variable always see a consistent value.
+ *
+ * During ongoing initialization the observed value is either ONGOING_INITIALIZATION
+ * or one of {SUCCESS, FAILURE}.
+ *
+ * Post initialization the observed value is always one of {SUCCESS, FAILURE}.
+ *
+ * See also http://jira.qos.ch/browse/SLF4J-167
+ *
+ * @author ceki
+ *
+ */
+public class DoubleCheckedInt {
+
+ final static int THREAD_COUNT = 10 + Runtime.getRuntime().availableProcessors() * 2;
+ final static int UNINITIALIZED_STATE = 0;
+ final static int ONGOING_INITIALIZATION = 1;
+ final static int SUCCESS = 2;
+ final static int FAILURE = 3;
+ final static int NUMBER_OF_STATES = FAILURE + 1;
+
+ private static int STATE = UNINITIALIZED_STATE;
+
+ public static int getState() {
+ if (STATE == 0) {
+ synchronized (DoubleCheckedInt.class) {
+ if (STATE == UNINITIALIZED_STATE) {
+ STATE = ONGOING_INITIALIZATION;
+ long r = System.nanoTime();
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ }
+ if (r % 2 == 0) {
+ STATE = SUCCESS;
+ } else {
+ STATE = FAILURE;
+ }
+ }
+ }
+ }
+ return STATE;
+ }
+
+ static public void main(String[] args) throws InterruptedException, BrokenBarrierException {
+ StateAccessingThread[] preInitializationThreads = harness();
+ check(preInitializationThreads, false);
+
+ System.out.println("============");
+ StateAccessingThread[] postInitializationThreads = harness();
+ check(postInitializationThreads, true);
+ }
+
+ private static StateAccessingThread[] harness() throws InterruptedException, BrokenBarrierException {
+ StateAccessingThread[] threads = new StateAccessingThread[THREAD_COUNT];
+ final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1);
+ for (int i = 0; i < THREAD_COUNT; i++) {
+ threads[i] = new StateAccessingThread(barrier);
+ threads[i].start();
+ }
+
+ barrier.await();
+ for (int i = 0; i < THREAD_COUNT; i++) {
+ threads[i].join();
+ }
+ return threads;
+ }
+
+ private static void check(StateAccessingThread[] threads, boolean postInit) {
+
+ int[] stateCount = getStateCount(threads);
+ printStateCount(stateCount);
+
+ if (stateCount[UNINITIALIZED_STATE] != 0) {
+ throw new IllegalStateException("getState() should never return a zero value");
+ }
+
+ if (stateCount[SUCCESS] != 0 && stateCount[FAILURE] != 0) {
+ throw new IllegalStateException("getState() should return consistent values");
+ }
+
+ if (postInit) {
+ if (stateCount[SUCCESS] != THREAD_COUNT && stateCount[FAILURE] != THREAD_COUNT) {
+ throw new IllegalStateException("getState() should return consistent values");
+ }
+ }
+
+ }
+
+ private static void printStateCount(int[] stateCount) {
+ for (int i = 0; i < NUMBER_OF_STATES; i++) {
+ switch (i) {
+ case UNINITIALIZED_STATE:
+ System.out.println("UNINITIALIZED_STATE count: " + stateCount[i]);
+ break;
+ case ONGOING_INITIALIZATION:
+ System.out.println("ONGOING_INITIALIZATION count: " + stateCount[i]);
+ break;
+ case SUCCESS:
+ System.out.println("SUCCESS count: " + stateCount[i]);
+ break;
+ case FAILURE:
+ System.out.println("FAILURE count: " + stateCount[i]);
+ break;
+ }
+ }
+ }
+
+ private static int[] getStateCount(StateAccessingThread[] threads) {
+ int[] valCount = new int[NUMBER_OF_STATES];
+ for (StateAccessingThread thread : threads) {
+ int val = thread.state;
+ valCount[val] = valCount[val] + 1;
+ }
+ return valCount;
+ }
+
+ static class StateAccessingThread extends Thread {
+ public int state = -1;
+ final CyclicBarrier barrier;
+
+ StateAccessingThread(CyclicBarrier barrier) {
+ this.barrier = barrier;
+ }
+
+ public void run() {
+ try {
+ barrier.await();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ state = DoubleCheckedInt.getState();
+ }
+ };
+}
diff --git a/slf4j-api/src/test/java/org/slf4j/basicTests/FluentAPIUsage.java b/slf4j-api/src/test/java/org/slf4j/basicTests/FluentAPIUsage.java
new file mode 100755
index 00000000..cc8434a9
--- /dev/null
+++ b/slf4j-api/src/test/java/org/slf4j/basicTests/FluentAPIUsage.java
@@ -0,0 +1,27 @@
+package org.slf4j.basicTests;
+
+import static org.junit.Assert.assertFalse;
+
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.event.Level;
+
+public class FluentAPIUsage {
+
+ @Test
+ public void smoke() {
+ String name = "smoke";
+ Logger logger = LoggerFactory.getLogger(name);
+ logger.atTrace().addKeyValue("a", "n").setCause(new Throwable()).log("hello");
+ }
+
+
+ @Test
+ public void smokxce() {
+ String name = "smoke";
+ Logger logger = LoggerFactory.getLogger(name);
+ assertFalse(logger.isEnabledForLevel(Level.DEBUG));
+ }
+
+}
diff --git a/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMDCBinder.java b/slf4j-api/src/test/java/org/slf4j/basicTests/NoBindingMultithreadedInitializationTest.java
index 77742309..024a7f82 100644
--- a/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMDCBinder.java
+++ b/slf4j-api/src/test/java/org/slf4j/basicTests/NoBindingMultithreadedInitializationTest.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2004-2011 QOS.ch
+ * Copyright (c) 2004-2016 QOS.ch
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
@@ -22,34 +22,35 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j.impl;
+package org.slf4j.basicTests;
-import org.slf4j.spi.MDCAdapter;
+import org.junit.After;
+import org.junit.Before;
+import org.slf4j.LoggerFactoryFriend;
+import org.slf4j.testHarness.MultithreadedInitializationTest;
/**
- * This implementation is bound to {@link Log4jMDCAdapter}.
- *
- * @author Ceki G&uuml;lc&uuml;
+ * Checks that when no binding is present, proper clean up is performed by LoggerFactory.
+ *
+ * See SLF4J-469
+ *
+ * @author David Harsha
*/
-public class StaticMDCBinder {
-
- /**
- * The unique instance of this class.
- */
- public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
+public class NoBindingMultithreadedInitializationTest extends MultithreadedInitializationTest {
+ final String loggerName = this.getClass().getName();
- private StaticMDCBinder() {
+ @Before
+ public void setup() {
+ LoggerFactoryFriend.reset();
}
- /**
- * Currently this method always returns an instance of
- * {@link StaticMDCBinder}.
- */
- public MDCAdapter getMDCA() {
- return new Log4jMDCAdapter();
+ @After
+ public void tearDown() throws Exception {
+ LoggerFactoryFriend.reset();
}
- public String getMDCAdapterClassStr() {
- return Log4jMDCAdapter.class.getName();
+ @Override
+ protected long getRecordedEventCount() {
+ return eventCount.get();
}
}
diff --git a/slf4j-api/src/test/java/org/slf4j/NoBindingTest.java b/slf4j-api/src/test/java/org/slf4j/basicTests/NoBindingTest.java
index 7a5ec2d8..8e1dd16c 100644
--- a/slf4j-api/src/test/java/org/slf4j/NoBindingTest.java
+++ b/slf4j-api/src/test/java/org/slf4j/basicTests/NoBindingTest.java
@@ -22,30 +22,40 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j;
+package org.slf4j.basicTests;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import java.util.Random;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
import org.slf4j.helpers.BasicMarker;
import org.slf4j.helpers.NOPLogger;
-import junit.framework.TestCase;
-
-public class NoBindingTest extends TestCase {
+public class NoBindingTest {
int diff = new Random().nextInt(10000);
+ @Test
public void testLogger() {
Logger logger = LoggerFactory.getLogger(NoBindingTest.class);
logger.debug("hello" + diff);
assertTrue(logger instanceof NOPLogger);
}
+ @Test
public void testMDC() {
MDC.put("k" + diff, "v");
assertNull(MDC.get("k"));
}
+ @Test
public void testMarker() {
Marker m = MarkerFactory.getMarker("a" + diff);
assertTrue(m instanceof BasicMarker);
diff --git a/slf4j-api/src/test/java/org/slf4j/eventTest/EventRecordingLoggerTest.java b/slf4j-api/src/test/java/org/slf4j/eventTest/EventRecordingLoggerTest.java
new file mode 100644
index 00000000..e2ec1c05
--- /dev/null
+++ b/slf4j-api/src/test/java/org/slf4j/eventTest/EventRecordingLoggerTest.java
@@ -0,0 +1,531 @@
+package org.slf4j.eventTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Marker;
+import org.slf4j.event.EventRecordingLogger;
+import org.slf4j.event.Level;
+import org.slf4j.event.SubstituteLoggingEvent;
+import org.slf4j.helpers.BasicMarkerFactory;
+import org.slf4j.helpers.SubstituteLogger;
+
+import java.util.Queue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import static org.junit.Assert.*;
+
+public class EventRecordingLoggerTest {
+ private Queue<SubstituteLoggingEvent> queue;
+ private EventRecordingLogger logger;
+ private String message;
+ private Object param1;
+ private Object param2;
+ private Object param3;
+ private Object[] oneParam;
+ private Object[] twoParams;
+ private Object[] threeParams;
+ private Throwable exception;
+ private Marker marker;
+
+ @Before
+ public void setUp() {
+ queue = new LinkedBlockingQueue<>();
+ logger = new EventRecordingLogger(new SubstituteLogger("testLogger", queue, true), queue);
+ message = "Test message with 3 parameters {} {} {} {}";
+ param1 = 1;
+ param2 = 2;
+ param3 = 3;
+ oneParam = new Object[] { param1 };
+ twoParams = new Object[] { param1, param2 };
+ threeParams = new Object[] { param1, param2, param3 };
+ exception = new IllegalStateException("We just need an exception");
+ marker = new BasicMarkerFactory().getMarker("testMarker");
+ }
+
+ @After
+ public void tearDown() {
+ assertTrue(queue.isEmpty());
+ }
+
+ @Test
+ public void singleMessage() {
+ for (Level level : Level.values()) {
+ singleMessageCheck(level);
+ }
+ }
+
+ private void singleMessageCheck(Level level) {
+ switch (level) {
+ case TRACE:
+ logger.trace(message);
+ break;
+ case DEBUG:
+ logger.debug(message);
+ break;
+ case INFO:
+ logger.info(message);
+ break;
+ case WARN:
+ logger.warn(message);
+ break;
+ case ERROR:
+ logger.error(message);
+ break;
+ }
+ verifyMessageWithoutMarker(level, null, null);
+ }
+
+ @Test
+ public void oneParameter() {
+ for (Level level : Level.values()) {
+ oneParameterCheck(level);
+ }
+ }
+
+ private void oneParameterCheck(Level level) {
+ switch (level) {
+ case TRACE:
+ logger.trace(message, param1);
+ break;
+ case DEBUG:
+ logger.debug(message, param1);
+ break;
+ case INFO:
+ logger.info(message, param1);
+ break;
+ case WARN:
+ logger.warn(message, param1);
+ break;
+ case ERROR:
+ logger.error(message, param1);
+ break;
+ }
+ verifyMessageWithoutMarker(level, oneParam, null);
+ }
+
+ @Test
+ public void messageTwoParameters() {
+ for (Level level : Level.values()) {
+ messageTwoParametersCheck(level);
+ }
+ }
+
+ private void messageTwoParametersCheck(Level level) {
+ switch (level) {
+ case TRACE:
+ logger.trace(message, param1, param2);
+ break;
+ case DEBUG:
+ logger.debug(message, param1, param2);
+ break;
+ case INFO:
+ logger.info(message, param1, param2);
+ break;
+ case WARN:
+ logger.warn(message, param1, param2);
+ break;
+ case ERROR:
+ logger.error(message, param1, param2);
+ break;
+ }
+ verifyMessageWithoutMarker(level, twoParams, null);
+ }
+
+ @Test
+ public void traceMessageThreeParameters() {
+ for (Level level : Level.values()) {
+ threeParameterCheck(level);
+ }
+ }
+
+ private void threeParameterCheck(Level level) {
+ switch (level) {
+ case TRACE:
+ logger.trace(message, param1, param2, param3);
+ break;
+ case DEBUG:
+ logger.debug(message, param1, param2, param3);
+ break;
+ case INFO:
+ logger.info(message, param1, param2, param3);
+ break;
+ case WARN:
+ logger.warn(message, param1, param2, param3);
+ break;
+ case ERROR:
+ logger.error(message, param1, param2, param3);
+ break;
+ }
+ verifyMessageWithoutMarker(level, threeParams, null);
+ }
+
+ @Test
+ public void testMessageThrowable() {
+ for (Level level : Level.values()) {
+ throwableCheck(level);
+ }
+ }
+
+ private void throwableCheck(Level level) {
+ switch (level) {
+ case TRACE:
+ logger.trace(message, exception);
+ break;
+ case DEBUG:
+ logger.debug(message, exception);
+ break;
+ case INFO:
+ logger.info(message, exception);
+ break;
+ case WARN:
+ logger.warn(message, exception);
+ break;
+ case ERROR:
+ logger.error(message, exception);
+ break;
+ }
+ verifyMessageWithoutMarker(level, null, exception);
+ }
+
+ @Test
+ public void traceMessageOneParameterThrowable() {
+ for (Level level : Level.values()) {
+ oneParamThrowableCheck(level);
+ }
+ }
+
+ private void oneParamThrowableCheck(Level level) {
+ switch (level) {
+ case TRACE:
+ logger.trace(message, param1, exception);
+ break;
+ case DEBUG:
+ logger.debug(message, param1, exception);
+ break;
+ case INFO:
+ logger.info(message, param1, exception);
+ break;
+ case WARN:
+ logger.warn(message, param1, exception);
+ break;
+ case ERROR:
+ logger.error(message, param1, exception);
+ break;
+ }
+ verifyMessageWithoutMarker(level, oneParam, exception);
+ }
+
+ @Test
+ public void traceMessageTwoParametersThrowable() {
+ for (Level level : Level.values()) {
+ twoParamThrowableCheck(level);
+ }
+ }
+
+ private void twoParamThrowableCheck(Level level) {
+ switch (level) {
+ case TRACE:
+ logger.trace(message, param1, param2, exception);
+ break;
+ case DEBUG:
+ logger.debug(message, param1, param2, exception);
+ break;
+ case INFO:
+ logger.info(message, param1, param2, exception);
+ break;
+ case WARN:
+ logger.warn(message, param1, param2, exception);
+ break;
+ case ERROR:
+ logger.error(message, param1, param2, exception);
+ break;
+ }
+ verifyMessageWithoutMarker(level, twoParams, exception);
+ }
+
+ @Test
+ public void testMessageThreeParametersThrowable() {
+ for (Level level : Level.values()) {
+ messageWith3ArgsPlusException(level);
+ }
+ }
+
+ private void messageWith3ArgsPlusException(Level level) {
+ switch (level) {
+ case TRACE:
+ logger.trace(message, param1, param2, param3, exception);
+ break;
+ case DEBUG:
+ logger.debug(message, param1, param2, param3, exception);
+ break;
+ case INFO:
+ logger.info(message, param1, param2, param3, exception);
+ break;
+ case WARN:
+ logger.warn(message, param1, param2, param3, exception);
+ break;
+ case ERROR:
+ logger.error(message, param1, param2, param3, exception);
+ break;
+ }
+ verifyMessageWithoutMarker(level, threeParams, exception);
+ }
+
+ @Test
+ public void markerMessage() {
+ for (Level level : Level.values()) {
+ markerMessageCheck(level);
+ }
+ }
+
+ private void markerMessageCheck(Level level) {
+ switch (level) {
+ case TRACE:
+ logger.trace(marker, message);
+ break;
+ case DEBUG:
+ logger.debug(marker, message);
+ break;
+ case INFO:
+ logger.info(marker, message);
+ break;
+ case WARN:
+ logger.warn(marker, message);
+ break;
+ case ERROR:
+ logger.error(marker, message);
+ break;
+ }
+ verifyMessage(level, marker, null, null);
+ }
+
+ @Test
+ public void markerMessageOneParameter() {
+ for (Level level : Level.values()) {
+ markerMessageOneParameter(level);
+ }
+ }
+
+ private void markerMessageOneParameter(Level level) {
+ switch (level) {
+ case TRACE:
+ logger.trace(marker, message, param1);
+ break;
+ case DEBUG:
+ logger.debug(marker, message, param1);
+ break;
+ case INFO:
+ logger.info(marker, message, param1);
+ break;
+ case WARN:
+ logger.warn(marker, message, param1);
+ break;
+ case ERROR:
+ logger.error(marker, message, param1);
+ break;
+ }
+ verifyMessage(level, marker, oneParam, null);
+ }
+
+ @Test
+ public void traceMarkerMessageTwoParameters() {
+ for (Level level : Level.values()) {
+ markerMessageTwoParameters(level);
+ }
+ }
+
+ private void markerMessageTwoParameters(Level level) {
+ switch (level) {
+ case TRACE:
+ logger.trace(marker, message, param1, param2);
+ break;
+ case DEBUG:
+ logger.debug(marker, message, param1, param2);
+ break;
+ case INFO:
+ logger.info(marker, message, param1, param2);
+ break;
+ case WARN:
+ logger.warn(marker, message, param1, param2);
+ break;
+ case ERROR:
+ logger.error(marker, message, param1, param2);
+ break;
+ }
+ verifyMessage(level, marker, twoParams, null);
+ }
+
+ @Test
+ public void traceMarkerMessageThreeParameters() {
+ for (Level level : Level.values()) {
+ markerMessageThreeParameters(level);
+ }
+ }
+
+ private void markerMessageThreeParameters(Level level) {
+ switch (level) {
+ case TRACE:
+ logger.trace(marker, message, param1, param2, param3);
+ break;
+ case DEBUG:
+ logger.debug(marker, message, param1, param2, param3);
+ break;
+ case INFO:
+ logger.info(marker, message, param1, param2, param3);
+ break;
+ case WARN:
+ logger.warn(marker, message, param1, param2, param3);
+ break;
+ case ERROR:
+ logger.error(marker, message, param1, param2, param3);
+ break;
+ }
+ verifyMessage(level, marker, threeParams, null);
+ }
+
+ @Test
+ public void markerMessageThrowable() {
+ for (Level level : Level.values()) {
+ markerMessageThrowable(level);
+ }
+ }
+
+ private void markerMessageThrowable(Level level) {
+ switch (level) {
+ case TRACE:
+ logger.trace(marker, message, exception);
+ break;
+ case DEBUG:
+ logger.debug(marker, message, exception);
+ break;
+ case INFO:
+ logger.info(marker, message, exception);
+ break;
+ case WARN:
+ logger.warn(marker, message, exception);
+ break;
+ case ERROR:
+ logger.error(marker, message, exception);
+ break;
+ }
+ verifyMessage(level, marker, null, exception);
+ }
+
+ @Test
+ public void markerMessageOneParameterThrowable() {
+ for (Level level : Level.values()) {
+ markerMessageOneParameterThrowableCheck(level);
+ }
+ }
+
+ private void markerMessageOneParameterThrowableCheck(Level level) {
+ switch (level) {
+ case TRACE:
+ logger.trace(marker, message, param1, exception);
+ break;
+ case DEBUG:
+ logger.debug(marker, message, param1, exception);
+ break;
+ case INFO:
+ logger.info(marker, message, param1, exception);
+ break;
+ case WARN:
+ logger.warn(marker, message, param1, exception);
+ break;
+ case ERROR:
+ logger.error(marker, message, param1, exception);
+ break;
+ }
+ verifyMessage(level, marker, oneParam, exception);
+ }
+
+ @Test
+ public void traceMarkerMessageTwoParametersThrowable() {
+ for (Level level : Level.values()) {
+ markerMessageTwoParametersThrowableCheck(level);
+ }
+ }
+
+ private void markerMessageTwoParametersThrowableCheck(Level level) {
+ switch (level) {
+ case TRACE:
+ logger.trace(marker, message, param1, param2, exception);
+ break;
+ case DEBUG:
+ logger.debug(marker, message, param1, param2, exception);
+ break;
+ case INFO:
+ logger.info(marker, message, param1, param2, exception);
+ break;
+ case WARN:
+ logger.warn(marker, message, param1, param2, exception);
+ break;
+ case ERROR:
+ logger.error(marker, message, param1, param2, exception);
+ break;
+ }
+ verifyMessage(level, marker, twoParams, exception);
+ }
+
+ @Test
+ public void traceMarkerMessageThreeParametersThrowable() {
+ for (Level level : Level.values()) {
+ markerMessageThreeParametersThrowableCheck(level);
+ }
+ }
+
+ private void markerMessageThreeParametersThrowableCheck(Level level) {
+ switch (level) {
+ case TRACE:
+ logger.trace(marker, message, param1, param2, param3, exception);
+ break;
+ case DEBUG:
+ logger.debug(marker, message, param1, param2, param3, exception);
+ break;
+ case INFO:
+ logger.info(marker, message, param1, param2, param3, exception);
+ break;
+ case WARN:
+ logger.warn(marker, message, param1, param2, param3, exception);
+ break;
+ case ERROR:
+ logger.error(marker, message, param1, param2, param3, exception);
+ break;
+ }
+ verifyMessage(level, marker, threeParams, exception);
+ }
+
+ private void verifyMessageWithoutMarker(Level level, Object[] arguments, Throwable exception) {
+ verifyMessage(level, null, arguments, exception);
+ }
+
+ private void verifyMessage(Level level, Marker marker, Object[] arguments, Throwable exception) {
+
+ assertEquals("missing event: ", 1, queue.size());
+ SubstituteLoggingEvent event = queue.poll();
+ assertNotNull(event);
+
+ if (marker == null) {
+ assertNull(event.getMarkers());
+ } else {
+ assertEquals(marker, event.getMarkers().get(0));
+ }
+
+ assertEquals(message, event.getMessage());
+
+ if (arguments == null) {
+ assertNull(event.getArgumentArray());
+ } else {
+ assertArrayEquals(arguments, event.getArgumentArray());
+ }
+
+ assertEquals("wrong level: ", level, event.getLevel());
+
+ if (exception == null) {
+ assertNull(event.getThrowable());
+ } else {
+ assertEquals(exception, event.getThrowable());
+ }
+ }
+}
diff --git a/slf4j-api/src/test/java/org/slf4j/helpers/BasicMDCAdapterTest.java b/slf4j-api/src/test/java/org/slf4j/helpers/BasicMDCAdapterTest.java
new file mode 100755
index 00000000..f73a6e06
--- /dev/null
+++ b/slf4j-api/src/test/java/org/slf4j/helpers/BasicMDCAdapterTest.java
@@ -0,0 +1,17 @@
+package org.slf4j.helpers;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+
+public class BasicMDCAdapterTest extends MDCAdapterTestBase {
+
+ @Test
+ public void testClearingMDC() {
+ mdc.put("testKey", "testValue");
+ assertFalse(mdc.getCopyOfContextMap().isEmpty());
+ mdc.clear();
+ assertNull(mdc.getCopyOfContextMap());
+ }
+}
diff --git a/slf4j-api/src/test/java/org/slf4j/helpers/BogoPerf.java b/slf4j-api/src/test/java/org/slf4j/helpers/BogoPerf.java
deleted file mode 100644
index 86f7d67d..00000000
--- a/slf4j-api/src/test/java/org/slf4j/helpers/BogoPerf.java
+++ /dev/null
@@ -1,150 +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.helpers;
-
-import junit.framework.AssertionFailedError;
-
-/**
- * BogoPerf is used to check that the time required to perform a certain
- * operation does not deteriorate over time. BogoPerf adjusts to the CPU speed
- * and capabilities of the host.
- *
- * @author Ceki G&uuml;lc&uuml;
- *
- */
-public class BogoPerf {
-
- private static long NANOS_IN_ONE_SECOND = 1000 * 1000 * 1000;
- private static int INITIAL_N = 1000;
- private static int LAST_N = 100;
- private static int SLACK_FACTOR = 3;
-
- static {
- // let the JIT warm up
- computeBogoIPS(INITIAL_N);
- double bogo_ips = computeBogoIPS(INITIAL_N);
- System.out.println("Host runs at " + bogo_ips + " BIPS");
- }
-
- /**
- * Compute bogoInstructions per second
- * <p>
- * on a 3.2 Ghz Pentium D CPU (around 2007), we obtain about 9'000 bogoIPS.
- *
- * @param N
- * number of bogoInstructions to average over in order to
- * compute the result
- * @return bogo Instructions Per Second
- */
- private static double computeBogoIPS(int N) {
- long begin = System.nanoTime();
-
- for (int i = 0; i < N; i++) {
- bogoInstruction();
- }
- long end = System.nanoTime();
-
- // duration
- double D = end - begin;
- // average duration per instruction
- double avgDPIS = D / N;
- // System.out.println(D + " nanos for " + N + " instructions");
- // System.out.println(avgD + " nanos per instruction");
-
- double bogoIPS = NANOS_IN_ONE_SECOND / avgDPIS;
- // System.out.println(bogoIPS + " bogoIPS");
-
- return bogoIPS;
- }
-
- private static void bogoInstruction() {
- // use our own random number generator, independent of the host JDK
- MyRandom myRandom = new MyRandom(100);
- int len = 150;
- int[] intArray = new int[len];
- for (int i = 0; i < len; i++) {
- intArray[i] = myRandom.nextInt();
- }
- // use our own sort algorithm, independent of the host JDK
- BubbleSort.sort(intArray);
- }
-
- /**
- * Computed the BogoIPS for this host CPU.
- *
- * @return
- */
- public static double currentBIPS() {
- return computeBogoIPS(LAST_N);
- }
-
- static double min(double a, double b) {
- return (a <= b) ? a : b;
- }
-
- /**
- * Assertion used for values that <b>decrease</b> with faster CPUs, typically
- * the time (duration) needed to perform a task.
- *
- * @param currentDuration
- * @param referenceDuration
- * @param referenceBIPS
- * @throws AssertionFailedError
- */
- public static void assertDuration(double currentDuration, long referenceDuration, double referenceBIPS) throws AssertionFailedError {
- double ajustedDuration = adjustExpectedDuration(referenceDuration, referenceBIPS);
- if (currentDuration > ajustedDuration * SLACK_FACTOR) {
- throw new AssertionFailedError("current duration " + currentDuration + " exceeded expected " + ajustedDuration + " (adjusted reference), "
- + referenceDuration + " (raw reference)");
- }
- }
-
- /**
- * Assertion used for values that <b>increase<b> with faster CPUs, typically
- * the number of operations accomplished per unit of time.
- *
- * @param currentPerformance
- * @param referencePerformance
- * @param referenceBIPS
- * @throws AssertionFailedError
- */
- public static void assertPerformance(double currentPerformance, long referencePerformance, double referenceBIPS) throws AssertionFailedError {
- double ajustedPerf = adjustExpectedPerformance(referencePerformance, referenceBIPS);
- if (currentPerformance * SLACK_FACTOR < ajustedPerf) {
- throw new AssertionFailedError(currentPerformance + " below expected " + ajustedPerf + " (adjusted), " + referencePerformance + " (raw)");
- }
- }
-
- private static double adjustExpectedPerformance(long referenceDuration, double referenceBIPS) {
- double currentBIPS = currentBIPS();
- return referenceDuration * (currentBIPS / referenceBIPS);
- }
-
- private static double adjustExpectedDuration(long referenceDuration, double referenceBIPS) {
- double currentBIPS = currentBIPS();
- System.out.println("currentBIPS=" + currentBIPS + " BIPS");
- return referenceDuration * (referenceBIPS / currentBIPS);
- }
-}
diff --git a/slf4j-api/src/test/java/org/slf4j/helpers/BubbleSortTest.java b/slf4j-api/src/test/java/org/slf4j/helpers/BubbleSortTest.java
deleted file mode 100644
index 3592eb02..00000000
--- a/slf4j-api/src/test/java/org/slf4j/helpers/BubbleSortTest.java
+++ /dev/null
@@ -1,100 +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.helpers;
-
-import java.util.Arrays;
-import java.util.Random;
-
-import junit.framework.TestCase;
-
-/**
- * Test that our BubbleSort algorithm is correctly implemented.
- *
- * @author Ceki
- *
- */
-public class BubbleSortTest extends TestCase {
-
- public void testSmoke() {
- int[] a = new int[] { 5, 3, 2, 7 };
- BubbleSort.sort(a);
- int i = 0;
- assertEquals(2, a[i++]);
- assertEquals(3, a[i++]);
- assertEquals(5, a[i++]);
- assertEquals(7, a[i++]);
- }
-
- public void testEmpty() {
- int[] a = new int[] {};
- BubbleSort.sort(a);
- }
-
- public void testSorted() {
- int[] a = new int[] { 3, 30, 300, 3000 };
- BubbleSort.sort(a);
- int i = 0;
- assertEquals(3, a[i++]);
- assertEquals(30, a[i++]);
- assertEquals(300, a[i++]);
- assertEquals(3000, a[i++]);
- }
-
- public void testInverted() {
- int[] a = new int[] { 3000, 300, 30, 3 };
- BubbleSort.sort(a);
- int i = 0;
- assertEquals(3, a[i++]);
- assertEquals(30, a[i++]);
- assertEquals(300, a[i++]);
- assertEquals(3000, a[i++]);
- }
-
- public void testWithSameEntry() {
- int[] a = new int[] { 10, 20, 10, 20 };
- BubbleSort.sort(a);
- int i = 0;
- assertEquals(10, a[i++]);
- assertEquals(10, a[i++]);
- assertEquals(20, a[i++]);
- assertEquals(20, a[i++]);
- }
-
- public void testRandom() {
- int len = 100;
- Random random = new Random(156);
- int[] a = new int[len];
- int[] witness = new int[len];
- for (int i = 0; i < len; i++) {
- int r = random.nextInt();
- a[i] = r;
- witness[i] = r;
- }
- BubbleSort.sort(a);
- Arrays.sort(witness);
- assertTrue(Arrays.equals(witness, a));
- }
-
-}
diff --git a/slf4j-api/src/test/java/org/slf4j/helpers/MDCAdapterTestBase.java b/slf4j-api/src/test/java/org/slf4j/helpers/MDCAdapterTestBase.java
new file mode 100644
index 00000000..cd97b1c3
--- /dev/null
+++ b/slf4j-api/src/test/java/org/slf4j/helpers/MDCAdapterTestBase.java
@@ -0,0 +1,147 @@
+/**
+ * Copyright (c) 2004-2013 QOS.ch, Copyright (C) 2015 Google Inc.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package org.slf4j.helpers;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.util.Map;
+
+import org.junit.After;
+import org.junit.Test;
+import org.slf4j.spi.MDCAdapter;
+
+/**
+ * Tests for {@link BasicMDCAdapter}
+ *
+ * @author Lukasz Cwik
+ */
+public class MDCAdapterTestBase {
+
+ protected MDCAdapter mdc = instantiateMDC();
+
+
+
+ protected MDCAdapter instantiateMDC() {
+ return new BasicMDCAdapter();
+ }
+
+ // leave MDC clean
+ @After
+ public void tearDown() throws Exception {
+ mdc.clear();
+ }
+
+ @Test
+ public void testSettingAndGettingWithMDC() {
+ assertNull(mdc.get("testKey"));
+ mdc.put("testKey", "testValue");
+ assertEquals(mdc.get("testKey"), "testValue");
+ }
+
+ @Test
+ public void testOverwritingAKeyInMDC() {
+ assertNull(mdc.get("testKey"));
+ mdc.put("testKey", "testValue");
+ mdc.put("testKey", "differentTestValue");
+ assertEquals(mdc.get("testKey"), "differentTestValue");
+ }
+
+ @Test
+ public void testGetCopyOfContextMapFromMDC() {
+ mdc.put("testKey", "testValue");
+ Map<String, String> copy = mdc.getCopyOfContextMap();
+ mdc.put("anotherTestKey", "anotherTestValue");
+ assertFalse(copy.size() == mdc.getCopyOfContextMap().size());
+ }
+
+ @Test
+ public void testMDCInheritsValuesFromParentThread() throws Exception {
+ mdc.put("parentKey", "parentValue");
+ runAndWait(() -> {
+ mdc.put("childKey", "childValue");
+ assertEquals("parentValue", mdc.get("parentKey"));
+ });
+ }
+
+ @Test
+ public void testMDCDoesntGetValuesFromChildThread() throws Exception {
+ mdc.put("parentKey", "parentValue");
+ runAndWait(() -> mdc.put("childKey", "childValue"));
+ assertEquals("parentValue", mdc.get("parentKey"));
+ assertNull(mdc.get("childKey"));
+ }
+
+
+ @Test
+ public void testInvokingSetContextMap_WithANullMap_SLF4J_414() {
+ mdc.setContextMap(null);
+ }
+
+ @Test
+ public void testMDCChildThreadCanOverwriteParentThread() throws Exception {
+ mdc.put("sharedKey", "parentValue");
+ runAndWait(() -> {
+ assertEquals("parentValue", mdc.get("sharedKey"));
+ mdc.put("sharedKey", "childValue");
+ assertEquals("childValue", mdc.get("sharedKey"));
+ });
+ assertEquals("parentValue", mdc.get("sharedKey"));
+ }
+
+ private void runAndWait(Runnable runnable) {
+ RecordingExceptionHandler handler = new RecordingExceptionHandler();
+ Thread thread = new Thread(runnable);
+ thread.setUncaughtExceptionHandler(handler);
+ thread.start();
+ try {
+ thread.join();
+ } catch (Throwable t) {
+ fail("Unexpected failure in child thread:" + t.getMessage());
+ }
+ assertFalse(handler.getMessage(), handler.hadException());
+ }
+
+ /** A {@link UncaughtExceptionHandler} that records whether the thread threw an exception. */
+ private static class RecordingExceptionHandler implements UncaughtExceptionHandler {
+ private Throwable exception;
+
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ exception = e;
+ }
+
+ boolean hadException() {
+ return exception != null;
+ }
+
+ String getMessage() {
+ return exception != null ? exception.getMessage() : "";
+ }
+ }
+}
diff --git a/slf4j-api/src/test/java/org/slf4j/helpers/MessageFormatterPerfTest.java b/slf4j-api/src/test/java/org/slf4j/helpers/MessageFormatterPerfTest.java
deleted file mode 100755
index 7b9640bb..00000000
--- a/slf4j-api/src/test/java/org/slf4j/helpers/MessageFormatterPerfTest.java
+++ /dev/null
@@ -1,111 +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.helpers;
-
-import java.text.MessageFormat;
-
-import junit.framework.TestCase;
-import org.junit.Ignore;
-
-@Ignore
-public class MessageFormatterPerfTest extends TestCase {
-
- Integer i1 = new Integer(1);
- Integer i2 = new Integer(2);
- static long RUN_LENGTH = 100 * 1000;
- //
- static long REFERENCE_BIPS = 48416;
-
- public MessageFormatterPerfTest(String name) {
- super(name);
- }
-
- protected void setUp() throws Exception {
- }
-
- protected void tearDown() throws Exception {
- }
-
- public void XtestJDKFormatterPerf() {
- jdkMessageFormatter(RUN_LENGTH);
- double duration = jdkMessageFormatter(RUN_LENGTH);
- System.out.println("jdk duration = " + duration + " nanos");
- }
-
- public void testSLF4JPerf_OneArg() {
- slf4jMessageFormatter_OneArg(RUN_LENGTH);
- double duration = slf4jMessageFormatter_OneArg(RUN_LENGTH);
- System.out.println("duration=" + duration);
- long referencePerf = 36;
- BogoPerf.assertDuration(duration, referencePerf, REFERENCE_BIPS);
- }
-
- public void testSLF4JPerf_TwoArg() {
- slf4jMessageFormatter_TwoArg(RUN_LENGTH);
- double duration = slf4jMessageFormatter_TwoArg(RUN_LENGTH);
- long referencePerf = 60;
- BogoPerf.assertDuration(duration, referencePerf, REFERENCE_BIPS);
- }
-
- public double slf4jMessageFormatter_OneArg(long len) {
- long start = System.nanoTime();
- for (int i = 0; i < len; i++) {
- final FormattingTuple tp = MessageFormatter.format("This is some rather short message {} ", i1);
- tp.getMessage();
- tp.getArgArray();
- tp.getThrowable();
-
- MessageFormatter.format("This is some rather short message {} ", i1);
- }
- long end = System.nanoTime();
- return (end - start) / (1000 * 1000.0);
- }
-
- public double slf4jMessageFormatter_TwoArg(long len) {
- long start = System.nanoTime();
- for (int i = 0; i < len; i++) {
- final FormattingTuple tp = MessageFormatter.format("This is some {} short message {} ", i1, i2);
- tp.getMessage();
- tp.getArgArray();
- tp.getThrowable();
- }
- long end = System.nanoTime();
- return (end - start) / (1000 * 1000.0);
- }
-
- public double jdkMessageFormatter(long len) {
- @SuppressWarnings("unused")
- String s = "";
- s += ""; // keep compiler happy
- long start = System.currentTimeMillis();
- Object[] oa = new Object[] { i1 };
- for (int i = 0; i < len; i++) {
- s = MessageFormat.format("This is some rather short message {0}", oa);
- }
- long end = System.currentTimeMillis();
- return (1.0 * end - start);
- }
-
-}
diff --git a/slf4j-api/src/test/java/org/slf4j/helpers/MessageFormatterTest.java b/slf4j-api/src/test/java/org/slf4j/helpers/MessageFormatterTest.java
index 98ebaa78..4edd59f5 100755
--- a/slf4j-api/src/test/java/org/slf4j/helpers/MessageFormatterTest.java
+++ b/slf4j-api/src/test/java/org/slf4j/helpers/MessageFormatterTest.java
@@ -35,11 +35,11 @@ import static org.junit.Assert.*;
*/
public class MessageFormatterTest {
- Integer i1 = new Integer(1);
- Integer i2 = new Integer(2);
- Integer i3 = new Integer(3);
+ Integer i1 = Integer.valueOf(1);
+ Integer i2 = Integer.valueOf(2);
+ Integer i3 = Integer.valueOf(3);
Integer[] ia0 = new Integer[] { i1, i2, i3 };
- Integer[] ia1 = new Integer[] { new Integer(10), new Integer(20), new Integer(30) };
+ Integer[] ia1 = new Integer[] { Integer.valueOf(10), Integer.valueOf(20), Integer.valueOf(30) };
String result;
@@ -50,6 +50,15 @@ public class MessageFormatterTest {
}
@Test
+ public void testParamaterContainingAnAnchor() {
+ result = MessageFormatter.format("Value is {}.", "[{}]").getMessage();
+ assertEquals("Value is [{}].", result);
+
+ result = MessageFormatter.format("Values are {} and {}.", i1, "[{}]").getMessage();
+ assertEquals("Values are 1 and [{}].", result);
+ }
+
+ @Test
public void nullParametersShouldBeHandledWithoutBarfing() {
result = MessageFormatter.format("Value is {}.", null).getMessage();
assertEquals("Value is null.", result);
@@ -311,14 +320,20 @@ public class MessageFormatterTest {
assertTrue(Arrays.equals(iaWitness, ft.getArgArray()));
assertEquals(t, ft.getThrowable());
- ft = MessageFormatter.arrayFormat("Value {} is smaller than {} and {} -- {} .", ia);
- assertEquals("Value 1 is smaller than 2 and 3 -- " + t.toString() + " .", ft.getMessage());
- assertTrue(Arrays.equals(ia, ft.getArgArray()));
- assertNull(ft.getThrowable());
+ ft = MessageFormatter.arrayFormat("Value {} is smaller than {} and {}.", ia);
+ assertEquals("Value 1 is smaller than 2 and 3.", ft.getMessage());
+ assertTrue(Arrays.equals(iaWitness, ft.getArgArray()));
+ assertEquals(t, ft.getThrowable());
ft = MessageFormatter.arrayFormat("{}{}{}{}", ia);
- assertEquals("123" + t.toString(), ft.getMessage());
- assertTrue(Arrays.equals(ia, ft.getArgArray()));
- assertNull(ft.getThrowable());
+ assertEquals("123{}", ft.getMessage());
+ assertTrue(Arrays.equals(iaWitness, ft.getArgArray()));
+ assertEquals(t, ft.getThrowable());
+
+ ft = MessageFormatter.arrayFormat("1={}", new Object[] { i1 }, t);
+ assertEquals("1=1", ft.getMessage());
+ assertTrue(Arrays.equals(new Object[] { i1 }, ft.getArgArray()));
+ assertEquals(t, ft.getThrowable());
+
}
}
diff --git a/slf4j-api/src/test/java/org/slf4j/helpers/MyRandom.java b/slf4j-api/src/test/java/org/slf4j/helpers/MyRandom.java
deleted file mode 100644
index c817d673..00000000
--- a/slf4j-api/src/test/java/org/slf4j/helpers/MyRandom.java
+++ /dev/null
@@ -1,51 +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.helpers;
-
-class MyRandom {
-
- private final static long m = 200000000041L; // a prime number
- private final static long a = 2000000011L; // a prime number
-
- long y;
- long unused;
- int bits = 32;
-
- public MyRandom() {
- this(System.nanoTime());
- }
-
- public MyRandom(long seed) {
- this.y = seed;
- }
-
- int nextInt() {
- // we don't really care about the randomness of this
- // generator
- y = (a * y + 1) % m;
- unused = y >>> (48 - bits); // just exercise the >>> operator
- return (int) (y);
- }
-}
diff --git a/slf4j-api/src/test/java/org/slf4j/helpers/StringPrintStream.java b/slf4j-api/src/test/java/org/slf4j/helpers/StringPrintStream.java
new file mode 100755
index 00000000..68a76257
--- /dev/null
+++ b/slf4j-api/src/test/java/org/slf4j/helpers/StringPrintStream.java
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2004-2021 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+package org.slf4j.helpers;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Copied from org.slfj.helpers.
+ *
+ * Currently it is not possible to use test-jar from tests running on the module-path.
+ *
+ * @author ceki
+ */
+public class StringPrintStream extends PrintStream {
+
+ public static final String LINE_SEP = System.getProperty("line.separator");
+ PrintStream other;
+ boolean duplicate = false;
+
+ public List<String> 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-api/src/test/java/org/slf4j/helpers/SubstitutableLoggerTest.java b/slf4j-api/src/test/java/org/slf4j/helpers/SubstitutableLoggerTest.java
index 210252f3..f82c4f5d 100644
--- a/slf4j-api/src/test/java/org/slf4j/helpers/SubstitutableLoggerTest.java
+++ b/slf4j-api/src/test/java/org/slf4j/helpers/SubstitutableLoggerTest.java
@@ -24,56 +24,84 @@
*/
package org.slf4j.helpers;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
-import java.util.List;
import java.util.Set;
-import junit.framework.TestCase;
+import org.junit.Test;
import org.slf4j.Logger;
+import org.slf4j.event.EventRecordingLogger;
/**
* @author Chetan Mehrotra
+ * @author Ceki Gülcü
*/
-public class SubstitutableLoggerTest extends TestCase {
- private static final Set<String> EXCLUDED_METHODS = new HashSet<String>(Arrays.asList("getName"));
+public class SubstitutableLoggerTest {
+
+ // NOTE: previous implementations of this class performed a handcrafted conversion of
+ // a method to a string. In this implementation we just invoke method.toString().
+
+ // WARNING: if you need to add an excluded method to have tests pass, ask yourself whether you
+ // forgot to implement the said method with delegation in SubstituteLogger. You probably did.
+ private static final Set<String> EXCLUDED_METHODS = new HashSet<>(
+ Arrays.asList("getName"));
- public void testDelegate() throws Exception {
- SubstituteLogger log = new SubstituteLogger("foo");
- assertTrue(log.delegate() instanceof NOPLogger);
+
+ /**
+ * Test that all SubstituteLogger methods invoke the delegate, except for explicitly excluded methods.
+ */
+ @Test
+ public void delegateIsInvokedTest() throws Exception {
+ SubstituteLogger substituteLogger = new SubstituteLogger("foo", null, false);
+ assertTrue(substituteLogger.delegate() instanceof EventRecordingLogger);
Set<String> expectedMethodSignatures = determineMethodSignatures(Logger.class);
- LoggerInvocationHandler ih = new LoggerInvocationHandler();
- Logger proxyLogger = (Logger) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { Logger.class }, ih);
- log.setDelegate(proxyLogger);
+ LoggerInvocationHandler loggerInvocationHandler = new LoggerInvocationHandler();
+ Logger proxyLogger = (Logger) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { Logger.class }, loggerInvocationHandler);
+ substituteLogger.setDelegate(proxyLogger);
- invokeMethods(log);
+ invokeAllMethodsOf(substituteLogger);
// Assert that all methods are delegated
- expectedMethodSignatures.removeAll(ih.getInvokedMethodSignatures());
+ expectedMethodSignatures.removeAll(loggerInvocationHandler.getInvokedMethodSignatures());
if (!expectedMethodSignatures.isEmpty()) {
fail("Following methods are not delegated " + expectedMethodSignatures.toString());
}
}
- private void invokeMethods(Logger proxyLogger) throws InvocationTargetException, IllegalAccessException {
+ private void invokeAllMethodsOf(Logger logger) throws InvocationTargetException, IllegalAccessException {
for (Method m : Logger.class.getDeclaredMethods()) {
if (!EXCLUDED_METHODS.contains(m.getName())) {
- m.invoke(proxyLogger, new Object[m.getParameterTypes().length]);
+ m.invoke(logger, new Object[m.getParameterTypes().length]);
}
}
}
+ private static Set<String> determineMethodSignatures(Class<Logger> loggerClass) {
+ Set<String> methodSignatures = new HashSet<>();
+ // Note: Class.getDeclaredMethods() does not include inherited methods
+ for (Method m : loggerClass.getDeclaredMethods()) {
+ if (!EXCLUDED_METHODS.contains(m.getName())) {
+ methodSignatures.add(m.toString());
+ }
+ }
+ return methodSignatures;
+ }
+
+
+ // implements InvocationHandler
private class LoggerInvocationHandler implements InvocationHandler {
- private final Set<String> invokedMethodSignatures = new HashSet<String>();
+ private final Set<String> invokedMethodSignatures = new HashSet<>();
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- invokedMethodSignatures.add(getMethodSignature(method));
+ invokedMethodSignatures.add(method.toString());
if (method.getName().startsWith("is")) {
return true;
}
@@ -84,23 +112,4 @@ public class SubstitutableLoggerTest extends TestCase {
return invokedMethodSignatures;
}
}
-
- private static Set<String> determineMethodSignatures(Class<Logger> loggerClass) {
- Set<String> methodSignatures = new HashSet<String>();
- for (Method m : loggerClass.getDeclaredMethods()) {
- if (!EXCLUDED_METHODS.contains(m.getName())) {
- methodSignatures.add(getMethodSignature(m));
- }
- }
- return methodSignatures;
- }
-
- private static String getMethodSignature(Method m) {
- List<String> result = new ArrayList<String>();
- result.add(m.getName());
- for (Class<?> clazz : m.getParameterTypes()) {
- result.add(clazz.getSimpleName());
- }
- return result.toString();
- }
}
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 370fc14b..a836f86b 100755
--- a/slf4j-api/src/test/java/org/slf4j/helpers/SubstituteLoggerFactoryTest.java
+++ b/slf4j-api/src/test/java/org/slf4j/helpers/SubstituteLoggerFactoryTest.java
@@ -24,16 +24,21 @@
*/
package org.slf4j.helpers;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
import org.slf4j.Logger;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
-public class SubstituteLoggerFactoryTest extends TestCase {
- private SubstituteLoggerFactory factory = new SubstituteLoggerFactory();
+public class SubstituteLoggerFactoryTest {
+ private final SubstituteLoggerFactory factory = new SubstituteLoggerFactory();
+ @Test
public void testFactory() {
Logger log = factory.getLogger("foo");
assertNotNull(log);
@@ -42,23 +47,25 @@ public class SubstituteLoggerFactoryTest extends TestCase {
assertTrue("Loggers with same name must be same", log == log2);
}
+ @Test
public void testLoggerNameList() {
factory.getLogger("foo1");
factory.getLogger("foo2");
- Set<String> expectedNames = new HashSet<String>(Arrays.asList("foo1", "foo2"));
- Set<String> actualNames = new HashSet<String>(factory.getLoggerNames());
+ Set<String> expectedNames = new HashSet<>(Arrays.asList("foo1", "foo2"));
+ Set<String> actualNames = new HashSet<>(factory.getLoggerNames());
assertEquals(expectedNames, actualNames);
}
+ @Test
public void testLoggers() {
factory.getLogger("foo1");
factory.getLogger("foo2");
- Set<String> expectedNames = new HashSet<String>(Arrays.asList("foo1", "foo2"));
+ Set<String> expectedNames = new HashSet<>(Arrays.asList("foo1", "foo2"));
- Set<String> actualNames = new HashSet<String>();
+ Set<String> actualNames = new HashSet<>();
for (SubstituteLogger slog : factory.getLoggers()) {
actualNames.add(slog.getName());
}
diff --git a/slf4j-api/src/test/java/org/slf4j/rule/BlaTest.java b/slf4j-api/src/test/java/org/slf4j/rule/BlaTest.java
new file mode 100755
index 00000000..259d063a
--- /dev/null
+++ b/slf4j-api/src/test/java/org/slf4j/rule/BlaTest.java
@@ -0,0 +1,38 @@
+package org.slf4j.rule;
+
+import static org.junit.Assert.fail;
+
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+@Ignore // this test has intentional fails
+public class BlaTest {
+
+ @Rule
+ public RunInNewThreadRule runInThread = new RunInNewThreadRule();
+
+ @Test
+ public void aTest() {
+ System.out.println("running aTest in "+ Thread.currentThread().getName());
+ }
+
+ @RunInNewThread
+ @Test
+ public void bTest() {
+ System.out.println("running bTest in "+ Thread.currentThread().getName());
+ }
+
+ @RunInNewThread(timeout = 2000L)
+ @Test
+ public void cTest() {
+ System.out.println("running cTest in "+ Thread.currentThread().getName());
+ }
+ @RunInNewThread()
+ @Test
+ public void dTest() {
+ System.out.println("running dTest in "+ Thread.currentThread().getName());
+ fail();
+ }
+}
+
diff --git a/slf4j-api/src/test/java/org/slf4j/helpers/BubbleSort.java b/slf4j-api/src/test/java/org/slf4j/rule/RunInNewThread.java
index e8f7bcfc..1bf5944f 100644..100755
--- a/slf4j-api/src/test/java/org/slf4j/helpers/BubbleSort.java
+++ b/slf4j-api/src/test/java/org/slf4j/rule/RunInNewThread.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2004-2011 QOS.ch
+ * Copyright (c) 2021 QOS.ch
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
@@ -22,30 +22,18 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j.helpers;
-/**
- * This class is used internally by BogoPerf, hence the package private
- * (default) access.
- *
- * @author Ceki
- */
-class BubbleSort {
+package org.slf4j.rule;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
- static void sort(int[] a) {
- int len = a.length;
- for (int i = 0; i < len - 1; i++) {
- for (int j = 0; j < len - 1 - i; j++) {
- if (a[j] > a[j + 1]) {
- swap(a, j, j + 1);
- }
- }
- }
- }
- static void swap(int[] a, int i, int j) {
- int t = a[i];
- a[i] = a[j];
- a[j] = t;
- }
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface RunInNewThread {
+ static final long DEFAULT_TIMEOUT = 1000L;
+ public long timeout() default DEFAULT_TIMEOUT;
}
diff --git a/slf4j-ext/src/main/java/org/slf4j/ext/MDCStrLookup.java b/slf4j-api/src/test/java/org/slf4j/rule/RunInNewThreadRule.java
index 5d1e63cf..3945144f 100644..100755
--- a/slf4j-ext/src/main/java/org/slf4j/ext/MDCStrLookup.java
+++ b/slf4j-api/src/test/java/org/slf4j/rule/RunInNewThreadRule.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2004-2011 QOS.ch
+ * Copyright (c) 2021 QOS.ch
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
@@ -22,28 +22,33 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j.ext;
-import org.apache.commons.lang.text.StrLookup;
-import org.slf4j.MDC;
+package org.slf4j.rule;
-/**
- * This class can be used with the Commons Lang StrSubstitutor to replace
- * tokens that occur in Strings with their values in the MDC.
- *
- * @author Ralph Goers
- */
-public class MDCStrLookup extends StrLookup {
- /**
- * Looks up up a value in the MDC.
- *
- * @param key the key to be looked up, may be null
- * @return the matching value, null if no match
- */
- public String lookup(String key) {
- if (key == null) {
- return null;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+// This class has been inspired by the article "A JUnit Rule to Run a Test in Its Own Thread"
+// published by Frank Appel, author of the book "Testing with JUnit" published by Packt publishing.
+//
+// See also
+// https://www.codeaffine.com/2014/07/21/a-junit-rule-to-run-a-test-in-its-own-thread/
+
+public class RunInNewThreadRule implements TestRule {
+
+ @Override
+ public Statement apply(Statement base, Description description) {
+ RunInNewThread desiredAnnotaton = description.getAnnotation(RunInNewThread.class);
+
+ if (desiredAnnotaton == null) {
+ System.out.println("test "+ description.getMethodName() +" not annotated");
+ return base;
+ } else {
+ long timeout = desiredAnnotaton.timeout();
+ System.out.println("running "+ description.getMethodName() +" in separate tjread");
+ return new RunInNewThreadStatement(base, timeout);
}
- return MDC.get(key);
}
+
}
diff --git a/slf4j-api/src/test/java/org/slf4j/rule/RunInNewThreadStatement.java b/slf4j-api/src/test/java/org/slf4j/rule/RunInNewThreadStatement.java
new file mode 100755
index 00000000..2b8869e5
--- /dev/null
+++ b/slf4j-api/src/test/java/org/slf4j/rule/RunInNewThreadStatement.java
@@ -0,0 +1,68 @@
+/**
+ * Copyright (c) 2021 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.rule;
+
+import org.junit.runners.model.Statement;
+
+//This class has been inspired by the article "A JUnit Rule to Run a Test in Its Own Thread"
+//published by Frank Appel, author of the book "Testing with JUnit" published by Packt publishing.
+//
+//See also
+//https://www.codeaffine.com/2014/07/21/a-junit-rule-to-run-a-test-in-its-own-thread/
+
+public class RunInNewThreadStatement extends Statement implements Runnable {
+
+ final Statement base;
+ final long timeout;
+ Throwable throwable;
+
+ RunInNewThreadStatement(Statement base, long timeout) {
+ this.base = base;
+ this.timeout = timeout;
+ }
+
+ @Override
+ public void evaluate() throws Throwable {
+ Thread thread = new Thread(this);
+ thread.start();
+ System.out.println("Timeout is "+timeout);
+ thread.join(timeout);
+
+ if (throwable != null) {
+ throw throwable;
+ }
+ }
+
+ @Override
+ public void run() {
+ try {
+ base.evaluate();
+ } catch (Throwable e) {
+ this.throwable = e;
+ }
+ }
+
+
+}
diff --git a/slf4j-api/src/test/java/org/slf4j/testHarness/MultithreadedInitializationTest.java b/slf4j-api/src/test/java/org/slf4j/testHarness/MultithreadedInitializationTest.java
new file mode 100644
index 00000000..c534bad1
--- /dev/null
+++ b/slf4j-api/src/test/java/org/slf4j/testHarness/MultithreadedInitializationTest.java
@@ -0,0 +1,79 @@
+package org.slf4j.testHarness;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerAccessingThread;
+import org.slf4j.LoggerFactory;
+import org.slf4j.event.EventRecordingLogger;
+import org.slf4j.helpers.SubstituteLogger;
+
+abstract public class MultithreadedInitializationTest {
+ final protected static int THREAD_COUNT = 4 + Runtime.getRuntime().availableProcessors() * 2;
+
+ private final List<Logger> createdLoggers = Collections.synchronizedList(new ArrayList<>());
+
+ final protected AtomicLong eventCount = new AtomicLong(0);
+ final private CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1);
+
+ @Test
+ public void multiThreadedInitialization() throws InterruptedException, BrokenBarrierException {
+ @SuppressWarnings("unused")
+ LoggerAccessingThread[] accessors = harness();
+
+ Logger logger = LoggerFactory.getLogger(getClass().getName());
+ logger.info("hello");
+ eventCount.getAndIncrement();
+
+ assertAllSubstLoggersAreFixed();
+ long recordedEventCount = getRecordedEventCount();
+ int LENIENCY_COUNT = 30;
+
+ long expectedEventCount = eventCount.get() + extraLogEvents();
+
+ assertTrue(expectedEventCount + " >= " + recordedEventCount, expectedEventCount >= recordedEventCount);
+ assertTrue(expectedEventCount + " < " + recordedEventCount + "+" + LENIENCY_COUNT, expectedEventCount < recordedEventCount + LENIENCY_COUNT);
+ }
+
+ abstract protected long getRecordedEventCount();
+
+ protected int extraLogEvents() {
+ return 0;
+ }
+
+ private void assertAllSubstLoggersAreFixed() {
+ for (Logger logger : createdLoggers) {
+ if (logger instanceof SubstituteLogger) {
+ SubstituteLogger substLogger = (SubstituteLogger) logger;
+ if (substLogger.delegate() instanceof EventRecordingLogger)
+ fail("substLogger " + substLogger.getName() + " has a delegate of type EventRecodingLogger");
+ }
+ }
+ }
+
+ 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, createdLoggers, 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-site/LICENSE.txt b/slf4j-ext/LICENSE.txt
index 508a2728..1a3d0532 100644
--- a/slf4j-site/LICENSE.txt
+++ b/slf4j-ext/LICENSE.txt
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2007 QOS.ch
+Copyright (c) 2004-2022 QOS.ch Sarl (Switzerland)
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/slf4j-ext/pom.xml b/slf4j-ext/pom.xml
index f2cec047..dd07244d 100755
--- a/slf4j-ext/pom.xml
+++ b/slf4j-ext/pom.xml
@@ -1,5 +1,5 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
@@ -7,7 +7,8 @@
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
- <version>1.7.13-SNAPSHOT</version>
+ <version>2.0.12</version>
+ <relativePath>../parent/pom.xml</relativePath>
</parent>
<artifactId>slf4j-ext</artifactId>
@@ -25,13 +26,14 @@
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
+ <artifactId>slf4j-reload4j</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.cal10n</groupId>
<artifactId>cal10n-api</artifactId>
+ <optional>true</optional>
</dependency>
<dependency>
<groupId>javassist</groupId>
@@ -39,30 +41,15 @@
<version>3.4.GA</version>
<optional>true</optional>
</dependency>
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.4</version>
- <optional>true</optional>
- </dependency>
</dependencies>
<build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <source>${required.jdk.version}</source>
- <target>${required.jdk.version}</target>
- </configuration>
- </plugin>
-
+ <plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
- <!-- http://maven.apache.org/plugins/maven-surefire-plugin/test-mojo.html -->
+ <!-- http://maven.apache.org/plugins/maven-surefire-plugin/test-mojo.html -->
<printSummary>false</printSummary>
<forkMode>once</forkMode>
<reportFormat>plain</reportFormat>
@@ -74,32 +61,32 @@
</configuration>
</plugin>
-
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
- <Bundle-Version>${parsedVersion.osgiVersion}</Bundle-Version>
- <Bundle-Description>${project.description}</Bundle-Description>
- <Implementation-Version>${project.version}</Implementation-Version>
<Premain-Class>org.slf4j.agent.AgentPremain</Premain-Class>
<!-- what is the proper way to specify the maven full name? /ravn -->
<Boot-Class-Path>../../../../javassist/javassist/3.4.GA/javassist-3.4.GA.jar javassist-3.4.GA.jar javassist.jar</Boot-Class-Path>
</manifestEntries>
- <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
- </configuration>
- </plugin>
- </plugins>
+ </configuration>
+ </plugin>
- </build>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Import-Package>ch.qos.cal10n;version="${cal10n.version}";resolution:="optional", org.slf4j, org.slf4j.*</Import-Package>
+ <_exportcontents>org.slf4j.ext, org.slf4j.profiler, org.slf4j.cal10n</_exportcontents>
+ </instructions>
+ </configuration>
+ </plugin>
- <reporting>
- <plugins>
-
</plugins>
- </reporting>
+ </build>
-</project> \ No newline at end of file
+</project>
diff --git a/slf4j-ext/src/main/java/org/slf4j/NDC.java b/slf4j-ext/src/main/java/org/slf4j/NDC.java
index fbad2741..623e96d3 100644
--- a/slf4j-ext/src/main/java/org/slf4j/NDC.java
+++ b/slf4j-ext/src/main/java/org/slf4j/NDC.java
@@ -24,8 +24,6 @@
*/
package org.slf4j;
-import org.slf4j.MDC;
-
public class NDC {
public final static String PREFIX = "NDC";
diff --git a/slf4j-ext/src/main/java/org/slf4j/agent/AgentOptions.java b/slf4j-ext/src/main/java/org/slf4j/agent/AgentOptions.java
index 181dfba5..600e5f40 100644
--- a/slf4j-ext/src/main/java/org/slf4j/agent/AgentOptions.java
+++ b/slf4j-ext/src/main/java/org/slf4j/agent/AgentOptions.java
@@ -28,12 +28,12 @@ package org.slf4j.agent;
* <p>
* All recognized options in the string passed to the java agent. For
* "java -javaagent:foo.jar=OPTIONS HelloWorld" this would be "OPTIONS".
- * </p>
+ *
* <p>
* It is considered to be a list of options separated by (currently) ";", on the
* form "option=value". The interpretation of "value" is specific to each
* option.
- * </p>
+ *
*/
public class AgentOptions {
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 bca08135..7db5cb7d 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 @@ import org.slf4j.instrumentation.LogTransformer;
/**
* 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.
- *
+ * <a href="http://java.sun.com/javase/6/docs/api/java/lang/instrument/package-summary.html">http://java.sun.com/javase/6/docs/api/java/lang/instrument/package-summary.html</a> for details.
+ *
* @param agentArgument
* string provided after "=" up to first space
* @param instrumentation
@@ -85,8 +83,8 @@ public class AgentPremain {
* 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,20 +107,17 @@ public class AgentPremain {
* 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();
System.err.println("Start at " + new Date());
- Thread hook = new Thread() {
- @Override
- public void run() {
- long timePassed = System.currentTimeMillis() - start;
- System.err.println("Stop at " + new Date() + ", execution time = " + timePassed + " ms");
- }
- };
+ Thread hook = new Thread(() -> {
+ long timePassed = System.currentTimeMillis() - start;
+ System.err.println("Stop at " + new Date() + ", execution time = " + timePassed + " ms");
+ });
Runtime.getRuntime().addShutdownHook(hook);
}
-} \ No newline at end of file
+}
diff --git a/slf4j-ext/src/main/java/org/slf4j/agent/package.html b/slf4j-ext/src/main/java/org/slf4j/agent/package.html
index 61726464..7385f651 100644
--- a/slf4j-ext/src/main/java/org/slf4j/agent/package.html
+++ b/slf4j-ext/src/main/java/org/slf4j/agent/package.html
@@ -24,10 +24,7 @@ E.g.
is changed to
<pre><code>java -javaagent:/path/to/slf4j-ext-X.Y.Z.jar=<em>OPTIONS</em> HelloWorld</code></pre>
-What is actually done, depends on the <em>OPTIONS</em> passed to the agent. These are listed in AgentOptions.java.
-</p>
-
-
+<p>What is actually done, depends on the <em>OPTIONS</em> passed to the agent. These are listed in AgentOptions.java.
</body>
</html>
diff --git a/slf4j-ext/src/main/java/org/slf4j/cal10n/LocLogger.java b/slf4j-ext/src/main/java/org/slf4j/cal10n/LocLogger.java
index d4ee8fe5..3e77b467 100644
--- a/slf4j-ext/src/main/java/org/slf4j/cal10n/LocLogger.java
+++ b/slf4j-ext/src/main/java/org/slf4j/cal10n/LocLogger.java
@@ -35,7 +35,7 @@ import ch.qos.cal10n.MessageParameterObj;
/**
* A logger specialized in localized logging. Localization is based in the <a
- * href="http://cal10n.qos.ch">CAL10N project</p>.
+ * href="http://cal10n.qos.ch">CAL10N project</a>.
*
* @author Ceki G&uuml;lc&uuml;
*/
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 2e54beec..f3c52090 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 org.slf4j.LoggerFactory;
import ch.qos.cal10n.IMessageConveyor;
/**
- *
+ *
* This class is essentially a wrapper around an {@link LoggerFactory} producing
* {@link LocLogger} instances.
- *
+ *
* <p>
* 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&uuml;c&uuml;
- *
+ *
+ * @author Ceki G&uuml;lc&uuml;
+ *
*/
public class LocLoggerFactory {
@@ -54,8 +54,8 @@ public class LocLoggerFactory {
/**
* Get an LocLogger instance by name.
- *
- * @param name
+ *
+ * @param name name of the logger to retrieve
* @return LocLogger instance by name.
*/
public LocLogger getLocLogger(String name) {
@@ -65,8 +65,8 @@ public class LocLoggerFactory {
/**
* Get a new LocLogger instance by class. The returned LocLogger will be named
* after the class.
- *
- * @param clazz
+ *
+ * @param clazz a class
* @return LocLogger instance by class
*/
public LocLogger getLocLogger(Class<?> clazz) {
diff --git a/slf4j-ext/src/main/java/org/slf4j/ext/EventData.java b/slf4j-ext/src/main/java/org/slf4j/ext/EventData.java
deleted file mode 100755
index cd661b83..00000000
--- a/slf4j-ext/src/main/java/org/slf4j/ext/EventData.java
+++ /dev/null
@@ -1,305 +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.ext;
-
-import java.io.Serializable;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.beans.XMLDecoder;
-import java.beans.XMLEncoder;
-import java.beans.ExceptionListener;
-
-/**
- * Base class for Event Data. Event Data contains data to be logged about an
- * event. Users may extend this class for each EventType they want to log.
- *
- * @author Ralph Goers
- */
-public class EventData implements Serializable {
-
- private static final long serialVersionUID = 153270778642103985L;
-
- private Map<String, Object> eventData = new HashMap<String, Object>();
- public static final String EVENT_MESSAGE = "EventMessage";
- public static final String EVENT_TYPE = "EventType";
- public static final String EVENT_DATETIME = "EventDateTime";
- public static final String EVENT_ID = "EventId";
-
- /**
- * Default Constructor
- */
- public EventData() {
- }
-
- /**
- * Constructor to create event data from a Map.
- *
- * @param map
- * The event data.
- */
- public EventData(Map<String, Object> map) {
- eventData.putAll(map);
- }
-
- /**
- * Construct from a serialized form of the Map containing the RequestInfo
- * elements
- *
- * @param xml
- * The serialized form of the RequestInfo Map.
- */
- @SuppressWarnings("unchecked")
- public EventData(String xml) {
- ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes());
- try {
- XMLDecoder decoder = new XMLDecoder(bais);
- this.eventData = (Map<String, Object>) decoder.readObject();
- } catch (Exception e) {
- throw new EventException("Error decoding " + xml, e);
- }
- }
-
- /**
- * Serialize all the EventData items into an XML representation.
- *
- * @return an XML String containing all the EventDAta items.
- */
- public String toXML() {
- return toXML(eventData);
- }
-
- /**
- * Serialize all the EventData items into an XML representation.
- *
- * @param map the Map to transform
- * @return an XML String containing all the EventDAta items.
- */
- public static String toXML(Map<String, Object> map) {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- try {
- XMLEncoder encoder = new XMLEncoder(baos);
- encoder.setExceptionListener(new ExceptionListener() {
- public void exceptionThrown(Exception exception) {
- exception.printStackTrace();
- }
- });
- encoder.writeObject(map);
- encoder.close();
- return baos.toString();
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
-
- /**
- * Retrieve the event identifier.
- *
- * @return The event identifier
- */
- public String getEventId() {
- return (String) this.eventData.get(EVENT_ID);
- }
-
- /**
- * Set the event identifier.
- *
- * @param eventId
- * The event identifier.
- */
- public void setEventId(String eventId) {
- if (eventId == null) {
- throw new IllegalArgumentException("eventId cannot be null");
- }
- this.eventData.put(EVENT_ID, eventId);
- }
-
- /**
- * Retrieve the message text associated with this event, if any.
- *
- * @return The message text associated with this event or null if there is
- * none.
- */
- public String getMessage() {
- return (String) this.eventData.get(EVENT_MESSAGE);
- }
-
- /**
- * Set the message text associated with this event.
- *
- * @param message
- * The message text.
- */
- public void setMessage(String message) {
- this.eventData.put(EVENT_MESSAGE, message);
- }
-
- /**
- * Retrieve the date and time the event occurred.
- *
- * @return The Date associated with the event.
- */
- public Date getEventDateTime() {
- return (Date) this.eventData.get(EVENT_DATETIME);
- }
-
- /**
- * Set the date and time the event occurred in case it is not the same as when
- * the event was logged.
- *
- * @param eventDateTime
- * The event Date.
- */
- public void setEventDateTime(Date eventDateTime) {
- this.eventData.put(EVENT_DATETIME, eventDateTime);
- }
-
- /**
- * Set the type of event that occurred.
- *
- * @param eventType
- * The type of the event.
- */
- public void setEventType(String eventType) {
- this.eventData.put(EVENT_TYPE, eventType);
- }
-
- /**
- * Retrieve the type of the event.
- *
- * @return The event type.
- */
- public String getEventType() {
- return (String) this.eventData.get(EVENT_TYPE);
- }
-
- /**
- * Add arbitrary attributes about the event.
- *
- * @param name
- * The attribute's key.
- * @param obj
- * The data associated with the key.
- */
- public void put(String name, Serializable obj) {
- this.eventData.put(name, obj);
- }
-
- /**
- * Retrieve an event attribute.
- *
- * @param name
- * The attribute's key.
- * @return The value associated with the key or null if the key is not
- * present.
- */
- public Serializable get(String name) {
- return (Serializable) this.eventData.get(name);
- }
-
- /**
- * Populate the event data from a Map.
- *
- * @param data
- * The Map to copy.
- */
- public void putAll(Map<String, Object> data) {
- this.eventData.putAll(data);
- }
-
- /**
- * Returns the number of attributes in the EventData.
- *
- * @return the number of attributes in the EventData.
- */
- public int getSize() {
- return this.eventData.size();
- }
-
- /**
- * Returns an Iterator over all the entries in the EventDAta.
- *
- * @return an Iterator that can be used to access all the event attributes.
- */
- public Iterator<Map.Entry<String, Object>> getEntrySetIterator() {
- return this.eventData.entrySet().iterator();
- }
-
- /**
- * Retrieve all the attributes in the EventData as a Map. Changes to this map
- * will be reflected in the EventData.
- *
- * @return The Map of attributes in this EventData instance.
- */
- public Map<String, Object> getEventMap() {
- return this.eventData;
- }
-
- /**
- * Convert the EventData to a String.
- *
- * @return The EventData as a String.
- */
- @Override
- public String toString() {
- return toXML();
- }
-
- /**
- * Compare two EventData objects for equality.
- *
- * @param o
- * The Object to compare.
- * @return true if the objects are the same instance or contain all the same
- * keys and their values.
- */
- @SuppressWarnings("unchecked")
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (!(o instanceof EventData || o instanceof Map)) {
- return false;
- }
- Map<String, Object> map = (o instanceof EventData) ? ((EventData) o).getEventMap() : (Map<String, Object>) o;
-
- return this.eventData.equals(map);
- }
-
- /**
- * Compute the hashCode for this EventData instance.
- *
- * @return The hashcode for this EventData instance.
- */
- @Override
- public int hashCode() {
- return this.eventData.hashCode();
- }
-} \ No newline at end of file
diff --git a/slf4j-ext/src/main/java/org/slf4j/ext/EventException.java b/slf4j-ext/src/main/java/org/slf4j/ext/EventException.java
deleted file mode 100644
index ab220768..00000000
--- a/slf4j-ext/src/main/java/org/slf4j/ext/EventException.java
+++ /dev/null
@@ -1,66 +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.ext;
-
-/**
- * Exception used to identify issues related to an event that is being logged.
- */
-public class EventException extends RuntimeException {
-
- private static final long serialVersionUID = -22873966112391992L;
-
- /**
- * Default constructor.
- */
- public EventException() {
- super();
- }
-
- /**
- * Constructor that allows an exception message.
- * @param exceptionMessage The exception message.
- */
- public EventException(String exceptionMessage) {
- super(exceptionMessage);
- }
-
- /**
- * Constructor that chains another Exception or Error.
- * @param originalException The original exception.
- */
- public EventException(Throwable originalException) {
- super(originalException);
- }
-
- /**
- * Constructor that chains another Exception or Error and also allows a message
- * to be specified.
- * @param exceptionMessage The exception message.
- * @param originalException The original excepton.
- */
- public EventException(String exceptionMessage, Throwable originalException) {
- super(exceptionMessage, originalException);
- }
-}
diff --git a/slf4j-ext/src/main/java/org/slf4j/ext/LoggerWrapper.java b/slf4j-ext/src/main/java/org/slf4j/ext/LoggerWrapper.java
index 392ddaf5..0c890fc9 100644
--- a/slf4j-ext/src/main/java/org/slf4j/ext/LoggerWrapper.java
+++ b/slf4j-ext/src/main/java/org/slf4j/ext/LoggerWrapper.java
@@ -26,8 +26,8 @@ package org.slf4j.ext;
import org.slf4j.Logger;
import org.slf4j.Marker;
-import org.slf4j.helpers.FormattingTuple;
-import org.slf4j.helpers.MessageFormatter;
+//import org.slf4j.helpers.FormattingTuple;
+//import org.slf4j.helpers.MessageFormatter;
import org.slf4j.spi.LocationAwareLogger;
/**
@@ -40,8 +40,7 @@ import org.slf4j.spi.LocationAwareLogger;
public class LoggerWrapper implements Logger {
// To ensure consistency between two instances sharing the same name
- // (homonyms)
- // a LoggerWrapper should not contain any state beyond
+ // (homonyms) a LoggerWrapper should not contain any state beyond
// the Logger instance it wraps.
// Note that 'instanceofLAL' directly depends on Logger.
// fqcn depend on the caller, but its value would not be different
@@ -98,8 +97,7 @@ public class LoggerWrapper implements Logger {
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.format(format, arg).getMessage();
- ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.TRACE_INT, formattedMessage, new Object[] { arg }, null);
+ ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.TRACE_INT, format, new Object[] { arg }, null);
} else {
logger.trace(format, arg);
}
@@ -113,8 +111,7 @@ public class LoggerWrapper implements Logger {
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.format(format, arg1, arg2).getMessage();
- ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.TRACE_INT, formattedMessage, new Object[] { arg1, arg2 }, null);
+ ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.TRACE_INT, format, new Object[] { arg1, arg2 }, null);
} else {
logger.trace(format, arg1, arg2);
}
@@ -128,8 +125,7 @@ public class LoggerWrapper implements Logger {
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.arrayFormat(format, args).getMessage();
- ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.TRACE_INT, formattedMessage, args, null);
+ ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.TRACE_INT, format, args, null);
} else {
logger.trace(format, args);
}
@@ -169,8 +165,7 @@ public class LoggerWrapper implements Logger {
if (!logger.isTraceEnabled(marker))
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.format(format, arg).getMessage();
- ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.TRACE_INT, formattedMessage, new Object[] { arg }, null);
+ ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.TRACE_INT, format, new Object[] { arg }, null);
} else {
logger.trace(marker, format, arg);
}
@@ -183,8 +178,7 @@ public class LoggerWrapper implements Logger {
if (!logger.isTraceEnabled(marker))
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.format(format, arg1, arg2).getMessage();
- ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.TRACE_INT, formattedMessage, new Object[] { arg1, arg2 }, null);
+ ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.TRACE_INT, format, new Object[] { arg1, arg2 }, null);
} else {
logger.trace(marker, format, arg1, arg2);
}
@@ -197,8 +191,7 @@ public class LoggerWrapper implements Logger {
if (!logger.isTraceEnabled(marker))
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.arrayFormat(format, args).getMessage();
- ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.TRACE_INT, formattedMessage, args, null);
+ ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.TRACE_INT, format, args, null);
} else {
logger.trace(marker, format, args);
}
@@ -253,8 +246,7 @@ public class LoggerWrapper implements Logger {
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.format(format, arg).getMessage();
- ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.DEBUG_INT, formattedMessage, new Object[] { arg }, null);
+ ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.DEBUG_INT, format, new Object[] { arg }, null);
} else {
logger.debug(format, arg);
}
@@ -268,8 +260,7 @@ public class LoggerWrapper implements Logger {
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.format(format, arg1, arg2).getMessage();
- ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.DEBUG_INT, formattedMessage, new Object[] { arg1, arg2 }, null);
+ ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.DEBUG_INT, format, new Object[] { arg1, arg2 }, null);
} else {
logger.debug(format, arg1, arg2);
}
@@ -283,8 +274,7 @@ public class LoggerWrapper implements Logger {
return;
if (instanceofLAL) {
- FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
- ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.DEBUG_INT, ft.getMessage(), ft.getArgArray(), ft.getThrowable());
+ ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.DEBUG_INT, format, argArray, null);
} else {
logger.debug(format, argArray);
}
@@ -324,8 +314,7 @@ public class LoggerWrapper implements Logger {
if (!logger.isDebugEnabled(marker))
return;
if (instanceofLAL) {
- FormattingTuple ft = MessageFormatter.format(format, arg);
- ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.DEBUG_INT, ft.getMessage(), ft.getArgArray(), ft.getThrowable());
+ ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.DEBUG_INT, format, new Object[] { arg }, null);
} else {
logger.debug(marker, format, arg);
}
@@ -338,8 +327,7 @@ public class LoggerWrapper implements Logger {
if (!logger.isDebugEnabled(marker))
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.format(format, arg1, arg2).getMessage();
- ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.DEBUG_INT, formattedMessage, new Object[] { arg1, arg2 }, null);
+ ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.DEBUG_INT, format, new Object[] { arg1, arg2 }, null);
} else {
logger.debug(marker, format, arg1, arg2);
}
@@ -353,8 +341,7 @@ public class LoggerWrapper implements Logger {
return;
if (instanceofLAL) {
- FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
- ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.DEBUG_INT, ft.getMessage(), argArray, ft.getThrowable());
+ ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.DEBUG_INT, format, argArray, null);
} else {
logger.debug(marker, format, argArray);
}
@@ -409,8 +396,7 @@ public class LoggerWrapper implements Logger {
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.format(format, arg).getMessage();
- ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.INFO_INT, formattedMessage, new Object[] { arg }, null);
+ ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.INFO_INT, format, new Object[] { arg }, null);
} else {
logger.info(format, arg);
}
@@ -424,8 +410,7 @@ public class LoggerWrapper implements Logger {
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.format(format, arg1, arg2).getMessage();
- ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.INFO_INT, formattedMessage, new Object[] { arg1, arg2 }, null);
+ ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.INFO_INT, format, new Object[] { arg1, arg2 }, null);
} else {
logger.info(format, arg1, arg2);
}
@@ -439,8 +424,7 @@ public class LoggerWrapper implements Logger {
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.arrayFormat(format, args).getMessage();
- ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.INFO_INT, formattedMessage, args, null);
+ ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.INFO_INT, format, args, null);
} else {
logger.info(format, args);
}
@@ -480,8 +464,7 @@ public class LoggerWrapper implements Logger {
if (!logger.isInfoEnabled(marker))
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.format(format, arg).getMessage();
- ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.INFO_INT, formattedMessage, new Object[] { arg }, null);
+ ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.INFO_INT, format, new Object[] { arg }, null);
} else {
logger.info(marker, format, arg);
}
@@ -494,8 +477,7 @@ public class LoggerWrapper implements Logger {
if (!logger.isInfoEnabled(marker))
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.format(format, arg1, arg2).getMessage();
- ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.INFO_INT, formattedMessage, new Object[] { arg1, arg2 }, null);
+ ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.INFO_INT, format, new Object[] { arg1, arg2 }, null);
} else {
logger.info(marker, format, arg1, arg2);
}
@@ -508,8 +490,7 @@ public class LoggerWrapper implements Logger {
if (!logger.isInfoEnabled(marker))
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.arrayFormat(format, args).getMessage();
- ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.INFO_INT, formattedMessage, args, null);
+ ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.INFO_INT, format, args, null);
} else {
logger.info(marker, format, args);
}
@@ -561,8 +542,7 @@ public class LoggerWrapper implements Logger {
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.format(format, arg).getMessage();
- ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.WARN_INT, formattedMessage, new Object[] { arg }, null);
+ ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.WARN_INT, format, new Object[] { arg }, null);
} else {
logger.warn(format, arg);
}
@@ -576,8 +556,7 @@ public class LoggerWrapper implements Logger {
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.format(format, arg1, arg2).getMessage();
- ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.WARN_INT, formattedMessage, new Object[] { arg1, arg2 }, null);
+ ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.WARN_INT, format, new Object[] { arg1, arg2 }, null);
} else {
logger.warn(format, arg1, arg2);
}
@@ -591,8 +570,7 @@ public class LoggerWrapper implements Logger {
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.arrayFormat(format, args).getMessage();
- ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.WARN_INT, formattedMessage, args, null);
+ ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.WARN_INT, format, args, null);
} else {
logger.warn(format, args);
}
@@ -632,8 +610,7 @@ public class LoggerWrapper implements Logger {
if (!logger.isWarnEnabled(marker))
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.format(format, arg).getMessage();
- ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.WARN_INT, formattedMessage, new Object[] { arg }, null);
+ ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.WARN_INT, format, new Object[] { arg }, null);
} else {
logger.warn(marker, format, arg);
}
@@ -646,8 +623,7 @@ public class LoggerWrapper implements Logger {
if (!logger.isWarnEnabled(marker))
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.format(format, arg1, arg2).getMessage();
- ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.WARN_INT, formattedMessage, new Object[] { arg1, arg2 }, null);
+ ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.WARN_INT, format, new Object[] { arg1, arg2 }, null);
} else {
logger.warn(marker, format, arg1, arg2);
}
@@ -660,8 +636,7 @@ public class LoggerWrapper implements Logger {
if (!logger.isWarnEnabled(marker))
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.arrayFormat(format, args).getMessage();
- ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.WARN_INT, formattedMessage, args, null);
+ ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.WARN_INT, format, args, null);
} else {
logger.warn(marker, format, args);
}
@@ -716,8 +691,7 @@ public class LoggerWrapper implements Logger {
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.format(format, arg).getMessage();
- ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.ERROR_INT, formattedMessage, new Object[] { arg }, null);
+ ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.ERROR_INT, format, new Object[] { arg }, null);
} else {
logger.error(format, arg);
}
@@ -731,8 +705,7 @@ public class LoggerWrapper implements Logger {
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.format(format, arg1, arg2).getMessage();
- ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.ERROR_INT, formattedMessage, new Object[] { arg1, arg2 }, null);
+ ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.ERROR_INT, format, new Object[] { arg1, arg2 }, null);
} else {
logger.error(format, arg1, arg2);
}
@@ -746,8 +719,7 @@ public class LoggerWrapper implements Logger {
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.arrayFormat(format, args).getMessage();
- ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.ERROR_INT, formattedMessage, args, null);
+ ((LocationAwareLogger) logger).log(null, fqcn, LocationAwareLogger.ERROR_INT, format, args, null);
} else {
logger.error(format, args);
}
@@ -787,8 +759,7 @@ public class LoggerWrapper implements Logger {
if (!logger.isErrorEnabled(marker))
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.format(format, arg).getMessage();
- ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.ERROR_INT, formattedMessage, new Object[] { arg }, null);
+ ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.ERROR_INT, format, new Object[] { arg }, null);
} else {
logger.error(marker, format, arg);
}
@@ -801,8 +772,7 @@ public class LoggerWrapper implements Logger {
if (!logger.isErrorEnabled(marker))
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.format(format, arg1, arg2).getMessage();
- ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.ERROR_INT, formattedMessage, new Object[] { arg1, arg2 }, null);
+ ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.ERROR_INT, format, new Object[] { arg1, arg2 }, null);
} else {
logger.error(marker, format, arg1, arg2);
}
@@ -815,8 +785,7 @@ public class LoggerWrapper implements Logger {
if (!logger.isErrorEnabled(marker))
return;
if (instanceofLAL) {
- String formattedMessage = MessageFormatter.arrayFormat(format, args).getMessage();
- ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.ERROR_INT, formattedMessage, args, null);
+ ((LocationAwareLogger) logger).log(marker, fqcn, LocationAwareLogger.ERROR_INT, format, args, null);
} else {
logger.error(marker, format, args);
}
diff --git a/slf4j-ext/src/main/java/org/slf4j/ext/XLogger.java b/slf4j-ext/src/main/java/org/slf4j/ext/XLogger.java
index 06f01626..fc7543b6 100644
--- a/slf4j-ext/src/main/java/org/slf4j/ext/XLogger.java
+++ b/slf4j-ext/src/main/java/org/slf4j/ext/XLogger.java
@@ -96,21 +96,19 @@ public class XLogger extends LoggerWrapper implements Logger {
/**
* Given an underlying logger, construct an XLogger
*
- * @param logger
- * underlying logger
+ * @param logger underlying logger
*/
public XLogger(Logger logger) {
// If class B extends A, assuming B does not override method x(), the caller
// of new B().x() is A and not B, see also
- // http://bugzilla.slf4j.org/show_bug.cgi?id=114
+ // http://jira.qos.ch/browse/SLF4J-105
super(logger, LoggerWrapper.class.getName());
}
/**
* Log method entry.
*
- * @param argArray
- * supplied parameters
+ * @param argArray supplied parameters
*/
public void entry(Object... argArray) {
if (instanceofLAL && logger.isTraceEnabled(ENTRY_MARKER)) {
@@ -137,8 +135,7 @@ public class XLogger extends LoggerWrapper implements Logger {
/**
* Log method exit
*
- * @param result
- * The result of the method being exited
+ * @param result The result of the method being exited
*/
public <T> T exit(T result) {
if (instanceofLAL && logger.isTraceEnabled(ENTRY_MARKER)) {
@@ -151,8 +148,7 @@ public class XLogger extends LoggerWrapper implements Logger {
/**
* Log an exception being thrown. The generated log event uses Level ERROR.
*
- * @param throwable
- * the exception being caught.
+ * @param throwable the exception being caught.
*/
public <T extends Throwable> T throwing(T throwable) {
if (instanceofLAL) {
@@ -164,10 +160,8 @@ public class XLogger extends LoggerWrapper implements Logger {
/**
* Log an exception being thrown allowing the log level to be specified.
*
- * @param level
- * the logging level to use.
- * @param throwable
- * the exception being caught.
+ * @param level the logging level to use.
+ * @param throwable the exception being caught.
*/
public <T extends Throwable> T throwing(Level level, T throwable) {
if (instanceofLAL) {
@@ -179,8 +173,7 @@ public class XLogger extends LoggerWrapper implements Logger {
/**
* Log an exception being caught. The generated log event uses Level ERROR.
*
- * @param throwable
- * the exception being caught.
+ * @param throwable the exception being caught.
*/
public void catching(Throwable throwable) {
if (instanceofLAL) {
@@ -191,10 +184,8 @@ public class XLogger extends LoggerWrapper implements Logger {
/**
* Log an exception being caught allowing the log level to be specified.
*
- * @param level
- * the logging level to use.
- * @param throwable
- * the exception being caught.
+ * @param level the logging level to use.
+ * @param throwable the exception being caught.
*/
public void catching(Level level, Throwable throwable) {
if (instanceofLAL) {
diff --git a/slf4j-ext/src/main/java/org/slf4j/instrumentation/JavassistHelper.java b/slf4j-ext/src/main/java/org/slf4j/instrumentation/JavassistHelper.java
index 17c52674..5f4c1f26 100644
--- a/slf4j-ext/src/main/java/org/slf4j/instrumentation/JavassistHelper.java
+++ b/slf4j-ext/src/main/java/org/slf4j/instrumentation/JavassistHelper.java
@@ -40,9 +40,9 @@ import javassist.bytecode.LocalVariableAttribute;
public class JavassistHelper {
/**
- * Create a javaassist source snippet which either is empty (for anything
- * which does not return a value) or a explanatory text around the $_
- * javaassist return value variable.
+ * Create a javassist source snippet which either is empty (for anything
+ * which does not return a value) or an explanatory text around the $_
+ * javassist return value variable.
*
* @param method
* descriptor of method
@@ -82,7 +82,7 @@ public class JavassistHelper {
}
/**
- * Return javaassist source snippet which lists all the parameters and their
+ * Return javassist source snippet which lists all the parameters and their
* values. If available the source names are extracted from the debug
* information and used, otherwise just a number is shown.
*
@@ -92,7 +92,7 @@ public class JavassistHelper {
*/
public static String getSignature(CtBehavior method) throws NotFoundException {
- CtClass parameterTypes[] = method.getParameterTypes();
+ CtClass[] parameterTypes = method.getParameterTypes();
CodeAttribute codeAttribute = method.getMethodInfo().getCodeAttribute();
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 09eff678..1ea44794 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;
@@ -46,28 +46,27 @@ import org.slf4j.helpers.MessageFormatter;
* <p>
* LogTransformer does the work of analyzing each class, and if appropriate add
* log statements to each method to allow logging entry/exit.
- * </p>
+ *
* <p>
* This class is based on the article <a href="http://today.java.net/pub/a/today/2008/04/24/add-logging-at-class-load-time-with-instrumentation.html"
* >Add Logging at Class Load Time with Java Instrumentation</a>.
- * </p>
+ *
*/
public class LogTransformer implements ClassFileTransformer {
/**
* 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}
- *
+ *
+ * <a href="http://rwhansen.blogspot.com/2007/07/theres-builder-pattern-that-joshua.html">http://rwhansen.blogspot.com/2007/07/theres-builder-pattern-that-joshua.html</a>
+ *
*/
public static class Builder {
/**
* Build and return the LogTransformer corresponding to the options set in
* this Builder.
- *
+ *
* @return
*/
public LogTransformer build() {
@@ -81,8 +80,8 @@ public class LogTransformer implements ClassFileTransformer {
/**
* Should each method log entry (with parameters) and exit (with parameters
- * and returnvalue)?
- *
+ * and return value)?
+ *
* @param b
* value of flag
* @return
@@ -105,7 +104,7 @@ public class LogTransformer implements ClassFileTransformer {
/**
* Should LogTransformer be verbose in what it does? This currently list the
* names of the classes being processed.
- *
+ *
* @param b
* @return
*/
@@ -136,8 +135,8 @@ public class LogTransformer implements ClassFileTransformer {
}
}
- private String level;
- private String levelEnabled;
+ private final String level;
+ private final String levelEnabled;
private LogTransformer(Builder builder) {
String s = "WARNING: javassist not available on classpath for javaagent, log statements will not be added";
@@ -157,10 +156,10 @@ public class LogTransformer implements ClassFileTransformer {
this.levelEnabled = "is" + builder.level.substring(0, 1).toUpperCase() + builder.level.substring(1) + "Enabled";
}
- private boolean addEntryExit;
+ private final boolean addEntryExit;
// private boolean addVariableAssignment;
- private boolean verbose;
- private String[] ignore;
+ private final boolean verbose;
+ private final String[] ignore;
public byte[] transform(ClassLoader loader, String className, Class<?> clazz, ProtectionDomain domain, byte[] bytes) {
@@ -177,7 +176,7 @@ public class LogTransformer implements ClassFileTransformer {
* 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
@@ -188,8 +187,8 @@ public class LogTransformer implements ClassFileTransformer {
private byte[] transform0(String className, Class<?> clazz, ProtectionDomain domain, byte[] bytes) {
try {
- for (int i = 0; i < ignore.length; i++) {
- if (className.startsWith(ignore[i])) {
+ for (String s : ignore) {
+ if (className.startsWith(s)) {
return bytes;
}
}
@@ -227,7 +226,7 @@ public class LogTransformer implements ClassFileTransformer {
* 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
@@ -264,9 +263,9 @@ public class LogTransformer implements ClassFileTransformer {
// instrumented too.
CtBehavior[] methods = cl.getDeclaredBehaviors();
- for (int i = 0; i < methods.length; i++) {
- if (methods[i].isEmpty() == false) {
- doMethod(methods[i]);
+ for (CtBehavior method : methods) {
+ if (method.isEmpty() == false) {
+ doMethod(method);
}
}
b = cl.toBytecode();
@@ -285,7 +284,7 @@ public class LogTransformer implements ClassFileTransformer {
/**
* 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 @@ public class LogTransformer implements ClassFileTransformer {
method.insertAfter(after);
}
}
-} \ No newline at end of file
+}
diff --git a/slf4j-ext/src/main/java/org/slf4j/instrumentation/ToStringHelper.java b/slf4j-ext/src/main/java/org/slf4j/instrumentation/ToStringHelper.java
index b20f5851..f479dab6 100644
--- a/slf4j-ext/src/main/java/org/slf4j/instrumentation/ToStringHelper.java
+++ b/slf4j-ext/src/main/java/org/slf4j/instrumentation/ToStringHelper.java
@@ -53,10 +53,10 @@ public class ToStringHelper {
* is needed, but unfortunately the runtime library does not contain a
* WeakHashSet class, so the behavior is emulated with a WeakHashmap with
* the class as the key, and a Long containing the value of
- * System.currentTimeMilis when an instance of the class failed to render.
+ * System.currentTimeMillis when an instance of the class failed to render.
*/
- final static Map<Class<?>, Object> unrenderableClasses = new WeakHashMap<Class<?>, Object>();
+ final static Map<Class<?>, Object> unrenderableClasses = new WeakHashMap<>();
/**
* Returns o.toString() unless it throws an exception (which causes it to be
@@ -84,7 +84,7 @@ public class ToStringHelper {
return o.toString();
}
} catch (Exception e) {
- Long now = new Long(System.currentTimeMillis());
+ Long now = Long.valueOf(System.currentTimeMillis());
System.err.println("Disabling exception throwing class " + objectClass.getName() + ", " + e.getMessage());
diff --git a/slf4j-ext/src/main/java/org/slf4j/instrumentation/package.html b/slf4j-ext/src/main/java/org/slf4j/instrumentation/package.html
index 76001498..6816e8f2 100644
--- a/slf4j-ext/src/main/java/org/slf4j/instrumentation/package.html
+++ b/slf4j-ext/src/main/java/org/slf4j/instrumentation/package.html
@@ -9,7 +9,7 @@
<body>
<p>Java instrumentation routines for SLF4J.</p>
-<p>Byte code instrumentation is an way to change behaviour of java
+<p>Byte code instrumentation is a way to change behaviour of java
classes at <i>load time</i>. This is done in-between the original byte
codes are retrieved and the class object is constructed by the class
loader. Currently this depends on the javassist library from JBoss
diff --git a/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java b/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java
index 56357373..a0ecf43b 100644
--- a/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java
+++ b/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java
@@ -57,7 +57,7 @@ public class Profiler implements TimeInstrument {
final String name;
final StopWatch globalStopWatch;
- List<TimeInstrument> childTimeInstrumentList = new ArrayList<TimeInstrument>();
+ List<TimeInstrument> childTimeInstrumentList = new ArrayList<>();
// optional field
ProfilerRegistry profilerRegistry;
@@ -209,12 +209,12 @@ public class Profiler implements TimeInstrument {
* @since 1.5.9
*/
public List<TimeInstrument> getCopyOfChildTimeInstruments() {
- List<TimeInstrument> copy = new ArrayList<TimeInstrument>(childTimeInstrumentList);
+ List<TimeInstrument> copy = new ArrayList<>(childTimeInstrumentList);
return copy;
}
/**
- * Return a copy of the global stopwath of this Profiler instance.
+ * Return a copy of the global stopwatch of this Profiler instance.
*
* @return a copy of this instance's global stop watch
* @since 1.5.9
diff --git a/slf4j-ext/src/main/java/org/slf4j/profiler/ProfilerRegistry.java b/slf4j-ext/src/main/java/org/slf4j/profiler/ProfilerRegistry.java
index 61fda75e..264ca493 100644
--- a/slf4j-ext/src/main/java/org/slf4j/profiler/ProfilerRegistry.java
+++ b/slf4j-ext/src/main/java/org/slf4j/profiler/ProfilerRegistry.java
@@ -34,9 +34,9 @@ import java.util.Map;
*/
public class ProfilerRegistry {
- private static final InheritableThreadLocal<ProfilerRegistry> inheritableThreadLocal = new InheritableThreadLocal<ProfilerRegistry>();
+ private static final InheritableThreadLocal<ProfilerRegistry> inheritableThreadLocal = new InheritableThreadLocal<>();
- Map<String, Profiler> profilerMap = new HashMap<String, Profiler>();
+ Map<String, Profiler> profilerMap = new HashMap<>();
public void put(Profiler profiler) {
put(profiler.getName(), profiler);
diff --git a/slf4j-ext/src/main/java/org/slf4j/profiler/StopWatch.java b/slf4j-ext/src/main/java/org/slf4j/profiler/StopWatch.java
index 9ae7d295..60488fc3 100644
--- a/slf4j-ext/src/main/java/org/slf4j/profiler/StopWatch.java
+++ b/slf4j-ext/src/main/java/org/slf4j/profiler/StopWatch.java
@@ -25,7 +25,7 @@
package org.slf4j.profiler;
/**
- * A very basic @{link TimeInstrument} which can be started and stopped
+ * A very basic {@link TimeInstrument} which can be started and stopped
* once and only once.
*
* @author Ceki G&uuml;lc&uuml;
diff --git a/slf4j-ext/src/main/java/org/slf4j/profiler/TimeInstrument.java b/slf4j-ext/src/main/java/org/slf4j/profiler/TimeInstrument.java
index de749df8..6024d46b 100644
--- a/slf4j-ext/src/main/java/org/slf4j/profiler/TimeInstrument.java
+++ b/slf4j-ext/src/main/java/org/slf4j/profiler/TimeInstrument.java
@@ -43,9 +43,9 @@ public interface TimeInstrument {
TimeInstrumentStatus getStatus();
/**
- * Start tis time instrument.
+ * Start this time instrument.
*
- * @param name
+ * @param name the name of this instrument
*/
void start(String name);
diff --git a/slf4j-ext/src/main/resources/META-INF/MANIFEST.MF b/slf4j-ext/src/main/resources/META-INF/MANIFEST.MF
deleted file mode 100644
index 3328a2cc..00000000
--- a/slf4j-ext/src/main/resources/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,8 +0,0 @@
-Implementation-Title: slf4j-ext
-Bundle-ManifestVersion: 2
-Bundle-SymbolicName: slf4j.ext
-Bundle-Name: slf4j-ext
-Bundle-Vendor: SLF4J.ORG
-Bundle-RequiredExecutionEnvironment: J2SE-1.5
-Export-Package: org.slf4j.profiler;version=${parsedVersion.osgiVersion}, org.slf4j.cal10n;version=${parsedVersion.osgiVersion}, org.slf4j.ext;version=${parsedVersion.osgiVersion}
-Import-Package: org.slf4j;version=${parsedVersion.osgiVersion}, org.slf4j.spi;version=${parsedVersion.osgiVersion}, org.slf4j.helpers;version=${parsedVersion.osgiVersion}, ch.qos.cal10n;version=${cal10n.version}
diff --git a/slf4j-ext/src/test/java/org/slf4j/NDCTest.java b/slf4j-ext/src/test/java/org/slf4j/NDCTest.java
index 33b02bb0..e25164ee 100644
--- a/slf4j-ext/src/test/java/org/slf4j/NDCTest.java
+++ b/slf4j-ext/src/test/java/org/slf4j/NDCTest.java
@@ -24,29 +24,31 @@
*/
package org.slf4j;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
-public class NDCTest extends TestCase {
+import org.junit.Before;
+import org.junit.Test;
- protected void setUp() throws Exception {
- super.setUp();
- MDC.clear();
- }
+public class NDCTest {
- protected void tearDown() throws Exception {
- super.tearDown();
+ @Before
+ public void setUp() throws Exception {
+ MDC.clear();
}
+ @Test
public void testEmpty() {
assertEquals("", NDC.pop());
}
+ @Test
public void testSmoke() {
NDC.push("a");
String result = NDC.pop();
assertEquals("a", result);
}
+ @Test
public void testSmoke2() {
NDC.push("a");
NDC.push("b");
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 9254ad70..becab673 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
@@ -24,11 +24,13 @@
*/
package org.slf4j.cal10n_dummy;
-import java.util.Locale;
+import static org.junit.Assert.assertEquals;
-import junit.framework.TestCase;
+import java.util.Locale;
import org.apache.log4j.spi.LoggingEvent;
+import org.junit.Before;
+import org.junit.Test;
import org.slf4j.cal10n.LocLogger;
import org.slf4j.cal10n.LocLoggerFactory;
import org.slf4j.dummyExt.ListAppender;
@@ -36,7 +38,7 @@ import org.slf4j.dummyExt.ListAppender;
import ch.qos.cal10n.IMessageConveyor;
import ch.qos.cal10n.MessageConveyor;
-public class LocLoggerTest extends TestCase {
+public class LocLoggerTest {
ListAppender listAppender;
org.apache.log4j.Logger log4jRoot;
@@ -46,13 +48,8 @@ public class LocLoggerTest extends TestCase {
final static String EXPECTED_FILE_NAME = "LocLoggerTest.java";
- public LocLoggerTest(String name) {
- super(name);
- }
-
+ @Before
public void setUp() throws Exception {
- super.setUp();
-
// start from a clean slate for each test
listAppender = new ListAppender();
@@ -67,10 +64,7 @@ public class LocLoggerTest extends TestCase {
assertEquals(EXPECTED_FILE_NAME, le.getLocationInformation().getFileName());
}
- public void tearDown() throws Exception {
- super.tearDown();
- }
-
+ @Test
public void testSmoke() {
LocLogger locLogger = llFactory_uk.getLocLogger(this.getClass());
locLogger.info(Months.JAN);
diff --git a/slf4j-ext/src/test/java/org/slf4j/cal10n_dummy/PackageTest.java b/slf4j-ext/src/test/java/org/slf4j/cal10n_dummy/PackageTest.java
index 88413ba9..f77207b0 100644
--- a/slf4j-ext/src/test/java/org/slf4j/cal10n_dummy/PackageTest.java
+++ b/slf4j-ext/src/test/java/org/slf4j/cal10n_dummy/PackageTest.java
@@ -24,13 +24,11 @@
*/
package org.slf4j.cal10n_dummy;
-import junit.framework.*;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
-public class PackageTest extends TestCase {
-
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTestSuite(LocLoggerTest.class);
- return suite;
- }
+@RunWith(Suite.class)
+@SuiteClasses({ LocLoggerTest.class })
+public class PackageTest {
}
diff --git a/slf4j-ext/src/test/java/org/slf4j/dummyExt/EventLoggerTest.java b/slf4j-ext/src/test/java/org/slf4j/dummyExt/EventLoggerTest.java
deleted file mode 100644
index f04aecb6..00000000
--- a/slf4j-ext/src/test/java/org/slf4j/dummyExt/EventLoggerTest.java
+++ /dev/null
@@ -1,106 +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.dummyExt;
-
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import junit.framework.TestCase;
-
-import org.apache.log4j.spi.LocationInfo;
-import org.apache.log4j.spi.LoggingEvent;
-import org.slf4j.MDC;
-import org.slf4j.ext.EventData;
-import org.slf4j.ext.EventLogger;
-
-public class EventLoggerTest extends TestCase {
-
- ListAppender listAppender;
- org.apache.log4j.Logger log4;
-
- final static String EXPECTED_FILE_NAME = "EventLoggerTest.java";
-
- public EventLoggerTest(String name) {
- super(name);
- }
-
- public void setUp() throws Exception {
- super.setUp();
-
- // start from a clean slate for each test
-
- listAppender = new ListAppender();
- listAppender.extractLocationInfo = true;
- org.apache.log4j.Logger eventLogger = org.apache.log4j.Logger.getLogger("EventLogger");
- eventLogger.addAppender(listAppender);
- eventLogger.setLevel(org.apache.log4j.Level.TRACE);
- eventLogger.setAdditivity(false);
- // Items that apply to any activity
- MDC.put("ipAddress", "192.168.1.110");
- MDC.put("login", "TestUSer");
- MDC.put("hostname", "localhost");
- MDC.put("productName", "SLF4J");
- MDC.put("locale", Locale.getDefault().getDisplayName());
- MDC.put("timezone", TimeZone.getDefault().getDisplayName());
-
- }
-
- public void tearDown() throws Exception {
- super.tearDown();
- MDC.clear();
- }
-
- void verify(LoggingEvent le, String expectedMsg) {
- assertEquals(expectedMsg, le.getMessage());
- assertEquals(EXPECTED_FILE_NAME, le.getLocationInformation().getFileName());
- }
-
- public void testEventLogger() {
- EventData data[] = new EventData[2];
- data[0] = new EventData();
- data[0].setEventType("Login");
- data[0].setEventId("1");
- data[0].setEventDateTime(new Date());
- data[0].put("Userid", "TestUser");
- EventLogger.logEvent(data[0]);
-
- data[1] = new EventData();
- data[1].setEventType("Update");
- data[1].setEventId("2");
- data[1].setEventDateTime(new Date());
- data[1].put("FileName", "/etc/hosts");
- EventLogger.logEvent(data[1]);
-
- assertEquals(2, listAppender.list.size());
- for (int i = 0; i < 2; ++i) {
- LoggingEvent event = listAppender.list.get(i);
- verify(event, data[i].toXML());
- LocationInfo li = event.getLocationInformation();
- assertEquals(this.getClass().getName(), li.getClassName());
- assertEquals(event.getMDC("hostname"), "localhost");
- }
- }
-} \ No newline at end of file
diff --git a/slf4j-ext/src/test/java/org/slf4j/dummyExt/ListAppender.java b/slf4j-ext/src/test/java/org/slf4j/dummyExt/ListAppender.java
index bb7f2f2b..16194f77 100644
--- a/slf4j-ext/src/test/java/org/slf4j/dummyExt/ListAppender.java
+++ b/slf4j-ext/src/test/java/org/slf4j/dummyExt/ListAppender.java
@@ -32,7 +32,7 @@ import org.apache.log4j.spi.LoggingEvent;
public class ListAppender extends AppenderSkeleton {
- public List<LoggingEvent> list = new ArrayList<LoggingEvent>();
+ public final List<LoggingEvent> list = new ArrayList<>();
public boolean extractLocationInfo = false;
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 cee15d38..219d4357 100644
--- a/slf4j-ext/src/test/java/org/slf4j/dummyExt/PackageTest.java
+++ b/slf4j-ext/src/test/java/org/slf4j/dummyExt/PackageTest.java
@@ -24,15 +24,11 @@
*/
package org.slf4j.dummyExt;
-import junit.framework.*;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
-public class PackageTest extends TestCase {
-
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTestSuite(MDCStrLookupTest.class);
- suite.addTestSuite(XLoggerTest.class);
- suite.addTestSuite(EventLoggerTest.class);
- return suite;
- }
+@RunWith(Suite.class)
+@SuiteClasses({ XLoggerTest.class })
+public class PackageTest {
}
diff --git a/slf4j-ext/src/test/java/org/slf4j/dummyExt/XLoggerTest.java b/slf4j-ext/src/test/java/org/slf4j/dummyExt/XLoggerTest.java
index 33940cfc..16c1bc40 100644
--- a/slf4j-ext/src/test/java/org/slf4j/dummyExt/XLoggerTest.java
+++ b/slf4j-ext/src/test/java/org/slf4j/dummyExt/XLoggerTest.java
@@ -24,26 +24,24 @@
*/
package org.slf4j.dummyExt;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;
+import org.junit.Before;
+import org.junit.Test;
import org.slf4j.ext.XLogger;
import org.slf4j.ext.XLoggerFactory;
-public class XLoggerTest extends TestCase {
+public class XLoggerTest {
ListAppender listAppender;
org.apache.log4j.Logger log4jRoot;
final static String EXPECTED_FILE_NAME = "XLoggerTest.java";
- public XLoggerTest(String name) {
- super(name);
- }
-
+ @Before
public void setUp() throws Exception {
- super.setUp();
// start from a clean slate for each test
@@ -54,10 +52,6 @@ public class XLoggerTest extends TestCase {
log4jRoot.setLevel(org.apache.log4j.Level.TRACE);
}
- public void tearDown() throws Exception {
- super.tearDown();
- }
-
void verify(LoggingEvent le, String expectedMsg) {
assertEquals(expectedMsg, le.getMessage());
assertEquals(EXPECTED_FILE_NAME, le.getLocationInformation().getFileName());
@@ -74,6 +68,7 @@ public class XLoggerTest extends TestCase {
assertEquals(le.getLevel().toString(), level.toString());
}
+ @Test
public void testEntering() {
XLogger logger = XLoggerFactory.getXLogger("UnitTest");
logger.entry();
@@ -84,11 +79,12 @@ public class XLoggerTest extends TestCase {
logger.entry("a", "b", "c", "d", "e", "f");
assertEquals(6, listAppender.list.size());
- verify((LoggingEvent) listAppender.list.get(0), "entry");
- verify((LoggingEvent) listAppender.list.get(1), "entry with (1)");
- verify((LoggingEvent) listAppender.list.get(2), "entry with (test)");
+ verify(listAppender.list.get(0), "entry");
+ verify(listAppender.list.get(1), "entry with (1)");
+ verify(listAppender.list.get(2), "entry with (test)");
}
+ @Test
public void testExiting() {
XLogger logger = XLoggerFactory.getXLogger("UnitTest");
logger.exit();
@@ -96,22 +92,24 @@ public class XLoggerTest extends TestCase {
assertEquals(Boolean.FALSE, logger.exit(false));
assertEquals(3, listAppender.list.size());
- verify((LoggingEvent) listAppender.list.get(0), "exit");
- verify((LoggingEvent) listAppender.list.get(1), "exit with (0)");
- verify((LoggingEvent) listAppender.list.get(2), "exit with (false)");
+ verify(listAppender.list.get(0), "exit");
+ verify(listAppender.list.get(1), "exit with (0)");
+ verify(listAppender.list.get(2), "exit with (false)");
}
+ @Test
public void testThrowing() {
XLogger logger = XLoggerFactory.getXLogger("UnitTest");
Throwable t = new UnsupportedOperationException("Test");
assertEquals(t, logger.throwing(t));
assertEquals(t, logger.throwing(XLogger.Level.DEBUG, t));
assertEquals(2, listAppender.list.size());
- verifyWithException((LoggingEvent) listAppender.list.get(0), "throwing", t);
- LoggingEvent event = (LoggingEvent) listAppender.list.get(1);
+ verifyWithException(listAppender.list.get(0), "throwing", t);
+ LoggingEvent event = listAppender.list.get(1);
verifyWithLevelAndException(event, XLogger.Level.DEBUG, "throwing", t);
}
+ @Test
public void testCaught() {
XLogger logger = XLoggerFactory.getXLogger("UnitTest");
long x = 5;
@@ -124,11 +122,13 @@ public class XLoggerTest extends TestCase {
logger.catching(ex);
logger.catching(XLogger.Level.DEBUG, ex);
}
- verifyWithException((LoggingEvent) listAppender.list.get(0), "catching", t);
- verifyWithLevelAndException((LoggingEvent) listAppender.list.get(1), XLogger.Level.DEBUG, "catching", t);
+ verifyWithException(listAppender.list.get(0), "catching", t);
+ verifyWithLevelAndException(listAppender.list.get(1), XLogger.Level.DEBUG, "catching", t);
}
- // See http://bugzilla.slf4j.org/show_bug.cgi?id=114
+ // See http://jira.qos.ch/browse/SLF4J-105
+ // formerly http://bugzilla.slf4j.org/show_bug.cgi?id=114
+ @Test
public void testLocationExtraction_Bug114() {
XLogger logger = XLoggerFactory.getXLogger("UnitTest");
int line = 135; // requires update if line numbers change
@@ -150,6 +150,17 @@ public class XLoggerTest extends TestCase {
assertEquals(this.getClass().getName(), li.getClassName());
assertEquals("" + (line + 1), li.getLineNumber());
}
-
}
+
+ @Test
+ public void testNoDoubleSubstitution_Bug421() {
+ XLogger logger = XLoggerFactory.getXLogger("UnitTest");
+ logger.error("{},{}", "foo", "[{}]");
+ verify(listAppender.list.get(0), "foo,[{}]");
+
+ logger.error("{},{}", "[{}]", "foo");
+ verify(listAppender.list.get(1), "[{}],foo");
+ }
+
+
}
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 c21b0b83..81723c0c 100644
--- a/slf4j-ext/src/test/java/org/slf4j/instrumentation/ToStringHelperTest.java
+++ b/slf4j-ext/src/test/java/org/slf4j/instrumentation/ToStringHelperTest.java
@@ -24,10 +24,13 @@
*/
package org.slf4j.instrumentation;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
-public class ToStringHelperTest extends TestCase {
+import org.junit.Test;
+public class ToStringHelperTest {
+
+ @Test
public void testRenderer() {
assertEquals("", "null", ToStringHelper.render(null));
assertEquals("", "a", ToStringHelper.render("a"));
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 9a634625..40b8365c 100644
--- a/slf4j-ext/src/test/java/org/slf4j/profiler/PackageTest.java
+++ b/slf4j-ext/src/test/java/org/slf4j/profiler/PackageTest.java
@@ -24,14 +24,12 @@
*/
package org.slf4j.profiler;
-import junit.framework.*;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
-public class PackageTest extends TestCase {
+@RunWith(Suite.class)
+@SuiteClasses({ UtilTest.class, ProfilerTest.class })
+public class PackageTest {
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTestSuite(UtilTest.class);
- suite.addTestSuite(ProfilerTest.class);
- return suite;
- }
} \ No newline at end of file
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 2ea552be..fef09a53 100644
--- a/slf4j-ext/src/test/java/org/slf4j/profiler/ProfilerTest.java
+++ b/slf4j-ext/src/test/java/org/slf4j/profiler/ProfilerTest.java
@@ -24,19 +24,19 @@
*/
package org.slf4j.profiler;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class ProfilerTest extends TestCase {
+public class ProfilerTest {
Logger logger = LoggerFactory.getLogger(ProfilerTest.class);
- public void setUp() throws Exception {
- super.setUp();
- }
-
+ @Test
public void testSmoke() {
Profiler profiler = new Profiler("SMOKE");
profiler.stop();
@@ -49,6 +49,7 @@ public class ProfilerTest extends TestCase {
assertNull(profiler.getLastTimeInstrument());
}
+ @Test
public void testBasicProfiling() {
Profiler profiler = new Profiler("BAS");
@@ -80,6 +81,7 @@ public class ProfilerTest extends TestCase {
// |-- Total elapsed time [subtask] 7.321 milliseconds.
// |-- elapsed time [doZ] 3.211 milliseconds.
// |-- Total elapsed time [BAS] 30.317 milliseconds.
+ @Test
public void testNestedProfiling() {
Profiler profiler = new Profiler("BAS");
diff --git a/slf4j-ext/src/test/java/org/slf4j/profiler/SortAndPruneComposites.java b/slf4j-ext/src/test/java/org/slf4j/profiler/SortAndPruneComposites.java
index 867bb60f..b6e15088 100644
--- a/slf4j-ext/src/test/java/org/slf4j/profiler/SortAndPruneComposites.java
+++ b/slf4j-ext/src/test/java/org/slf4j/profiler/SortAndPruneComposites.java
@@ -50,7 +50,7 @@ public class SortAndPruneComposites {
int[] sortedArray = sort();
// start a new stopwatch called PRUNE_COMPOSITES
sortProfiler.start("PRUNE_COMPOSITES");
- int result[] = pruneComposites(sortedArray);
+ int[] result = pruneComposites(sortedArray);
return result;
}
@@ -63,7 +63,7 @@ public class SortAndPruneComposites {
}
int[] pruneComposites(int[] sortedArray) {
- ArrayList<Integer> primesArray = new ArrayList<Integer>();
+ ArrayList<Integer> primesArray = new ArrayList<>();
for (int i = 0; i < originalArrrayLength; i++) {
int n = sortedArray[i];
if (isPrime(n)) {
diff --git a/slf4j-ext/src/test/java/org/slf4j/profiler/UtilTest.java b/slf4j-ext/src/test/java/org/slf4j/profiler/UtilTest.java
index 601d6fb0..fc302518 100644
--- a/slf4j-ext/src/test/java/org/slf4j/profiler/UtilTest.java
+++ b/slf4j-ext/src/test/java/org/slf4j/profiler/UtilTest.java
@@ -24,22 +24,13 @@
*/
package org.slf4j.profiler;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
-public class UtilTest extends TestCase {
+import org.junit.Test;
- public UtilTest(String name) {
- super(name);
- }
-
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
+public class UtilTest {
+ @Test
public void testSelectDurationUnitForDisplay() throws InterruptedException {
assertEquals(DurationUnit.NANOSECOND, Util.selectDurationUnitForDisplay(10));
assertEquals(DurationUnit.NANOSECOND, Util.selectDurationUnitForDisplay(9 * Util.NANOS_IN_ONE_MICROSECOND));
diff --git a/slf4j-jcl/pom.xml b/slf4j-jcl/pom.xml
deleted file mode 100755
index 48216181..00000000
--- a/slf4j-jcl/pom.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-parent</artifactId>
- <version>1.7.13-SNAPSHOT</version>
- </parent>
-
- <artifactId>slf4j-jcl</artifactId>
- <packaging>jar</packaging>
- <name>SLF4J JCL Binding</name>
- <description>SLF4J JCL Binding</description>
-
- <url>http://www.slf4j.org</url>
-
- <dependencies>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- <version>1.1.1</version>
- </dependency>
-
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <archive>
- <manifestEntries>
- <Bundle-Version>${parsedVersion.osgiVersion}</Bundle-Version>
- <Bundle-Description>${project.description}</Bundle-Description>
- <Implementation-Version>${project.version}</Implementation-Version>
- </manifestEntries>
- <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
- </archive>
- </configuration>
- </plugin>
-
- </plugins>
- </build>
-
-</project> \ No newline at end of file
diff --git a/slf4j-jcl/src/main/java/org/slf4j/impl/JCLLoggerAdapter.java b/slf4j-jcl/src/main/java/org/slf4j/impl/JCLLoggerAdapter.java
deleted file mode 100644
index ad075208..00000000
--- a/slf4j-jcl/src/main/java/org/slf4j/impl/JCLLoggerAdapter.java
+++ /dev/null
@@ -1,531 +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 org.apache.commons.logging.Log;
-import org.slf4j.Logger;
-import org.slf4j.helpers.FormattingTuple;
-import org.slf4j.helpers.MarkerIgnoringBase;
-import org.slf4j.helpers.MessageFormatter;
-
-/**
- * A wrapper over {@link org.apache.commons.logging.Log
- * org.apache.commons.logging.Log} in conformance with the {@link Logger}
- * interface.
- *
- * @author Ceki G&uuml;lc&uuml;
- */
-public final class JCLLoggerAdapter extends MarkerIgnoringBase {
-
- private static final long serialVersionUID = 4141593417490482209L;
- final Log log;
-
- // WARN: JCLLoggerAdapter constructor should have only package access so
- // that only JCLLoggerFactory be able to create one.
- JCLLoggerAdapter(Log log, String name) {
- this.log = log;
- this.name = name;
- }
-
- /**
- * Delegates to the {@link Log#isTraceEnabled} method of the underlying
- * {@link Log} instance.
- */
- public boolean isTraceEnabled() {
- return log.isTraceEnabled();
- }
-
- //
-
- /**
- * Delegates to the {@link Log#trace(java.lang.Object)} method of the underlying
- * {@link Log} instance.
- *
- * @param msg - the message object to be logged
- */
- public void trace(String msg) {
- log.trace(msg);
- }
-
- /**
- * Delegates to the {@link Log#trace(java.lang.Object)} method of the underlying
- * {@link Log} instance.
- *
- * <p>
- * However, this form avoids superfluous object creation when the logger is disabled
- * for level TRACE.
- * </p>
- *
- * @param format
- * the format string
- * @param arg
- * the argument
- */
- public void trace(String format, Object arg) {
- if (log.isTraceEnabled()) {
- FormattingTuple ft = MessageFormatter.format(format, arg);
- log.trace(ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Delegates to the {@link Log#trace(java.lang.Object)} method of the underlying
- * {@link Log} instance.
- *
- * <p>
- * However, this form avoids superfluous object creation when the logger is disabled
- * for level TRACE.
- * </p>
- *
- * @param format
- * the format string
- * @param arg1
- * the first argument
- * @param arg2
- * the second argument
- */
- public void trace(String format, Object arg1, Object arg2) {
- if (log.isTraceEnabled()) {
- FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
- log.trace(ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Delegates to the {@link Log#trace(java.lang.Object)} method of the underlying
- * {@link Log} instance.
- *
- * <p>
- * However, this form avoids superfluous object creation when the logger is disabled
- * for level TRACE.
- * </p>
- *
- * @param format the format string
- * @param arguments a list of 3 or more arguments
- */
- public void trace(String format, Object... arguments) {
- if (log.isTraceEnabled()) {
- FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
- log.trace(ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Delegates to the {@link Log#trace(java.lang.Object, java.lang.Throwable)} method of
- * the underlying {@link Log} instance.
- *
- * @param msg
- * the message accompanying the exception
- * @param t
- * the exception (throwable) to log
- */
- public void trace(String msg, Throwable t) {
- log.trace(msg, t);
- }
-
- /**
- * Delegates to the {@link Log#isDebugEnabled} method of the underlying
- * {@link Log} instance.
- */
- public boolean isDebugEnabled() {
- return log.isDebugEnabled();
- }
-
- //
-
- /**
- * Delegates to the {@link Log#debug(java.lang.Object)} method of the underlying
- * {@link Log} instance.
- *
- * @param msg - the message object to be logged
- */
- public void debug(String msg) {
- log.debug(msg);
- }
-
- /**
- * Delegates to the {@link Log#debug(java.lang.Object)} method of the underlying
- * {@link Log} instance.
- *
- * <p>
- * However, this form avoids superfluous object creation when the logger is disabled
- * for level DEBUG.
- * </p>
- *
- * @param format
- * the format string
- * @param arg
- * the argument
- */
- public void debug(String format, Object arg) {
- if (log.isDebugEnabled()) {
- FormattingTuple ft = MessageFormatter.format(format, arg);
- log.debug(ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Delegates to the {@link Log#debug(java.lang.Object)} method of the underlying
- * {@link Log} instance.
- *
- * <p>
- * However, this form avoids superfluous object creation when the logger is disabled
- * for level DEBUG.
- * </p>
- *
- * @param format
- * the format string
- * @param arg1
- * the first argument
- * @param arg2
- * the second argument
- */
- public void debug(String format, Object arg1, Object arg2) {
- if (log.isDebugEnabled()) {
- FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
- log.debug(ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Delegates to the {@link Log#debug(java.lang.Object)} method of the underlying
- * {@link Log} instance.
- *
- * <p>
- * However, this form avoids superfluous object creation when the logger is disabled
- * for level DEBUG.
- * </p>
- *
- * @param format the format string
- * @param arguments a list of 3 or more arguments
- */
- public void debug(String format, Object... arguments) {
- if (log.isDebugEnabled()) {
- FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
- log.debug(ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Delegates to the {@link Log#debug(java.lang.Object, java.lang.Throwable)} method of
- * the underlying {@link Log} instance.
- *
- * @param msg
- * the message accompanying the exception
- * @param t
- * the exception (throwable) to log
- */
- public void debug(String msg, Throwable t) {
- log.debug(msg, t);
- }
-
- /**
- * Delegates to the {@link Log#isInfoEnabled} method of the underlying
- * {@link Log} instance.
- */
- public boolean isInfoEnabled() {
- return log.isInfoEnabled();
- }
-
- /**
- * Delegates to the {@link Log#debug(java.lang.Object)} method of the underlying
- * {@link Log} instance.
- *
- * @param msg - the message object to be logged
- */
- public void info(String msg) {
- log.info(msg);
- }
-
- /**
- * Delegates to the {@link Log#info(java.lang.Object)} method of the underlying
- * {@link Log} instance.
- *
- * <p>
- * However, this form avoids superfluous object creation when the logger is disabled
- * for level INFO.
- * </p>
- *
- * @param format
- * the format string
- * @param arg
- * the argument
- */
-
- public void info(String format, Object arg) {
- if (log.isInfoEnabled()) {
- FormattingTuple ft = MessageFormatter.format(format, arg);
- log.info(ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Delegates to the {@link Log#info(java.lang.Object)} method of the underlying
- * {@link Log} instance.
- *
- * <p>
- * However, this form avoids superfluous object creation when the logger is disabled
- * for level INFO.
- * </p>
- *
- * @param format
- * the format string
- * @param arg1
- * the first argument
- * @param arg2
- * the second argument
- */
- public void info(String format, Object arg1, Object arg2) {
- if (log.isInfoEnabled()) {
-
- FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
- log.info(ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Delegates to the {@link Log#info(java.lang.Object)} method of the underlying
- * {@link Log} instance.
- *
- * <p>
- * However, this form avoids superfluous object creation when the logger is disabled
- * for level INFO.
- * </p>
- *
- * @param format the format string
- * @param arguments a list of 3 or more arguments
- */
- public void info(String format, Object... arguments) {
- if (log.isInfoEnabled()) {
- FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
- log.info(ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Delegates to the {@link Log#info(java.lang.Object, java.lang.Throwable)} method of
- * the underlying {@link Log} instance.
- *
- * @param msg
- * the message accompanying the exception
- * @param t
- * the exception (throwable) to log
- */
- public void info(String msg, Throwable t) {
- log.info(msg, t);
- }
-
- /**
- * Delegates to the {@link Log#isWarnEnabled} method of the underlying
- * {@link Log} instance.
- */
- public boolean isWarnEnabled() {
- return log.isWarnEnabled();
- }
-
- /**
- * Delegates to the {@link Log#warn(java.lang.Object)} method of the underlying
- * {@link Log} instance.
- *
- * @param msg - the message object to be logged
- */
- public void warn(String msg) {
- log.warn(msg);
- }
-
- /**
- * Delegates to the {@link Log#warn(java.lang.Object)} method of the underlying
- * {@link Log} instance.
- *
- * <p>
- * However, this form avoids superfluous object creation when the logger is disabled
- * for level WARN.
- * </p>
- *
- * @param format
- * the format string
- * @param arg
- * the argument
- */
- public void warn(String format, Object arg) {
- if (log.isWarnEnabled()) {
- FormattingTuple ft = MessageFormatter.format(format, arg);
- log.warn(ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Delegates to the {@link Log#warn(java.lang.Object)} method of the underlying
- * {@link Log} instance.
- *
- * <p>
- * However, this form avoids superfluous object creation when the logger is disabled
- * for level WARN.
- * </p>
- *
- * @param format
- * the format string
- * @param arg1
- * the first argument
- * @param arg2
- * the second argument
- */
- public void warn(String format, Object arg1, Object arg2) {
- if (log.isWarnEnabled()) {
- FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
- log.warn(ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Delegates to the {@link Log#warn(java.lang.Object)} method of the underlying
- * {@link Log} instance.
- *
- * <p>
- * However, this form avoids superfluous object creation when the logger is disabled
- * for level WARN.
- * </p>
- *
- * @param format the format string
- * @param arguments a list of 3 or more arguments
- */
- public void warn(String format, Object... arguments) {
- if (log.isWarnEnabled()) {
- FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
- log.warn(ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Delegates to the {@link Log#warn(java.lang.Object, java.lang.Throwable)} method of
- * the underlying {@link Log} instance.
- *
- * @param msg
- * the message accompanying the exception
- * @param t
- * the exception (throwable) to log
- */
-
- public void warn(String msg, Throwable t) {
- log.warn(msg, t);
- }
-
- /**
- * Delegates to the {@link Log#isErrorEnabled} method of the underlying
- * {@link Log} instance.
- */
- public boolean isErrorEnabled() {
- return log.isErrorEnabled();
- }
-
- /**
- * Delegates to the {@link Log#error(java.lang.Object)} method of the underlying
- * {@link Log} instance.
- *
- * @param msg - the message object to be logged
- */
- public void error(String msg) {
- log.error(msg);
- }
-
- /**
- * Delegates to the {@link Log#error(java.lang.Object)} method of the underlying
- * {@link Log} instance.
- *
- * <p>
- * However, this form avoids superfluous object creation when the logger is disabled
- * for level ERROR.
- * </p>
- *
- * @param format
- * the format string
- * @param arg
- * the argument
- */
- public void error(String format, Object arg) {
- if (log.isErrorEnabled()) {
- FormattingTuple ft = MessageFormatter.format(format, arg);
- log.error(ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Delegates to the {@link Log#error(java.lang.Object)} method of the underlying
- * {@link Log} instance.
- *
- * <p>
- * However, this form avoids superfluous object creation when the logger is disabled
- * for level ERROR.
- * </p>
- *
- * @param format
- * the format string
- * @param arg1
- * the first argument
- * @param arg2
- * the second argument
- */
- public void error(String format, Object arg1, Object arg2) {
- if (log.isErrorEnabled()) {
- FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
- log.error(ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Delegates to the {@link Log#error(java.lang.Object)} method of the underlying
- * {@link Log} instance.
- *
- * <p>
- * However, this form avoids superfluous object creation when the logger is disabled
- * for level ERROR.
- * </p>
- *
- * @param format the format string
- * @param arguments a list of 3 or more arguments
- */
- public void error(String format, Object... arguments) {
- if (log.isErrorEnabled()) {
- FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
- log.error(ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Delegates to the {@link Log#error(java.lang.Object, java.lang.Throwable)} method of
- * the underlying {@link Log} instance.
- *
- * @param msg
- * the message accompanying the exception
- * @param t
- * the exception (throwable) to log
- */
-
- public void error(String msg, Throwable t) {
- log.error(msg, t);
- }
-
-}
diff --git a/slf4j-jcl/src/main/java/org/slf4j/impl/JCLLoggerFactory.java b/slf4j-jcl/src/main/java/org/slf4j/impl/JCLLoggerFactory.java
deleted file mode 100644
index 77ea88ec..00000000
--- a/slf4j-jcl/src/main/java/org/slf4j/impl/JCLLoggerFactory.java
+++ /dev/null
@@ -1,83 +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 java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import org.apache.commons.logging.LogFactory;
-import org.slf4j.ILoggerFactory;
-import org.slf4j.Logger;
-import org.slf4j.helpers.Util;
-
-/**
- * JCLLoggerFactory is an implementation of {@link ILoggerFactory} returning the
- * appropriately named {@link JCLLoggerAdapter} instance.
- *
- * @author Ceki G&uuml;lc&uuml;
- */
-public class JCLLoggerFactory implements ILoggerFactory {
-
- private static final String JCL_DELEGATION_LOOP_URL = "http://www.slf4j.org/codes.html#jclDelegationLoop";
-
- // check for delegation loops
- static {
- try {
- Class.forName("org.apache.commons.logging.impl.SLF4JLogFactory");
- String part1 = "Detected both jcl-over-slf4j.jar AND slf4j-jcl.jar on the class path, preempting StackOverflowError. ";
- String part2 = "See also " + JCL_DELEGATION_LOOP_URL + " for more details.";
-
- Util.report(part1);
- Util.report(part2);
- throw new IllegalStateException(part1 + part2);
- } catch (ClassNotFoundException e) {
- // this is the good case
- }
- }
-
- // key: name (String), value: a JCLLoggerAdapter;
- ConcurrentMap<String, Logger> loggerMap;
-
- public JCLLoggerFactory() {
- loggerMap = new ConcurrentHashMap<String, Logger>();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.slf4j.ILoggerFactory#getLogger(java.lang.String)
- */
- public Logger getLogger(String name) {
- Logger slf4jLogger = loggerMap.get(name);
- if (slf4jLogger != null) {
- return slf4jLogger;
- } else {
- org.apache.commons.logging.Log jclLogger = LogFactory.getLog(name);
- Logger newInstance = new JCLLoggerAdapter(jclLogger, name);
- Logger oldInstance = loggerMap.putIfAbsent(name, newInstance);
- return oldInstance == null ? newInstance : oldInstance;
- }
- }
-}
diff --git a/slf4j-jcl/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/slf4j-jcl/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
deleted file mode 100644
index 580770db..00000000
--- a/slf4j-jcl/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
+++ /dev/null
@@ -1,82 +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 org.slf4j.ILoggerFactory;
-import org.slf4j.LoggerFactory;
-import org.slf4j.spi.LoggerFactoryBinder;
-
-/**
- * The binding of {@link LoggerFactory} class with an actual instance of
- * {@link ILoggerFactory} is performed using information returned by this class.
- *
- * @author Ceki G&uuml;lc&uuml;
- */
-public class StaticLoggerBinder implements LoggerFactoryBinder {
-
- /**
- * The unique instance of this class.
- */
- private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
-
- /**
- * Return the singleton of this class.
- *
- * @return the StaticLoggerBinder singleton
- */
- public static final StaticLoggerBinder getSingleton() {
- return SINGLETON;
- }
-
- /**
- * Version tag used to check compatibility. The value of this field is
- * modified with each release.
- */
-
- // to avoid constant folding by the compiler, this field must *not* be final
- public static String REQUESTED_API_VERSION = "1.6.99";
-
- // Binding specific code:
- private static final String loggerFactoryClassStr = JCLLoggerFactory.class.getName();
-
- /**
- * The ILoggerFactory instance returned by the {@link #getLoggerFactory}
- * method should always be the same object
- */
- private final ILoggerFactory loggerFactory;
-
- private StaticLoggerBinder() {
- // Binding specific code:
- loggerFactory = new JCLLoggerFactory();
- }
-
- public ILoggerFactory getLoggerFactory() {
- return loggerFactory;
- }
-
- public String getLoggerFactoryClassStr() {
- return loggerFactoryClassStr;
- }
-}
diff --git a/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMarkerBinder.java b/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
deleted file mode 100644
index 1d255230..00000000
--- a/slf4j-jcl/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
+++ /dev/null
@@ -1,67 +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 org.slf4j.IMarkerFactory;
-import org.slf4j.MarkerFactory;
-import org.slf4j.helpers.BasicMarkerFactory;
-import org.slf4j.spi.MarkerFactoryBinder;
-
-/**
- *
- * The binding of {@link MarkerFactory} class with an actual instance of
- * {@link IMarkerFactory} is performed using information returned by this class.
- *
- * @author Ceki G&uuml;lc&uuml;
- */
-public class StaticMarkerBinder implements MarkerFactoryBinder {
-
- /**
- * The unique instance of this class.
- */
- public static final StaticMarkerBinder SINGLETON = new StaticMarkerBinder();
-
- final IMarkerFactory markerFactory = new BasicMarkerFactory();
-
- private StaticMarkerBinder() {
- }
-
- /**
- * Currently this method always returns an instance of
- * {@link BasicMarkerFactory}.
- */
- public IMarkerFactory getMarkerFactory() {
- return markerFactory;
- }
-
- /**
- * Currently, this method returns the class name of
- * {@link BasicMarkerFactory}.
- */
- public String getMarkerFactoryClassStr() {
- return BasicMarkerFactory.class.getName();
- }
-
-}
diff --git a/slf4j-jcl/src/main/resources/META-INF/MANIFEST.MF b/slf4j-jcl/src/main/resources/META-INF/MANIFEST.MF
deleted file mode 100644
index a9ee90ef..00000000
--- a/slf4j-jcl/src/main/resources/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,10 +0,0 @@
-Implementation-Title: slf4j-jcl
-Bundle-ManifestVersion: 2
-Bundle-SymbolicName: slf4j.jcl
-Bundle-Name: slf4j-jcl
-Bundle-Vendor: SLF4J.ORG
-Require-Bundle: slf4j.api
-Bundle-RequiredExecutionEnvironment: J2SE-1.5
-Export-Package: org.slf4j.impl;version=${parsedVersion.osgiVersion}
-Import-Package: org.slf4j.spi;version=${parsedVersion.osgiVersion}, org.slf4j.helpers;version=${parsedVersion.osgiVersion}, org.apache.commons.logging
-Fragment-Host: slf4j.api \ No newline at end of file
diff --git a/slf4j-jcl/src/test/java/org/slf4j/InvocationTest.java b/slf4j-jcl/src/test/java/org/slf4j/InvocationTest.java
deleted file mode 100644
index a7035153..00000000
--- a/slf4j-jcl/src/test/java/org/slf4j/InvocationTest.java
+++ /dev/null
@@ -1,125 +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;
-
-import java.util.logging.Level;
-
-import junit.framework.TestCase;
-
-/**
- * Test whether invoking the SLF4J API causes problems or not.
- *
- * @author Ceki Gulcu
- *
- */
-public class InvocationTest extends TestCase {
-
- Level oldLevel;
- java.util.logging.Logger root = java.util.logging.Logger.getLogger("");
-
- public InvocationTest(String arg0) {
- super(arg0);
- }
-
- protected void setUp() throws Exception {
- super.setUp();
- oldLevel = root.getLevel();
- root.setLevel(Level.OFF);
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- root.setLevel(oldLevel);
- }
-
- public void test1() {
- Logger logger = LoggerFactory.getLogger("test1");
- logger.debug("Hello world.");
- }
-
- public void test2() {
- Integer i1 = new Integer(1);
- Integer i2 = new Integer(2);
- Integer i3 = new Integer(3);
- Exception e = new Exception("This is a test exception.");
- Logger logger = LoggerFactory.getLogger("test2");
-
- logger.debug("Hello world 1.");
- logger.debug("Hello world {}", i1);
- logger.debug("val={} val={}", i1, i2);
- logger.debug("val={} val={} val={}", new Object[] { i1, i2, i3 });
-
- logger.debug("Hello world 2", e);
- logger.info("Hello world 2.");
-
- logger.warn("Hello world 3.");
- logger.warn("Hello world 3", e);
-
- logger.error("Hello world 4.");
- logger.error("Hello world {}", new Integer(3));
- logger.error("Hello world 4.", e);
- }
-
- public void testNull() {
- Logger logger = LoggerFactory.getLogger("testNull");
- logger.debug(null);
- logger.info(null);
- logger.warn(null);
- logger.error(null);
-
- Exception e = new Exception("This is a test exception.");
- logger.debug(null, e);
- logger.info(null, e);
- logger.warn(null, e);
- logger.error(null, e);
- }
-
- public void testMarker() {
- Logger logger = LoggerFactory.getLogger("testMarker");
- Marker blue = MarkerFactory.getMarker("BLUE");
- logger.debug(blue, "hello");
- logger.info(blue, "hello");
- logger.warn(blue, "hello");
- logger.error(blue, "hello");
-
- logger.debug(blue, "hello {}", "world");
- logger.info(blue, "hello {}", "world");
- logger.warn(blue, "hello {}", "world");
- logger.error(blue, "hello {}", "world");
-
- logger.debug(blue, "hello {} and {} ", "world", "universe");
- logger.info(blue, "hello {} and {} ", "world", "universe");
- logger.warn(blue, "hello {} and {} ", "world", "universe");
- logger.error(blue, "hello {} and {} ", "world", "universe");
- }
-
- public void testMDC() {
- MDC.put("k", "v");
- assertNull(MDC.get("k"));
- MDC.remove("k");
- assertNull(MDC.get("k"));
- MDC.clear();
- }
-}
diff --git a/slf4j-jdk-platform-logging/LICENSE.txt b/slf4j-jdk-platform-logging/LICENSE.txt
new file mode 100644
index 00000000..1a3d0532
--- /dev/null
+++ b/slf4j-jdk-platform-logging/LICENSE.txt
@@ -0,0 +1,24 @@
+Copyright (c) 2004-2022 QOS.ch Sarl (Switzerland)
+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.
+
+
+
diff --git a/slf4j-jdk-platform-logging/pom.xml b/slf4j-jdk-platform-logging/pom.xml
new file mode 100644
index 00000000..116ca976
--- /dev/null
+++ b/slf4j-jdk-platform-logging/pom.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>slf4j-parent</artifactId>
+ <groupId>org.slf4j</groupId>
+ <version>2.0.12</version>
+ <relativePath>../parent/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>slf4j-jdk-platform-logging</artifactId>
+ <packaging>jar</packaging>
+ <name>SLF4J JDK Platform Logging Integration</name>
+ <description>Integrated SLF4J with the Platform Logging API added by JEP 264 in Java 9</description>
+
+ <url>https://www.slf4j.org</url>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <!-- target Java 9+ -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>${maven-compiler-plugin.version}</version>
+ <executions>
+ <execution>
+ <id>default-compile</id>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ <configuration>
+ <source>9</source>
+ <target>9</target>
+ <release>9</release>
+ </configuration>
+ </execution>
+ <execution>
+ <id>default-testCompile</id>
+ <goals>
+ <goal>testCompile</goal>
+ </goals>
+ <configuration>
+ <source>9</source>
+ <target>9</target>
+ <release>9</release>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>${maven-surefire-plugin.version}</version>
+ <configuration>
+ <forkCount>1</forkCount>
+ <reuseForks>false</reuseForks>
+ <reportFormat>plain</reportFormat>
+ <trimStackTrace>false</trimStackTrace>
+ </configuration>
+ </plugin>
+
+
+ </plugins>
+ </build>
+
+</project>
diff --git a/slf4j-jdk-platform-logging/src/main/java/module-info.java b/slf4j-jdk-platform-logging/src/main/java/module-info.java
new file mode 100644
index 00000000..271ecb20
--- /dev/null
+++ b/slf4j-jdk-platform-logging/src/main/java/module-info.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2004-2021 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.
+ *
+ */
+module org.slf4j.jdk.platform.logging {
+ requires org.slf4j;
+ provides java.lang.System.LoggerFinder with org.slf4j.jdk.platform.logging.SLF4JSystemLoggerFinder;
+}
diff --git a/slf4j-jdk-platform-logging/src/main/java/org/slf4j/jdk/platform/logging/SLF4JPlatformLogger.java b/slf4j-jdk-platform-logging/src/main/java/org/slf4j/jdk/platform/logging/SLF4JPlatformLogger.java
new file mode 100644
index 00000000..194436d7
--- /dev/null
+++ b/slf4j-jdk-platform-logging/src/main/java/org/slf4j/jdk/platform/logging/SLF4JPlatformLogger.java
@@ -0,0 +1,181 @@
+/**
+ * Copyright (c) 2004-2021 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.jdk.platform.logging;
+
+import static java.util.Objects.requireNonNull;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.slf4j.Logger;
+import org.slf4j.helpers.Reporter;
+import org.slf4j.spi.CallerBoundaryAware;
+import org.slf4j.spi.LoggingEventBuilder;
+
+/**
+ * Adapts {@link Logger} to {@link System.Logger}.
+ * @since 2.0.0
+ */
+class SLF4JPlatformLogger implements System.Logger {
+
+ static private final String PRESUMED_CALLER_BOUNDARY = System.Logger.class.getName();
+
+ private final Logger slf4jLogger;
+
+ public SLF4JPlatformLogger(Logger logger) {
+ this.slf4jLogger = requireNonNull(logger);
+ }
+
+ @Override
+ public String getName() {
+ return slf4jLogger.getName();
+ }
+
+ // The fact that non loggable levels (in java.lang.System.Logger.Level)
+ // such as ALL and OFF leak into the public interface is quite a pity.
+
+ @Override
+ public boolean isLoggable(Level jplLevel) {
+ if (jplLevel == Level.ALL)
+ return true;
+ if (jplLevel == Level.OFF)
+ return true;
+
+ org.slf4j.event.Level slf4jLevel = jplLevelToSLF4JLevel(jplLevel);
+
+ return slf4jLogger.isEnabledForLevel(slf4jLevel);
+ }
+
+
+ /**
+ * Transform a {@link Level} to {@link org.slf4j.event.Level}.
+ *
+ * This method assumes that Level.ALL or Level.OFF never reach this method.
+ *
+ * @param jplLevel
+ * @return
+ */
+ private org.slf4j.event.Level jplLevelToSLF4JLevel(Level jplLevel) {
+ switch (jplLevel) {
+ case TRACE:
+ return org.slf4j.event.Level.TRACE;
+ case DEBUG:
+ return org.slf4j.event.Level.DEBUG;
+ case INFO:
+ return org.slf4j.event.Level.INFO;
+ case WARNING:
+ return org.slf4j.event.Level.WARN;
+ case ERROR:
+ return org.slf4j.event.Level.ERROR;
+ default:
+ reportUnknownLevel(jplLevel);
+ return null;
+ }
+ }
+
+ @Override
+ public void log(Level jplLevel, ResourceBundle bundle, String msg, Throwable thrown) {
+ log(jplLevel, bundle, msg, thrown, (Object[]) null);
+ }
+
+ @Override
+ public void log(Level jplLevel, ResourceBundle bundle, String format, Object... params) {
+ log(jplLevel, bundle, format, null, params);
+ }
+
+ /**
+ * Single point of processing taking all possible parameters.
+ *
+ * @param jplLevel
+ * @param bundle
+ * @param msg
+ * @param thrown
+ * @param params
+ */
+ private void log(Level jplLevel, ResourceBundle bundle, String msg, Throwable thrown, Object... params) {
+ if (jplLevel == Level.OFF)
+ return;
+
+ if (jplLevel == Level.ALL) {
+ performLog(org.slf4j.event.Level.TRACE, bundle, msg, thrown, params);
+ return;
+ }
+
+ org.slf4j.event.Level slf4jLevel = jplLevelToSLF4JLevel(jplLevel);
+ boolean isEnabled = slf4jLogger.isEnabledForLevel(slf4jLevel);
+
+ if (isEnabled) {
+ performLog(slf4jLevel, bundle, msg, thrown, params);
+ }
+ }
+
+ private void performLog(org.slf4j.event.Level slf4jLevel, ResourceBundle bundle, String msg, Throwable thrown, Object... params) {
+ String message = getResourceStringOrMessage(bundle, msg);
+ LoggingEventBuilder leb = slf4jLogger.makeLoggingEventBuilder(slf4jLevel);
+ if (thrown != null) {
+ leb = leb.setCause(thrown);
+ }
+ if (params != null && params.length > 0) {
+ // add the arguments to the logging event for possible processing by the backend
+ for (Object p : params) {
+ leb = leb.addArgument(p);
+ }
+ // The JDK uses a different formatting convention. We must invoke it now.
+ message = MessageFormat.format(message, params);
+ }
+ if (leb instanceof CallerBoundaryAware) {
+ CallerBoundaryAware cba = (CallerBoundaryAware) leb;
+ cba.setCallerBoundary(PRESUMED_CALLER_BOUNDARY);
+ }
+ leb.log(message);
+ }
+
+ private void reportUnknownLevel(Level jplLevel) {
+ String message = "Unknown log level [" + jplLevel + "]";
+ IllegalArgumentException iae = new IllegalArgumentException(message);
+ Reporter.error("Unsupported log level", iae);
+ }
+
+ private static String getResourceStringOrMessage(ResourceBundle bundle, String msg) {
+ if (bundle == null || msg == null)
+ return msg;
+ // ResourceBundle::getString throws:
+ //
+ // * NullPointerException for null keys
+ // * ClassCastException if the message is no string
+ // * MissingResourceException if there is no message for the key
+ //
+ // Handle all of these cases here to avoid log-related exceptions from crashing the JVM.
+ try {
+ return bundle.getString(msg);
+ } catch (MissingResourceException ex) {
+ return msg;
+ } catch (ClassCastException ex) {
+ return bundle.getObject(msg).toString();
+ }
+ }
+
+}
diff --git a/slf4j-ext/src/main/java/org/slf4j/ext/EventLogger.java b/slf4j-jdk-platform-logging/src/main/java/org/slf4j/jdk/platform/logging/SLF4JPlatformLoggerFactory.java
index a72e656e..f31ac7a8 100755..100644
--- a/slf4j-ext/src/main/java/org/slf4j/ext/EventLogger.java
+++ b/slf4j-jdk-platform-logging/src/main/java/org/slf4j/jdk/platform/logging/SLF4JPlatformLoggerFactory.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2004-2011 QOS.ch
+ * Copyright (c) 2004-2021 QOS.ch
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
@@ -22,43 +22,38 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j.ext;
+package org.slf4j.jdk.platform.logging;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.slf4j.Marker;
-import org.slf4j.MarkerFactory;
-import org.slf4j.spi.LocationAwareLogger;
/**
- * Simple Logger used to log events. All events are directed to a logger named "EventLogger"
- * with a level of INFO and with an Event marker.
+ * Manages instances of {@link SLF4JPlatformLogger}.
+ *
+ * @since 1.3.0
+ * @author Ceki
*
- * @author Ralph Goers
*/
-public class EventLogger {
-
- private static final String FQCN = EventLogger.class.getName();
-
- static Marker EVENT_MARKER = MarkerFactory.getMarker("EVENT");
-
- private static LoggerWrapper eventLogger = new LoggerWrapper(LoggerFactory.getLogger("EventLogger"), FQCN);
-
- /**
- * There can only be a single EventLogger.
- */
- private EventLogger() {
- }
-
+public class SLF4JPlatformLoggerFactory {
+ ConcurrentMap<String, SLF4JPlatformLogger> loggerMap = new ConcurrentHashMap<>();
+
/**
- * Logs the event.
- *
- * @param data The EventData.
+ * Return an appropriate {@link SLF4JPlatformLogger} instance by name.
*/
- public static void logEvent(EventData data) {
- if (eventLogger.instanceofLAL) {
- ((LocationAwareLogger) eventLogger.logger).log(EVENT_MARKER, FQCN, LocationAwareLogger.INFO_INT, data.toXML(), new Object[] { data }, null);
+ public SLF4JPlatformLogger getLogger(String loggerName) {
+
+
+ SLF4JPlatformLogger spla = loggerMap.get(loggerName);
+ if (spla != null) {
+ return spla;
} else {
- eventLogger.logger.info(EVENT_MARKER, data.toXML(), data);
+ Logger slf4jLogger = LoggerFactory.getLogger(loggerName);
+ SLF4JPlatformLogger newInstance = new SLF4JPlatformLogger(slf4jLogger);
+ SLF4JPlatformLogger oldInstance = loggerMap.putIfAbsent(loggerName, newInstance);
+ return oldInstance == null ? newInstance : oldInstance;
}
}
}
diff --git a/slf4j-jdk-platform-logging/src/main/java/org/slf4j/jdk/platform/logging/SLF4JSystemLoggerFinder.java b/slf4j-jdk-platform-logging/src/main/java/org/slf4j/jdk/platform/logging/SLF4JSystemLoggerFinder.java
new file mode 100644
index 00000000..a8622428
--- /dev/null
+++ b/slf4j-jdk-platform-logging/src/main/java/org/slf4j/jdk/platform/logging/SLF4JSystemLoggerFinder.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2004-2021 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.jdk.platform.logging;
+
+/**
+ * Uses {@link SLF4JPlatformLoggerFactory#getLogger(String)} to get a logger
+ * that is adapted for {@link System.Logger}.
+ *
+ * @since 2.0.0
+ */
+public class SLF4JSystemLoggerFinder extends System.LoggerFinder {
+
+ final SLF4JPlatformLoggerFactory platformLoggerFactory = new SLF4JPlatformLoggerFactory();
+
+ @Override
+ public System.Logger getLogger(String name, Module module) {
+ // JEP 264[1], which introduced the Platform Logging API,
+ // contains the following note:
+ //
+ // > An implementation of the LoggerFinder service should make it
+ // > possible to distinguish system loggers (used by system classes
+ // > from the Bootstrap Class Loader (BCL)) and application loggers
+ // > (created by an application for its own usage). This distinction
+ // > is important for platform security. The creator of a logger can
+ // > pass the class or module for which the logger is created to the
+ // > LoggerFinder so that the LoggerFinder can figure out which kind
+ // > of logger to return.
+ //
+ // If backends support this distinction and once `LoggerFactory`'s API
+ // is updated to forward a module, we should do that here.
+ //
+ // [1] https://openjdk.java.net/jeps/264
+ SLF4JPlatformLogger adapter = platformLoggerFactory.getLogger(name);
+ return adapter;
+ }
+
+} \ No newline at end of file
diff --git a/slf4j-jdk-platform-logging/src/main/resources/META-INF/services/java.lang.System$LoggerFinder b/slf4j-jdk-platform-logging/src/main/resources/META-INF/services/java.lang.System$LoggerFinder
new file mode 100644
index 00000000..06845269
--- /dev/null
+++ b/slf4j-jdk-platform-logging/src/main/resources/META-INF/services/java.lang.System$LoggerFinder
@@ -0,0 +1 @@
+org.slf4j.jdk.platform.logging.SLF4JSystemLoggerFinder
diff --git a/slf4j-jdk-platform-logging/src/test/java/org/slf4j/jdk/platform/logging/test/SLF4JPlatformLoggingTest.java b/slf4j-jdk-platform-logging/src/test/java/org/slf4j/jdk/platform/logging/test/SLF4JPlatformLoggingTest.java
new file mode 100644
index 00000000..7a662b96
--- /dev/null
+++ b/slf4j-jdk-platform-logging/src/test/java/org/slf4j/jdk/platform/logging/test/SLF4JPlatformLoggingTest.java
@@ -0,0 +1,119 @@
+/**
+ * Copyright (c) 2004-2021 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.jdk.platform.logging.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
+import java.lang.System.LoggerFinder;
+import java.util.List;
+import java.util.Random;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * The present test is fragile in the sense that it sets up SimpleLogger
+ * with a StringPrintStream and reverts to the old stream when done.
+ *
+ * Any tests running simultaneously (and using SimpleLogger) will be affected
+ * by this. Moreover, since SimpleLogger is initialized by the call to LoggerFactory
+ * and tests also using LoggerFactory will also be affected.
+ *
+ * @author Ceki G&uuml;lc&uuml;
+ *
+ */
+public class SLF4JPlatformLoggingTest {
+
+ static final String PREFIX = "org.slf4j.simpleLogger.";
+ static final String SIMPLE_LOGGER_FILE_PROPERTY = PREFIX + "logFile";
+ static final String SIMPLE_LOGGER_THREAD_NAME_PROPERTY = PREFIX + "showThreadName";
+
+ static final String EXPECTED_FINDER_CLASS = "org.slf4j.jdk.platform.logging.SLF4JSystemLoggerFinder";
+
+ static int diff = new Random().nextInt(100*1000*1000);
+
+ static final PrintStream oldErr = System.err;
+ static StringPrintStream SPS = new StringPrintStream(oldErr, false);
+
+ @BeforeClass
+ static public void beforeClass() throws Exception {
+ System.setErr(SPS);
+ //System.setProperty(SIMPLE_LOGGER_FILE_PROPERTY, targetFile);
+ System.setProperty(SIMPLE_LOGGER_THREAD_NAME_PROPERTY, "false");
+ }
+
+ @AfterClass
+ static public void afterClass() {
+ System.setErr(oldErr);
+ System.clearProperty(SIMPLE_LOGGER_THREAD_NAME_PROPERTY);
+ }
+
+ @After
+ public void tearDown() {
+ SPS.stringList.clear();
+ }
+
+ @Test
+ public void smoke() throws IOException {
+ LoggerFinder finder = System.LoggerFinder.getLoggerFinder();
+ assertEquals(EXPECTED_FINDER_CLASS, finder.getClass().getName());
+ Logger systemLogger = finder.getLogger("smoke", null);
+ systemLogger.log(Level.INFO, "hello");
+ systemLogger.log(Level.INFO, "hello {0}", "world");
+
+ List<String> results = SPS.stringList;
+ assertEquals(2, results.size());
+ assertEquals("INFO smoke - hello", results.get(0));
+ assertEquals("INFO smoke - hello world", results.get(1));
+ }
+
+ @Test
+ public void throwTest() throws IOException {
+ LoggerFinder finder = System.LoggerFinder.getLoggerFinder();
+ assertEquals(EXPECTED_FINDER_CLASS, finder.getClass().getName());
+
+ Logger systemLogger = finder.getLogger("throwTest", null);
+ systemLogger.log(Level.INFO, "we have a problem", new Exception());
+
+ List<String> results = SPS.stringList;
+ //INFO throwTest - a problem
+ //java.lang.Exception
+ // at org.slf4j.jdk.platform.logging/org.slf4j.jdk.platform.logging.SLF4JPlatformLoggingTest.throwTest(SLF4JPlatformLoggingTest.java:92)
+
+ assertEquals("INFO throwTest - we have a problem", results.get(0));
+ assertEquals(Exception.class.getName(), results.get(1));
+ assertTrue(results.get(2).contains("at "));
+ assertTrue(results.get(2).contains(this.getClass().getName()));
+ }
+
+
+}
diff --git a/slf4j-jdk-platform-logging/src/test/java/org/slf4j/jdk/platform/logging/test/StringPrintStream.java b/slf4j-jdk-platform-logging/src/test/java/org/slf4j/jdk/platform/logging/test/StringPrintStream.java
new file mode 100644
index 00000000..b51e1cd2
--- /dev/null
+++ b/slf4j-jdk-platform-logging/src/test/java/org/slf4j/jdk/platform/logging/test/StringPrintStream.java
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2004-2021 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.jdk.platform.logging.test;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class StringPrintStream extends PrintStream {
+
+ public static final String LINE_SEP = System.getProperty("line.separator");
+ PrintStream other;
+ boolean duplicate = false;
+
+ public List<String> stringList = Collections.synchronizedList(new ArrayList<String>());
+
+ 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());
+ }
+} \ No newline at end of file
diff --git a/slf4j-jdk14/LICENSE.txt b/slf4j-jdk14/LICENSE.txt
index 508a2728..e4079f54 100644
--- a/slf4j-jdk14/LICENSE.txt
+++ b/slf4j-jdk14/LICENSE.txt
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2007 QOS.ch
+Copyright (c) 2004-2023 QOS.ch
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/slf4j-jdk14/pom.xml b/slf4j-jdk14/pom.xml
index 16d4fa79..8d677685 100755
--- a/slf4j-jdk14/pom.xml
+++ b/slf4j-jdk14/pom.xml
@@ -1,23 +1,27 @@
-<project
- xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
- <version>1.7.13-SNAPSHOT</version>
+ <version>2.0.12</version>
+ <relativePath>../parent/pom.xml</relativePath>
</parent>
<artifactId>slf4j-jdk14</artifactId>
-
<packaging>jar</packaging>
- <name>SLF4J JDK14 Binding</name>
- <description>SLF4J JDK14 Binding</description>
+ <name>SLF4J JDK14 Provider</name>
+ <description>SLF4J JDK14 Provider</description>
<url>http://www.slf4j.org</url>
+ <properties>
+ <module-name>org.slf4j.jul</module-name>
+ <slf4j.provider.implementation>org.slf4j.jul.JULServiceProvider</slf4j.provider.implementation>
+ <slf4j.provider.type>jul</slf4j.provider.type>
+ </properties>
<dependencies>
<dependency>
@@ -34,23 +38,4 @@
</dependency>
</dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <archive>
- <manifestEntries>
- <Bundle-Version>${parsedVersion.osgiVersion}</Bundle-Version>
- <Bundle-Description>${project.description}</Bundle-Description>
- <Implementation-Version>${project.version}</Implementation-Version>
- </manifestEntries>
- <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
- </archive>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project> \ No newline at end of file
+</project>
diff --git a/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerAdapter.java b/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerAdapter.java
deleted file mode 100755
index 2de8e3e5..00000000
--- a/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerAdapter.java
+++ /dev/null
@@ -1,651 +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 java.util.logging.Level;
-import java.util.logging.LogRecord;
-
-import org.slf4j.Logger;
-import org.slf4j.Marker;
-import org.slf4j.helpers.FormattingTuple;
-import org.slf4j.helpers.MarkerIgnoringBase;
-import org.slf4j.helpers.MessageFormatter;
-import org.slf4j.spi.LocationAwareLogger;
-
-/**
- * A wrapper over {@link java.util.logging.Logger java.util.logging.Logger} in
- * conformity with the {@link Logger} interface. Note that the logging levels
- * mentioned in this class refer to those defined in the java.util.logging
- * package.
- *
- * @author Ceki G&uuml;lc&uuml;
- * @author Peter Royal
- */
-public final class JDK14LoggerAdapter extends MarkerIgnoringBase implements LocationAwareLogger {
-
- private static final long serialVersionUID = -8053026990503422791L;
-
- transient final java.util.logging.Logger logger;
-
- // WARN: JDK14LoggerAdapter constructor should have only package access so
- // that only JDK14LoggerFactory be able to create one.
- JDK14LoggerAdapter(java.util.logging.Logger logger) {
- this.logger = logger;
- this.name = logger.getName();
- }
-
- /**
- * Is this logger instance enabled for the FINEST level?
- *
- * @return True if this Logger is enabled for level FINEST, false otherwise.
- */
- public boolean isTraceEnabled() {
- return logger.isLoggable(Level.FINEST);
- }
-
- /**
- * Log a message object at level FINEST.
- *
- * @param msg
- * - the message object to be logged
- */
- public void trace(String msg) {
- if (logger.isLoggable(Level.FINEST)) {
- log(SELF, Level.FINEST, msg, null);
- }
- }
-
- /**
- * Log a message at level FINEST according to the specified format and
- * argument.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for level FINEST.
- * </p>
- *
- * @param format
- * the format string
- * @param arg
- * the argument
- */
- public void trace(String format, Object arg) {
- if (logger.isLoggable(Level.FINEST)) {
- FormattingTuple ft = MessageFormatter.format(format, arg);
- log(SELF, Level.FINEST, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log a message at level FINEST according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the FINEST level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg1
- * the first argument
- * @param arg2
- * the second argument
- */
- public void trace(String format, Object arg1, Object arg2) {
- if (logger.isLoggable(Level.FINEST)) {
- FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
- log(SELF, Level.FINEST, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log a message at level FINEST according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the FINEST level.
- * </p>
- *
- * @param format
- * the format string
- * @param argArray
- * an array of arguments
- */
- public void trace(String format, Object... argArray) {
- if (logger.isLoggable(Level.FINEST)) {
- FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
- log(SELF, Level.FINEST, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log an exception (throwable) at level FINEST with an accompanying message.
- *
- * @param msg
- * the message accompanying the exception
- * @param t
- * the exception (throwable) to log
- */
- public void trace(String msg, Throwable t) {
- if (logger.isLoggable(Level.FINEST)) {
- log(SELF, Level.FINEST, msg, t);
- }
- }
-
- /**
- * Is this logger instance enabled for the FINE level?
- *
- * @return True if this Logger is enabled for level FINE, false otherwise.
- */
- public boolean isDebugEnabled() {
- return logger.isLoggable(Level.FINE);
- }
-
- /**
- * Log a message object at level FINE.
- *
- * @param msg
- * - the message object to be logged
- */
- public void debug(String msg) {
- if (logger.isLoggable(Level.FINE)) {
- log(SELF, Level.FINE, msg, null);
- }
- }
-
- /**
- * Log a message at level FINE according to the specified format and argument.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for level FINE.
- * </p>
- *
- * @param format
- * the format string
- * @param arg
- * the argument
- */
- public void debug(String format, Object arg) {
- if (logger.isLoggable(Level.FINE)) {
- FormattingTuple ft = MessageFormatter.format(format, arg);
- log(SELF, Level.FINE, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log a message at level FINE according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the FINE level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg1
- * the first argument
- * @param arg2
- * the second argument
- */
- public void debug(String format, Object arg1, Object arg2) {
- if (logger.isLoggable(Level.FINE)) {
- FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
- log(SELF, Level.FINE, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log a message at level FINE according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the FINE level.
- * </p>
- *
- * @param format
- * the format string
- * @param argArray
- * an array of arguments
- */
- public void debug(String format, Object... argArray) {
- if (logger.isLoggable(Level.FINE)) {
- FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
- log(SELF, Level.FINE, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log an exception (throwable) at level FINE with an accompanying message.
- *
- * @param msg
- * the message accompanying the exception
- * @param t
- * the exception (throwable) to log
- */
- public void debug(String msg, Throwable t) {
- if (logger.isLoggable(Level.FINE)) {
- log(SELF, Level.FINE, msg, t);
- }
- }
-
- /**
- * Is this logger instance enabled for the INFO level?
- *
- * @return True if this Logger is enabled for the INFO level, false otherwise.
- */
- public boolean isInfoEnabled() {
- return logger.isLoggable(Level.INFO);
- }
-
- /**
- * Log a message object at the INFO level.
- *
- * @param msg
- * - the message object to be logged
- */
- public void info(String msg) {
- if (logger.isLoggable(Level.INFO)) {
- log(SELF, Level.INFO, msg, null);
- }
- }
-
- /**
- * Log a message at level INFO according to the specified format and argument.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the INFO level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg
- * the argument
- */
- public void info(String format, Object arg) {
- if (logger.isLoggable(Level.INFO)) {
- FormattingTuple ft = MessageFormatter.format(format, arg);
- log(SELF, Level.INFO, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log a message at the INFO level according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the INFO level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg1
- * the first argument
- * @param arg2
- * the second argument
- */
- public void info(String format, Object arg1, Object arg2) {
- if (logger.isLoggable(Level.INFO)) {
- FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
- log(SELF, Level.INFO, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log a message at level INFO according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the INFO level.
- * </p>
- *
- * @param format
- * the format string
- * @param argArray
- * an array of arguments
- */
- public void info(String format, Object... argArray) {
- if (logger.isLoggable(Level.INFO)) {
- FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
- log(SELF, Level.INFO, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log an exception (throwable) at the INFO level with an accompanying
- * message.
- *
- * @param msg
- * the message accompanying the exception
- * @param t
- * the exception (throwable) to log
- */
- public void info(String msg, Throwable t) {
- if (logger.isLoggable(Level.INFO)) {
- log(SELF, Level.INFO, msg, t);
- }
- }
-
- /**
- * Is this logger instance enabled for the WARNING level?
- *
- * @return True if this Logger is enabled for the WARNING level, false
- * otherwise.
- */
- public boolean isWarnEnabled() {
- return logger.isLoggable(Level.WARNING);
- }
-
- /**
- * Log a message object at the WARNING level.
- *
- * @param msg
- * - the message object to be logged
- */
- public void warn(String msg) {
- if (logger.isLoggable(Level.WARNING)) {
- log(SELF, Level.WARNING, msg, null);
- }
- }
-
- /**
- * Log a message at the WARNING level according to the specified format and
- * argument.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the WARNING level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg
- * the argument
- */
- public void warn(String format, Object arg) {
- if (logger.isLoggable(Level.WARNING)) {
- FormattingTuple ft = MessageFormatter.format(format, arg);
- log(SELF, Level.WARNING, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log a message at the WARNING level according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the WARNING level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg1
- * the first argument
- * @param arg2
- * the second argument
- */
- public void warn(String format, Object arg1, Object arg2) {
- if (logger.isLoggable(Level.WARNING)) {
- FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
- log(SELF, Level.WARNING, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log a message at level WARNING according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the WARNING level.
- * </p>
- *
- * @param format
- * the format string
- * @param argArray
- * an array of arguments
- */
- public void warn(String format, Object... argArray) {
- if (logger.isLoggable(Level.WARNING)) {
- FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
- log(SELF, Level.WARNING, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log an exception (throwable) at the WARNING level with an accompanying
- * message.
- *
- * @param msg
- * the message accompanying the exception
- * @param t
- * the exception (throwable) to log
- */
- public void warn(String msg, Throwable t) {
- if (logger.isLoggable(Level.WARNING)) {
- log(SELF, Level.WARNING, msg, t);
- }
- }
-
- /**
- * Is this logger instance enabled for level SEVERE?
- *
- * @return True if this Logger is enabled for level SEVERE, false otherwise.
- */
- public boolean isErrorEnabled() {
- return logger.isLoggable(Level.SEVERE);
- }
-
- /**
- * Log a message object at the SEVERE level.
- *
- * @param msg
- * - the message object to be logged
- */
- public void error(String msg) {
- if (logger.isLoggable(Level.SEVERE)) {
- log(SELF, Level.SEVERE, msg, null);
- }
- }
-
- /**
- * Log a message at the SEVERE level according to the specified format and
- * argument.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the SEVERE level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg
- * the argument
- */
- public void error(String format, Object arg) {
- if (logger.isLoggable(Level.SEVERE)) {
- FormattingTuple ft = MessageFormatter.format(format, arg);
- log(SELF, Level.SEVERE, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log a message at the SEVERE level according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the SEVERE level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg1
- * the first argument
- * @param arg2
- * the second argument
- */
- public void error(String format, Object arg1, Object arg2) {
- if (logger.isLoggable(Level.SEVERE)) {
- FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
- log(SELF, Level.SEVERE, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log a message at level SEVERE according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the SEVERE level.
- * </p>
- *
- * @param format
- * the format string
- * @param arguments
- * an array of arguments
- */
- public void error(String format, Object... arguments) {
- if (logger.isLoggable(Level.SEVERE)) {
- FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
- log(SELF, Level.SEVERE, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log an exception (throwable) at the SEVERE level with an accompanying
- * message.
- *
- * @param msg
- * the message accompanying the exception
- * @param t
- * the exception (throwable) to log
- */
- public void error(String msg, Throwable t) {
- if (logger.isLoggable(Level.SEVERE)) {
- log(SELF, Level.SEVERE, msg, t);
- }
- }
-
- /**
- * Log the message at the specified level with the specified throwable if any.
- * This method creates a LogRecord and fills in caller date before calling
- * this instance's JDK14 logger.
- *
- * See bug report #13 for more details.
- *
- * @param level
- * @param msg
- * @param t
- */
- private void log(String callerFQCN, Level level, String msg, Throwable t) {
- // millis and thread are filled by the constructor
- LogRecord record = new LogRecord(level, msg);
- record.setLoggerName(getName());
- record.setThrown(t);
- fillCallerData(callerFQCN, record);
- logger.log(record);
-
- }
-
- static String SELF = JDK14LoggerAdapter.class.getName();
- static String SUPER = MarkerIgnoringBase.class.getName();
-
- /**
- * Fill in caller data if possible.
- *
- * @param record
- * The record to update
- */
- final private void fillCallerData(String callerFQCN, LogRecord record) {
- StackTraceElement[] steArray = new Throwable().getStackTrace();
-
- int selfIndex = -1;
- for (int i = 0; i < steArray.length; i++) {
- final String className = steArray[i].getClassName();
- if (className.equals(callerFQCN) || className.equals(SUPER)) {
- selfIndex = i;
- break;
- }
- }
-
- int found = -1;
- for (int i = selfIndex + 1; i < steArray.length; i++) {
- final String className = steArray[i].getClassName();
- if (!(className.equals(callerFQCN) || className.equals(SUPER))) {
- found = i;
- break;
- }
- }
-
- if (found != -1) {
- StackTraceElement ste = steArray[found];
- // setting the class name has the side effect of setting
- // the needToInferCaller variable to false.
- record.setSourceClassName(ste.getClassName());
- record.setSourceMethodName(ste.getMethodName());
- }
- }
-
- public void log(Marker marker, String callerFQCN, int level, String message, Object[] argArray, Throwable t) {
- Level julLevel;
- switch (level) {
- case LocationAwareLogger.TRACE_INT:
- julLevel = Level.FINEST;
- break;
- case LocationAwareLogger.DEBUG_INT:
- julLevel = Level.FINE;
- break;
- case LocationAwareLogger.INFO_INT:
- julLevel = Level.INFO;
- break;
- case LocationAwareLogger.WARN_INT:
- julLevel = Level.WARNING;
- break;
- case LocationAwareLogger.ERROR_INT:
- 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://bugzilla.slf4j.org/show_bug.cgi?id=90
- if (logger.isLoggable(julLevel)) {
- log(callerFQCN, julLevel, message, t);
- }
- }
-}
diff --git a/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
deleted file mode 100644
index e532be61..00000000
--- a/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
+++ /dev/null
@@ -1,80 +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 org.slf4j.ILoggerFactory;
-import org.slf4j.LoggerFactory;
-import org.slf4j.spi.LoggerFactoryBinder;
-
-/**
- * The binding of {@link LoggerFactory} class with an actual instance of
- * {@link ILoggerFactory} is performed using information returned by this class.
- *
- * @author Ceki G&uuml;lc&uuml;
- */
-public class StaticLoggerBinder implements LoggerFactoryBinder {
-
- /**
- * The unique instance of this class.
- *
- */
- private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
-
- /**
- * Return the singleton of this class.
- *
- * @return the StaticLoggerBinder singleton
- */
- public static final StaticLoggerBinder getSingleton() {
- return SINGLETON;
- }
-
- /**
- * Declare the version of the SLF4J API this implementation is compiled against.
- * The value of this field is usually modified with each release.
- */
- // to avoid constant folding by the compiler, this field must *not* be final
- public static String REQUESTED_API_VERSION = "1.6.99"; // !final
-
- private static final String loggerFactoryClassStr = org.slf4j.impl.JDK14LoggerFactory.class.getName();
-
- /** The ILoggerFactory instance returned by the {@link #getLoggerFactory} method
- * should always be the same object
- */
- private final ILoggerFactory loggerFactory;
-
- private StaticLoggerBinder() {
- // Note: JCL gets substituted at build time by an appropriate Ant task
- loggerFactory = new org.slf4j.impl.JDK14LoggerFactory();
- }
-
- public ILoggerFactory getLoggerFactory() {
- return loggerFactory;
- }
-
- public String getLoggerFactoryClassStr() {
- return loggerFactoryClassStr;
- }
-}
diff --git a/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMDCBinder.java b/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMDCBinder.java
deleted file mode 100644
index bff523db..00000000
--- a/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMDCBinder.java
+++ /dev/null
@@ -1,58 +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 org.slf4j.helpers.BasicMDCAdapter;
-import org.slf4j.spi.MDCAdapter;
-
-/**
- * This implementation is bound to {@link BasicMDCAdapter}.
- *
- * @author Ceki G&uuml;lc&uuml;
- */
-public class StaticMDCBinder {
-
- /**
- * The unique instance of this class.
- */
- public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
-
- private StaticMDCBinder() {
- }
-
- /**
- * Currently this method always returns an instance of
- * {@link BasicMDCAdapter}.
- */
- public MDCAdapter getMDCA() {
- // note that this method is invoked only from within the static initializer of
- // the org.slf4j.MDC class.
- return new BasicMDCAdapter();
- }
-
- public String getMDCAdapterClassStr() {
- return BasicMDCAdapter.class.getName();
- }
-}
diff --git a/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMarkerBinder.java b/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
deleted file mode 100644
index 1d255230..00000000
--- a/slf4j-jdk14/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
+++ /dev/null
@@ -1,67 +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 org.slf4j.IMarkerFactory;
-import org.slf4j.MarkerFactory;
-import org.slf4j.helpers.BasicMarkerFactory;
-import org.slf4j.spi.MarkerFactoryBinder;
-
-/**
- *
- * The binding of {@link MarkerFactory} class with an actual instance of
- * {@link IMarkerFactory} is performed using information returned by this class.
- *
- * @author Ceki G&uuml;lc&uuml;
- */
-public class StaticMarkerBinder implements MarkerFactoryBinder {
-
- /**
- * The unique instance of this class.
- */
- public static final StaticMarkerBinder SINGLETON = new StaticMarkerBinder();
-
- final IMarkerFactory markerFactory = new BasicMarkerFactory();
-
- private StaticMarkerBinder() {
- }
-
- /**
- * Currently this method always returns an instance of
- * {@link BasicMarkerFactory}.
- */
- public IMarkerFactory getMarkerFactory() {
- return markerFactory;
- }
-
- /**
- * Currently, this method returns the class name of
- * {@link BasicMarkerFactory}.
- */
- public String getMarkerFactoryClassStr() {
- return BasicMarkerFactory.class.getName();
- }
-
-}
diff --git a/slf4j-jdk14/src/main/java/org/slf4j/jul/JDK14LoggerAdapter.java b/slf4j-jdk14/src/main/java/org/slf4j/jul/JDK14LoggerAdapter.java
new file mode 100755
index 00000000..dbc52da5
--- /dev/null
+++ b/slf4j-jdk14/src/main/java/org/slf4j/jul/JDK14LoggerAdapter.java
@@ -0,0 +1,298 @@
+/**
+ * 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.jul;
+
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+
+import org.slf4j.Logger;
+import org.slf4j.Marker;
+import org.slf4j.event.EventConstants;
+import org.slf4j.event.LoggingEvent;
+import org.slf4j.helpers.AbstractLogger;
+import org.slf4j.helpers.FormattingTuple;
+import org.slf4j.helpers.LegacyAbstractLogger;
+import org.slf4j.helpers.MessageFormatter;
+import org.slf4j.helpers.NormalizedParameters;
+import org.slf4j.helpers.SubstituteLogger;
+import org.slf4j.spi.DefaultLoggingEventBuilder;
+import org.slf4j.spi.LocationAwareLogger;
+
+/**
+ * A wrapper over {@link java.util.logging.Logger java.util.logging.Logger} in
+ * conformity with the {@link Logger} interface. Note that the logging levels
+ * mentioned in this class refer to those defined in the java.util.logging
+ * package.
+ *
+ * @author Ceki G&uuml;lc&uuml;
+ * @author Peter Royal
+ */
+public final class JDK14LoggerAdapter extends LegacyAbstractLogger implements LocationAwareLogger {
+
+ private static final long serialVersionUID = -8053026990503422791L;
+
+ transient final java.util.logging.Logger logger;
+
+ // WARN: JDK14LoggerAdapter constructor should have only package access so
+ // that only JDK14LoggerFactory be able to create one.
+ JDK14LoggerAdapter(java.util.logging.Logger logger) {
+ this.logger = logger;
+ this.name = logger.getName();
+ }
+
+ /**
+ * Is this logger instance enabled for the FINEST level?
+ *
+ * @return True if this Logger is enabled for level FINEST, false otherwise.
+ */
+ public boolean isTraceEnabled() {
+ return logger.isLoggable(Level.FINEST);
+ }
+
+ /**
+ * Is this logger instance enabled for the FINE level?
+ *
+ * @return True if this Logger is enabled for level FINE, false otherwise.
+ */
+ public boolean isDebugEnabled() {
+ return logger.isLoggable(Level.FINE);
+ }
+
+ /**
+ * Is this logger instance enabled for the INFO level?
+ *
+ * @return True if this Logger is enabled for the INFO level, false otherwise.
+ */
+ public boolean isInfoEnabled() {
+ return logger.isLoggable(Level.INFO);
+ }
+
+ /**
+ * Is this logger instance enabled for the WARNING level?
+ *
+ * @return True if this Logger is enabled for the WARNING level, false
+ * otherwise.
+ */
+ public boolean isWarnEnabled() {
+ return logger.isLoggable(Level.WARNING);
+ }
+
+ /**
+ * Is this logger instance enabled for level SEVERE?
+ *
+ * @return True if this Logger is enabled for level SEVERE, false otherwise.
+ */
+ public boolean isErrorEnabled() {
+ return logger.isLoggable(Level.SEVERE);
+ }
+
+ // /**
+ // * Log the message at the specified level with the specified throwable if any.
+ // * This method creates a LogRecord and fills in caller date before calling
+ // * this instance's JDK14 logger.
+ // *
+ // * See bug report #13 for more details.
+ // *
+ // * @param level
+ // * @param msg
+ // * @param t
+ // */
+ // private void log(String callerFQCN, Level level, String msg, Throwable t) {
+ // // millis and thread are filled by the constructor
+ // LogRecord record = new LogRecord(level, msg);
+ // record.setLoggerName(getName());
+ // record.setThrown(t);
+ // // Note: parameters in record are not set because SLF4J only
+ // // supports a single formatting style
+ // fillCallerData(callerFQCN, record);
+ // logger.log(record);
+ // }
+
+ /**
+ * Log the message at the specified level with the specified throwable if any.
+ * This method creates a LogRecord and fills in caller date before calling this
+ * instance's JDK14 logger.
+ */
+ @Override
+ protected void handleNormalizedLoggingCall(org.slf4j.event.Level level, Marker marker, String msg, Object[] args, Throwable throwable) {
+ innerNormalizedLoggingCallHandler(getFullyQualifiedCallerName(), level, marker, msg, args, throwable);
+ }
+
+ private void innerNormalizedLoggingCallHandler(String fqcn, org.slf4j.event.Level level, Marker marker, String msg, Object[] args, Throwable throwable) {
+ // millis and thread are filled by the constructor
+ Level julLevel = slf4jLevelToJULLevel(level);
+ String formattedMessage = MessageFormatter.basicArrayFormat(msg, args);
+ LogRecord record = new LogRecord(julLevel, formattedMessage);
+
+ // https://jira.qos.ch/browse/SLF4J-13
+ record.setLoggerName(getName());
+ record.setThrown(throwable);
+ // Note: parameters in record are not set because SLF4J only
+ // supports a single formatting style
+ // See also https://jira.qos.ch/browse/SLF4J-10
+ fillCallerData(fqcn, record);
+ logger.log(record);
+ }
+
+ @Override
+ protected String getFullyQualifiedCallerName() {
+ return SELF;
+ }
+
+ @Override
+ public void log(Marker marker, String callerFQCN, int slf4jLevelInt, String message, Object[] arguments, Throwable throwable) {
+
+ org.slf4j.event.Level slf4jLevel = org.slf4j.event.Level.intToLevel(slf4jLevelInt);
+ Level julLevel = slf4jLevelIntToJULLevel(slf4jLevelInt);
+
+ if (logger.isLoggable(julLevel)) {
+ NormalizedParameters np = NormalizedParameters.normalize(message, arguments, throwable);
+ innerNormalizedLoggingCallHandler(callerFQCN, slf4jLevel, marker, np.getMessage(), np.getArguments(), np.getThrowable());
+ }
+ }
+
+ /**
+ * Fill in caller data if possible.
+ *
+ * @param record The record to update
+ */
+ final private void fillCallerData(String callerFQCN, LogRecord record) {
+ StackTraceElement[] steArray = new Throwable().getStackTrace();
+
+ int selfIndex = -1;
+ for (int i = 0; i < steArray.length; i++) {
+ final String className = steArray[i].getClassName();
+
+ if (barrierMatch(callerFQCN, className)) {
+ selfIndex = i;
+ break;
+ }
+ }
+
+ int found = -1;
+ for (int i = selfIndex + 1; i < steArray.length; i++) {
+ final String className = steArray[i].getClassName();
+ if (!(barrierMatch(callerFQCN, className))) {
+ found = i;
+ break;
+ }
+ }
+
+ if (found != -1) {
+ StackTraceElement ste = steArray[found];
+ // setting the class name has the side effect of setting
+ // the needToInferCaller variable to false.
+ record.setSourceClassName(ste.getClassName());
+ record.setSourceMethodName(ste.getMethodName());
+ }
+ }
+
+ static String SELF = JDK14LoggerAdapter.class.getName();
+
+ static String SUPER = LegacyAbstractLogger.class.getName();
+ static String SUPER_OF_SUPER = AbstractLogger.class.getName();
+ static String SUBSTITUE = SubstituteLogger.class.getName();
+ static String FLUENT = DefaultLoggingEventBuilder.class.getName();
+
+ static String[] BARRIER_CLASSES = new String[] { SUPER_OF_SUPER, SUPER, SELF, SUBSTITUE, FLUENT };
+
+ private boolean barrierMatch(String callerFQCN, String candidateClassName) {
+ if (candidateClassName.equals(callerFQCN))
+ return true;
+ for (String barrierClassName : BARRIER_CLASSES) {
+ if (barrierClassName.equals(candidateClassName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static Level slf4jLevelIntToJULLevel(int levelInt) {
+ org.slf4j.event.Level slf4jLevel = org.slf4j.event.Level.intToLevel(levelInt);
+ return slf4jLevelToJULLevel(slf4jLevel);
+ }
+
+ private static Level slf4jLevelToJULLevel(org.slf4j.event.Level slf4jLevel) {
+ Level julLevel;
+ switch (slf4jLevel) {
+ case TRACE:
+ julLevel = Level.FINEST;
+ break;
+ case DEBUG:
+ julLevel = Level.FINE;
+ break;
+ case INFO:
+ julLevel = Level.INFO;
+ break;
+ case WARN:
+ julLevel = Level.WARNING;
+ break;
+ case ERROR:
+ julLevel = Level.SEVERE;
+ break;
+ default:
+ throw new IllegalStateException("Level " + slf4jLevel + " is not recognized.");
+ }
+ return julLevel;
+ }
+
+ /**
+ * @since 1.7.15
+ */
+ public void log(LoggingEvent event) {
+ // assumes that the invocation is made from a substitute logger
+ // this assumption might change in the future with the advent of a fluent API
+ Level julLevel = slf4jLevelToJULLevel(event.getLevel());
+ if (logger.isLoggable(julLevel)) {
+ 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/jul/JDK14LoggerFactory.java
index f251d987..bd314e0c 100644
--- a/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerFactory.java
+++ b/slf4j-jdk14/src/main/java/org/slf4j/jul/JDK14LoggerFactory.java
@@ -22,7 +22,7 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j.impl;
+package org.slf4j.jul;
import org.slf4j.Logger;
import org.slf4j.ILoggerFactory;
@@ -41,8 +41,17 @@ public class JDK14LoggerFactory implements ILoggerFactory {
// key: name (String), value: a JDK14LoggerAdapter;
ConcurrentMap<String, Logger> loggerMap;
+ /**
+ * the root logger is called "" in JUL
+ */
+ private static String JUL_ROOT_LOGGER_NAME = "";
+
public JDK14LoggerFactory() {
- loggerMap = new ConcurrentHashMap<String, Logger>();
+ loggerMap = new ConcurrentHashMap<>();
+ // 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("");
}
/*
@@ -53,7 +62,7 @@ public class JDK14LoggerFactory implements ILoggerFactory {
public Logger getLogger(String name) {
// the root logger is called "" in JUL
if (name.equalsIgnoreCase(Logger.ROOT_LOGGER_NAME)) {
- name = "";
+ name = JUL_ROOT_LOGGER_NAME;
}
Logger slf4jLogger = loggerMap.get(name);
diff --git a/slf4j-jdk14/src/main/java/org/slf4j/jul/JULServiceProvider.java b/slf4j-jdk14/src/main/java/org/slf4j/jul/JULServiceProvider.java
new file mode 100755
index 00000000..5e9a74ed
--- /dev/null
+++ b/slf4j-jdk14/src/main/java/org/slf4j/jul/JULServiceProvider.java
@@ -0,0 +1,48 @@
+package org.slf4j.jul;
+
+import org.slf4j.ILoggerFactory;
+import org.slf4j.IMarkerFactory;
+import org.slf4j.helpers.BasicMDCAdapter;
+import org.slf4j.helpers.BasicMarkerFactory;
+import org.slf4j.spi.MDCAdapter;
+import org.slf4j.spi.SLF4JServiceProvider;
+
+public class JULServiceProvider implements SLF4JServiceProvider {
+
+ /**
+ * Declare the version of the SLF4J API this implementation is compiled
+ * against. The value of this field is modified with each major release.
+ */
+ // to avoid constant folding by the compiler, this field must *not* be final
+ public static String REQUESTED_API_VERSION = "2.0.99"; // !final
+
+ private ILoggerFactory loggerFactory;
+ private IMarkerFactory markerFactory;
+ private MDCAdapter mdcAdapter;
+
+ @Override
+ public ILoggerFactory getLoggerFactory() {
+ return loggerFactory;
+ }
+
+ @Override
+ public IMarkerFactory getMarkerFactory() {
+ return markerFactory;
+ }
+
+ public MDCAdapter getMDCAdapter() {
+ return mdcAdapter;
+ }
+
+ @Override
+ public String getRequestedApiVersion() {
+ return REQUESTED_API_VERSION;
+ }
+
+ @Override
+ public void initialize() {
+ loggerFactory = new JDK14LoggerFactory();
+ markerFactory = new BasicMarkerFactory();
+ mdcAdapter = new BasicMDCAdapter();
+ }
+}
diff --git a/slf4j-jdk14/src/main/java9/module-info.java b/slf4j-jdk14/src/main/java9/module-info.java
new file mode 100755
index 00000000..5fdbdcf1
--- /dev/null
+++ b/slf4j-jdk14/src/main/java9/module-info.java
@@ -0,0 +1,9 @@
+module org.slf4j.jul {
+ requires org.slf4j;
+ requires java.logging;
+ provides org.slf4j.spi.SLF4JServiceProvider with org.slf4j.jul.JULServiceProvider;
+
+ exports org.slf4j.jul;
+ opens org.slf4j.jul to org.slf4j;
+}
+
diff --git a/slf4j-jdk14/src/main/resources/META-INF/MANIFEST.MF b/slf4j-jdk14/src/main/resources/META-INF/MANIFEST.MF
deleted file mode 100644
index bab3c6fe..00000000
--- a/slf4j-jdk14/src/main/resources/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,9 +0,0 @@
-Implementation-Title: slf4j-jdk14
-Bundle-ManifestVersion: 2
-Bundle-SymbolicName: slf4j.jdk14
-Bundle-Name: slf4j-jdk14
-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}
-Fragment-Host: slf4j.api \ No newline at end of file
diff --git a/slf4j-jdk14/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider b/slf4j-jdk14/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider
new file mode 100755
index 00000000..8d062b2f
--- /dev/null
+++ b/slf4j-jdk14/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider
@@ -0,0 +1 @@
+org.slf4j.jul.JULServiceProvider \ No newline at end of file
diff --git a/slf4j-jdk14/src/test/java/org/slf4j/impl/PerfTest.java b/slf4j-jdk14/src/test/java/org/slf4j/impl/PerfTest.java
deleted file mode 100644
index 3b77ab96..00000000
--- a/slf4j-jdk14/src/test/java/org/slf4j/impl/PerfTest.java
+++ /dev/null
@@ -1,76 +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 junit.framework.TestCase;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.slf4j.helpers.BogoPerf;
-
-public class PerfTest extends TestCase {
-
- static long REFERENCE_BIPS = 9000;
-
- public PerfTest(String name) {
- super(name);
- }
-
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testBug72() {
-
- int LEN = 1000 * 1000 * 10;
- debugLoop(LEN); // warm up
- double avg = debugLoop(LEN);
- long referencePerf = 93;
- BogoPerf.assertDuration(avg, referencePerf, REFERENCE_BIPS);
-
- // when the code is guarded by a logger.isLoggable condition,
- // duration is about 16 *micro*seconds for 1000 iterations
- // when it is not guarded the figure is 90 milliseconds,
- // i.e a ration of 1 to 5000
- }
-
- double debugLoop(int len) {
- Logger logger = LoggerFactory.getLogger(PerfTest.class);
- long start = System.currentTimeMillis();
- for (int i = 0; i < len; i++) {
- logger.debug("hello");
- }
-
- long end = System.currentTimeMillis();
-
- long duration = end - start;
- return duration;
- }
-
-}
diff --git a/slf4j-jdk14/src/test/java/org/slf4j/issue/CallerInfoTest.java b/slf4j-jdk14/src/test/java/org/slf4j/issue/CallerInfoTest.java
new file mode 100755
index 00000000..a94d4631
--- /dev/null
+++ b/slf4j-jdk14/src/test/java/org/slf4j/issue/CallerInfoTest.java
@@ -0,0 +1,122 @@
+package org.slf4j.issue;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+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;
+import org.slf4j.event.EventConstants;
+import org.slf4j.event.SubstituteLoggingEvent;
+import org.slf4j.helpers.SubstituteLogger;
+import org.slf4j.helpers.SubstituteServiceProvider;
+import org.slf4j.jul.ListHandler;
+
+public class CallerInfoTest {
+ Level oldLevel;
+ java.util.logging.Logger root = java.util.logging.Logger.getLogger("");
+
+ ListHandler listHandler = new ListHandler();
+
+ @Before
+ public void setUp() throws Exception {
+ oldLevel = root.getLevel();
+ root.setLevel(Level.FINE);
+ // removeAllHandlers(root);
+ root.addHandler(listHandler);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ root.setLevel(oldLevel);
+ removeListHandlers(root);
+ }
+
+ void removeListHandlers(java.util.logging.Logger logger) {
+ Handler[] handlers = logger.getHandlers();
+ for (Handler h : handlers) {
+ if (h instanceof ListHandler)
+ logger.removeHandler(h);
+ }
+ }
+
+ @Test
+ public void testCallerInfo() {
+ Logger logger = LoggerFactory.getLogger("bla");
+ logger.debug("hello");
+
+ List<LogRecord> recordList = listHandler.recordList;
+
+ assertEquals(1, recordList.size());
+
+ LogRecord logRecod = recordList.get(0);
+ assertEquals(this.getClass().getName(), logRecod.getSourceClassName());
+ }
+
+ // Do we preserve location info using fluent API?
+ // See https://jira.qos.ch/browse/SLF4J-511
+
+ @Test
+ public void testCallerInfoWithFluentAPI() {
+ Logger logger = LoggerFactory.getLogger("bla");
+ logger.atDebug().log("hello");
+
+ List<LogRecord> recordList = listHandler.recordList;
+
+ assertEquals(1, recordList.size());
+
+ LogRecord logRecod = recordList.get(0);
+ assertEquals(this.getClass().getName(), logRecod.getSourceClassName());
+ }
+
+ @Test
+ public void testPostInitializationCallerInfoWithSubstituteLogger() {
+ Logger logger = LoggerFactory.getLogger("bla");
+ SubstituteLogger substituteLogger = new SubstituteLogger("bla", null, false);
+ substituteLogger.setDelegate(logger);
+ substituteLogger.debug("hello");
+
+ List<LogRecord> recordList = listHandler.recordList;
+
+ assertEquals(1, recordList.size());
+
+ LogRecord logRecod = recordList.get(0);
+ assertEquals(CallerInfoTest.class.getName(), logRecod.getSourceClassName());
+ }
+
+ // In this case we KNOW that we CANNOT KNOW the caller
+ @Test
+ public void testIntraInitializationCallerInfoWithSubstituteLogger() throws InterruptedException {
+ SubstituteServiceProvider substituteServiceProvider = new SubstituteServiceProvider();
+ String loggerName = "bkla";
+ substituteServiceProvider.getLoggerFactory().getLogger(loggerName);
+ SubstituteLogger substituteLogger = substituteServiceProvider.getSubstituteLoggerFactory().getLoggers().get(0);
+ assertEquals(loggerName, substituteLogger.getName());
+
+ substituteLogger.debug("jello");
+ Logger logger = LoggerFactory.getLogger(loggerName);
+ substituteLogger.setDelegate(logger);
+
+ final LinkedBlockingQueue<SubstituteLoggingEvent> queue = substituteServiceProvider.getSubstituteLoggerFactory().getEventQueue();
+
+ SubstituteLoggingEvent substituteLoggingEvent = queue.take();
+ assertTrue(substituteLogger.isDelegateEventAware());
+ substituteLogger.log(substituteLoggingEvent);
+
+ List<LogRecord> recordList = listHandler.recordList;
+
+ assertEquals(1, recordList.size());
+
+ LogRecord logRecod = recordList.get(0);
+ assertEquals(EventConstants.NA_SUBST, logRecod.getSourceClassName());
+ }
+
+}
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 bb9b8745..a8139d85 100644
--- a/slf4j-jdk14/src/test/java/org/slf4j/issue/LoggerSerializationTest.java
+++ b/slf4j-jdk14/src/test/java/org/slf4j/issue/LoggerSerializationTest.java
@@ -32,22 +32,22 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
-import junit.framework.Assert;
+import static org.junit.Assert.assertNotNull;
-import junit.framework.TestCase;
+import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * See http://bugzilla.slf4j.org/show_bug.cgi?id=261
+ * See http://jira.qos.ch/browse/SLF4J-252
* @author Thorbjorn Ravn Andersen
*/
-public class LoggerSerializationTest extends TestCase {
+public class LoggerSerializationTest {
static class LoggerHolder implements Serializable {
private static final long serialVersionUID = 1L;
- private Logger log = LoggerFactory.getLogger(LoggerHolder.class);
+ private final Logger log = LoggerFactory.getLogger(LoggerHolder.class);
public String toString() {
return "log=" + getLog();
@@ -58,6 +58,7 @@ public class LoggerSerializationTest extends TestCase {
}
}
+ @Test
public void testCanLoggerBeSerialized() throws IOException, ClassNotFoundException {
LoggerHolder lh1 = new LoggerHolder();
@@ -75,8 +76,8 @@ public class LoggerSerializationTest extends TestCase {
ObjectInputStream in = new ObjectInputStream(is);
LoggerHolder lh2 = (LoggerHolder) in.readObject();
- Assert.assertNotNull(lh2);
- Assert.assertNotNull(lh2.getLog());
+ assertNotNull(lh2);
+ assertNotNull(lh2.getLog());
lh2.getLog().info("You must see this message as a log message");
}
diff --git a/slf4j-jdk14/src/test/java/org/slf4j/jul/CountingHandler.java b/slf4j-jdk14/src/test/java/org/slf4j/jul/CountingHandler.java
new file mode 100644
index 00000000..ea31174b
--- /dev/null
+++ b/slf4j-jdk14/src/test/java/org/slf4j/jul/CountingHandler.java
@@ -0,0 +1,24 @@
+package org.slf4j.jul;
+
+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/jul/FluentApiInvocationTest.java b/slf4j-jdk14/src/test/java/org/slf4j/jul/FluentApiInvocationTest.java
new file mode 100755
index 00000000..dc37ac21
--- /dev/null
+++ b/slf4j-jdk14/src/test/java/org/slf4j/jul/FluentApiInvocationTest.java
@@ -0,0 +1,144 @@
+package org.slf4j.jul;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.function.Supplier;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FluentApiInvocationTest {
+
+ ListHandler listHandler = new ListHandler();
+ java.util.logging.Logger root = java.util.logging.Logger.getLogger("");
+ Level oldLevel;
+ Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ @Before
+ public void setUp() throws Exception {
+ oldLevel = root.getLevel();
+ root.setLevel(Level.FINE);
+ // removeAllHandlers(root);
+ root.addHandler(listHandler);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ root.setLevel(oldLevel);
+ removeListHandlers(root);
+ }
+
+ void removeListHandlers(java.util.logging.Logger logger) {
+ Handler[] handlers = logger.getHandlers();
+ for (Handler h : handlers) {
+ if (h instanceof ListHandler)
+ logger.removeHandler(h);
+ }
+ }
+
+ @Test
+ public void singleMessage() {
+ String msg = "Hello world.";
+ logger.atDebug().log(msg);
+ assertLogMessage(msg, 0);
+ }
+
+ @Test
+ public void messageWithArguments() {
+ String msg = "Hello {}.";
+ logger.atDebug().addArgument("world").log(msg);
+ assertLogMessage("Hello world.", 0);
+ }
+
+ @Test
+ public void messageWithTwoArguments() {
+ int old = 15;
+ int t = 16;
+
+ {
+ String msg = "Temperature set to {}. Old temperature was {}.";
+ logger.atDebug().addArgument(t).addArgument(old).log(msg);
+ assertLogMessage("Temperature set to 16. Old temperature was 15.", 0);
+ }
+
+ {
+ String msg = "Temperature set to {}. Old temperature was {}.";
+ logger.atDebug().log(msg, t, old);
+ assertLogMessage("Temperature set to 16. Old temperature was 15.", 0);
+ }
+
+ {
+ String msg = "Temperature set to {}. Old temperature was {}.";
+ logger.atDebug().addArgument(t).log(msg, old);
+ assertLogMessage("Temperature set to 16. Old temperature was 15.", 0);
+ }
+
+ {
+ String msg = "Temperature set to {}. Old temperature was {}.";
+ logger.atDebug().addArgument(() -> t16()).log(msg, old);
+ assertLogMessage("Temperature set to 16. Old temperature was 15.", 0);
+ }
+ }
+
+ @Test
+ public void supplierArguments() {
+ Supplier<String> stringSupplier = () -> "world";
+ logger.atInfo().addArgument(stringSupplier).log("hello {}");
+ assertLogMessage("hello world", 0);
+ }
+
+ public int t16() {
+ return 16;
+ }
+
+ @Test
+ public void messageWithThrowable() {
+ String msg = "Hello world.";
+ Throwable t = new IllegalStateException();
+ logger.atDebug().setCause(t).log(msg);
+ assertLogMessage("Hello world.", 0);
+ assertThrowable(t, 0);
+ }
+
+ @Test
+ public void messageWithArgumentsAndThrowable() {
+ String msg = "Hello {}.";
+ Throwable t = new IllegalStateException();
+
+ logger.atDebug().setCause(t).addArgument("world").log(msg);
+ assertLogMessage("Hello world.", 0);
+ assertThrowable(t, 0);
+ }
+
+ @Test
+ public void messageWithKeyValuePair() {
+ String msg = "Hello world.";
+ logger.atDebug().addKeyValue("k", "v").log(msg);
+ assertLogMessage("k=v Hello world.", 0);
+
+ int oldT = 15;
+ int newT = 16;
+ logger.atDebug().addKeyValue("oldT", oldT).addKeyValue("newT", newT).log("Temperature changed.");
+ assertLogMessage("oldT=15 newT=16 Temperature changed.", 1);
+
+ }
+
+ private void assertLogMessage(String expected, int index) {
+ LogRecord logRecord = listHandler.recordList.get(index);
+ Assert.assertNotNull(logRecord);
+ assertEquals(expected, logRecord.getMessage());
+ }
+
+ private void assertThrowable(Throwable expected, int index) {
+ LogRecord logRecord = listHandler.recordList.get(index);
+ Assert.assertNotNull(logRecord);
+ assertEquals(expected, logRecord.getThrown());
+ }
+}
diff --git a/slf4j-jdk14/src/test/java/org/slf4j/InvocationTest.java b/slf4j-jdk14/src/test/java/org/slf4j/jul/InvocationTest.java
index da76fab3..22669c2b 100755
--- a/slf4j-jdk14/src/test/java/org/slf4j/InvocationTest.java
+++ b/slf4j-jdk14/src/test/java/org/slf4j/jul/InvocationTest.java
@@ -22,21 +22,20 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j;
+package org.slf4j.jul;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import org.slf4j.*;
-import java.util.ArrayList;
-import java.util.List;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
@@ -66,8 +65,16 @@ public class InvocationTest {
removeListHandlers(root);
}
+ void removeListHandlers(java.util.logging.Logger logger) {
+ Handler[] handlers = logger.getHandlers();
+ for (Handler h : handlers) {
+ if (h instanceof ListHandler)
+ logger.removeHandler(h);
+ }
+ }
+
@Test
- public void test1() {
+ public void smoke() {
Logger logger = LoggerFactory.getLogger("test1");
logger.debug("Hello world.");
assertLogMessage("Hello world.", 0);
@@ -75,9 +82,9 @@ public class InvocationTest {
@Test
public void verifyMessageFormatting() {
- Integer i1 = new Integer(1);
- Integer i2 = new Integer(2);
- Integer i3 = new Integer(3);
+ Integer i1 = Integer.valueOf(1);
+ Integer i2 = Integer.valueOf(2);
+ Integer i3 = Integer.valueOf(3);
Exception e = new Exception("This is a test exception.");
Logger logger = LoggerFactory.getLogger("test2");
@@ -103,7 +110,7 @@ public class InvocationTest {
logger.warn("Hello world 3", e);
logger.error("Hello world 4.");
- logger.error("Hello world {}", new Integer(3));
+ logger.error("Hello world {}", Integer.valueOf(3));
logger.error("Hello world 4.", e);
}
@@ -175,29 +182,4 @@ public class InvocationTest {
assertEquals(exceptionType, logRecord.getThrown().getClass());
}
- void removeListHandlers(java.util.logging.Logger logger) {
- Handler[] handlers = logger.getHandlers();
- for (Handler h : handlers) {
- if (h instanceof ListHandler)
- logger.removeHandler(h);
- }
- }
-
- static private class ListHandler extends java.util.logging.Handler {
-
- List<LogRecord> recordList = new ArrayList<LogRecord>();
-
- @Override
- public void publish(LogRecord record) {
- recordList.add(record);
- }
-
- @Override
- public void flush() {
- }
-
- @Override
- public void close() throws SecurityException {
- }
- }
}
diff --git a/slf4j-jdk14/src/test/java/org/slf4j/impl/JDK14AdapterLoggerNameTest.java b/slf4j-jdk14/src/test/java/org/slf4j/jul/JDK14AdapterLoggerNameTest.java
index e3cbbd25..8b263c58 100644
--- a/slf4j-jdk14/src/test/java/org/slf4j/impl/JDK14AdapterLoggerNameTest.java
+++ b/slf4j-jdk14/src/test/java/org/slf4j/jul/JDK14AdapterLoggerNameTest.java
@@ -22,48 +22,63 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j.impl;
+package org.slf4j.jul;
+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;
-import junit.framework.TestCase;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
-public class JDK14AdapterLoggerNameTest extends TestCase {
+public class JDK14AdapterLoggerNameTest {
private MockHandler mockHandler;
+ static Random random = new Random(System.currentTimeMillis());
+ long diff = random.nextInt(10000);
+ String loggerName = "JDK14AdapterLoggerNameTest" + diff;
- protected void setUp() throws Exception {
- super.setUp();
- Logger logger = Logger.getLogger("TEST");
- mockHandler = new MockHandler();
- removeHandlers(logger);
- logger.addHandler(mockHandler);
+ Logger logger = Logger.getLogger(loggerName);
+
+ @Before
+ public void setUp() throws Exception {
+ Logger logger = Logger.getLogger(loggerName);
+ addMockHandler(logger);
}
- protected void tearDown() throws Exception {
- removeHandlers(Logger.getLogger("TEST"));
- super.tearDown();
+ @After
+ public void tearDown() throws Exception {
+ removeHandlers(Logger.getLogger(loggerName));
}
- public void testLoggerNameusingJdkLogging() throws Exception {
- Logger.getLogger("TEST").info("test message");
+ @Test
+ 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();
- for (int i = 0; i < handlers.length; i++) {
- logger.removeHandler(handlers[i]);
+ for (Handler handler : handlers) {
+ logger.removeHandler(handler);
}
}
@@ -72,7 +87,7 @@ public class JDK14AdapterLoggerNameTest extends TestCase {
assertNotNull("missing logger name", mockHandler.record.getLoggerName());
}
- private class MockHandler extends java.util.logging.Handler {
+ private static class MockHandler extends java.util.logging.Handler {
public LogRecord record;
public void close() throws SecurityException {
diff --git a/slf4j-jdk14/src/test/java/org/slf4j/jul/JDK14MultithreadedInitializationTest.java b/slf4j-jdk14/src/test/java/org/slf4j/jul/JDK14MultithreadedInitializationTest.java
new file mode 100644
index 00000000..3211f901
--- /dev/null
+++ b/slf4j-jdk14/src/test/java/org/slf4j/jul/JDK14MultithreadedInitializationTest.java
@@ -0,0 +1,77 @@
+/**
+ * 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.jul;
+
+import static org.junit.Assert.fail;
+
+import java.util.logging.Handler;
+
+import org.junit.After;
+import org.junit.Before;
+import org.slf4j.testHarness.MultithreadedInitializationTest;
+
+public class JDK14MultithreadedInitializationTest extends MultithreadedInitializationTest {
+
+ 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 (Handler handler : handlers) {
+ logger.removeHandler(handler);
+ }
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ removeAllHandlers(julOrgLogger);
+ }
+
+ protected 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;
+ }
+
+}
diff --git a/slf4j-jdk14/src/test/java/org/slf4j/jul/ListHandler.java b/slf4j-jdk14/src/test/java/org/slf4j/jul/ListHandler.java
new file mode 100755
index 00000000..d1ac5f49
--- /dev/null
+++ b/slf4j-jdk14/src/test/java/org/slf4j/jul/ListHandler.java
@@ -0,0 +1,23 @@
+package org.slf4j.jul;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.LogRecord;
+
+public class ListHandler extends java.util.logging.Handler {
+
+ public List<LogRecord> recordList = new ArrayList<>();
+
+ @Override
+ public void publish(LogRecord record) {
+ recordList.add(record);
+ }
+
+ @Override
+ public void flush() {
+ }
+
+ @Override
+ public void close() throws SecurityException {
+ }
+} \ No newline at end of file
diff --git a/slf4j-log4j12/LICENSE.txt b/slf4j-log4j12/LICENSE.txt
index 508a2728..e4079f54 100644
--- a/slf4j-log4j12/LICENSE.txt
+++ b/slf4j-log4j12/LICENSE.txt
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2007 QOS.ch
+Copyright (c) 2004-2023 QOS.ch
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/slf4j-log4j12/pom.xml b/slf4j-log4j12/pom.xml
index d7aad90f..8ba89b56 100755
--- a/slf4j-log4j12/pom.xml
+++ b/slf4j-log4j12/pom.xml
@@ -1,53 +1,32 @@
-<project
- xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
- <version>1.7.13-SNAPSHOT</version>
+ <version>2.0.12</version>
+ <relativePath>../parent/pom.xml</relativePath>
</parent>
-
+
<artifactId>slf4j-log4j12</artifactId>
-
- <packaging>jar</packaging>
- <name>SLF4J LOG4J-12 Binding</name>
- <description>SLF4J LOG4J-12 Binding</description>
+ <packaging>pom</packaging>
+
+ <name>SLF4J LOG4J-12 Binding relocated</name>
+ <description>SLF4J LOG4J-12 relocated to slf4j-reload4j</description>
<url>http://www.slf4j.org</url>
- <dependencies>
- <dependency>
+ <distributionManagement>
+ <relocation>
<groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- </dependency>
- </dependencies>
+ <artifactId>slf4j-reload4j</artifactId>
+ <version>2.0.12</version>
+ </relocation>
+ </distributionManagement>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <archive>
- <manifestEntries>
- <Bundle-Version>${parsedVersion.osgiVersion}</Bundle-Version>
- <Bundle-Description>${project.description}</Bundle-Description>
- <Implementation-Version>${project.version}</Implementation-Version>
- </manifestEntries>
- <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
- </archive>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project> \ No newline at end of file
+</project>
diff --git a/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerAdapter.java b/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerAdapter.java
deleted file mode 100755
index 08d3ea0e..00000000
--- a/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerAdapter.java
+++ /dev/null
@@ -1,598 +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 java.io.Serializable;
-
-import org.apache.log4j.Level;
-import org.slf4j.Logger;
-import org.slf4j.Marker;
-import org.slf4j.helpers.FormattingTuple;
-import org.slf4j.helpers.MarkerIgnoringBase;
-import org.slf4j.helpers.MessageFormatter;
-import org.slf4j.spi.LocationAwareLogger;
-
-/**
- * A wrapper over {@link org.apache.log4j.Logger org.apache.log4j.Logger} in
- * conforming to the {@link Logger} interface.
- *
- * <p>
- * Note that the logging levels mentioned in this class refer to those defined
- * in the <a
- * href="http://logging.apache.org/log4j/docs/api/org/apache/log4j/Level.html">
- * <code>org.apache.log4j.Level</code></a> class.
- *
- * <p>
- * The TRACE level was introduced in log4j version 1.2.12. In order to avoid
- * crashing the host application, in the case the log4j version in use predates
- * 1.2.12, the TRACE level will be mapped as DEBUG. See also <a
- * href="http://bugzilla.slf4j.org/show_bug.cgi?id=68">bug 68</a>.
- *
- * @author Ceki G&uuml;lc&uuml;
- */
-public final class Log4jLoggerAdapter extends MarkerIgnoringBase implements LocationAwareLogger, Serializable {
-
- private static final long serialVersionUID = 6182834493563598289L;
-
- final transient org.apache.log4j.Logger logger;
-
- /**
- * Following the pattern discussed in pages 162 through 168 of "The complete
- * log4j manual".
- */
- final static String FQCN = Log4jLoggerAdapter.class.getName();
-
- // Does the log4j version in use recognize the TRACE level?
- // The trace level was introduced in log4j 1.2.12.
- final boolean traceCapable;
-
- // WARN: Log4jLoggerAdapter constructor should have only package access so
- // that
- // only Log4jLoggerFactory be able to create one.
- Log4jLoggerAdapter(org.apache.log4j.Logger logger) {
- this.logger = logger;
- this.name = logger.getName();
- traceCapable = isTraceCapable();
- }
-
- private boolean isTraceCapable() {
- try {
- logger.isTraceEnabled();
- return true;
- } catch (NoSuchMethodError e) {
- return false;
- }
- }
-
- /**
- * Is this logger instance enabled for the TRACE level?
- *
- * @return True if this Logger is enabled for level TRACE, false otherwise.
- */
- public boolean isTraceEnabled() {
- if (traceCapable) {
- return logger.isTraceEnabled();
- } else {
- return logger.isDebugEnabled();
- }
- }
-
- /**
- * Log a message object at level TRACE.
- *
- * @param msg
- * - the message object to be logged
- */
- public void trace(String msg) {
- logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, msg, null);
- }
-
- /**
- * Log a message at level TRACE according to the specified format and
- * argument.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for level TRACE.
- * </p>
- *
- * @param format
- * the format string
- * @param arg
- * the argument
- */
- public void trace(String format, Object arg) {
- if (isTraceEnabled()) {
- FormattingTuple ft = MessageFormatter.format(format, arg);
- logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log a message at level TRACE according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the TRACE level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg1
- * the first argument
- * @param arg2
- * the second argument
- */
- public void trace(String format, Object arg1, Object arg2) {
- if (isTraceEnabled()) {
- FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
- logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log a message at level TRACE according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the TRACE level.
- * </p>
- *
- * @param format
- * the format string
- * @param arguments
- * an array of arguments
- */
- public void trace(String format, Object... arguments) {
- if (isTraceEnabled()) {
- FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
- logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log an exception (throwable) at level TRACE with an accompanying message.
- *
- * @param msg
- * the message accompanying the exception
- * @param t
- * the exception (throwable) to log
- */
- public void trace(String msg, Throwable t) {
- logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, msg, t);
- }
-
- /**
- * Is this logger instance enabled for the DEBUG level?
- *
- * @return True if this Logger is enabled for level DEBUG, false otherwise.
- */
- public boolean isDebugEnabled() {
- return logger.isDebugEnabled();
- }
-
- /**
- * Log a message object at level DEBUG.
- *
- * @param msg
- * - the message object to be logged
- */
- public void debug(String msg) {
- logger.log(FQCN, Level.DEBUG, msg, null);
- }
-
- /**
- * Log a message at level DEBUG according to the specified format and
- * argument.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for level DEBUG.
- * </p>
- *
- * @param format
- * the format string
- * @param arg
- * the argument
- */
- public void debug(String format, Object arg) {
- if (logger.isDebugEnabled()) {
- FormattingTuple ft = MessageFormatter.format(format, arg);
- logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log a message at level DEBUG according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the DEBUG level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg1
- * the first argument
- * @param arg2
- * the second argument
- */
- public void debug(String format, Object arg1, Object arg2) {
- if (logger.isDebugEnabled()) {
- FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
- logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log a message at level DEBUG according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the DEBUG level.
- * </p>
- *
- * @param format
- * the format string
- * @param arguments an array of arguments
- */
- public void debug(String format, Object... arguments) {
- if (logger.isDebugEnabled()) {
- FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
- logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log an exception (throwable) at level DEBUG with an accompanying message.
- *
- * @param msg
- * the message accompanying the exception
- * @param t
- * the exception (throwable) to log
- */
- public void debug(String msg, Throwable t) {
- logger.log(FQCN, Level.DEBUG, msg, t);
- }
-
- /**
- * Is this logger instance enabled for the INFO level?
- *
- * @return True if this Logger is enabled for the INFO level, false otherwise.
- */
- public boolean isInfoEnabled() {
- return logger.isInfoEnabled();
- }
-
- /**
- * Log a message object at the INFO level.
- *
- * @param msg
- * - the message object to be logged
- */
- public void info(String msg) {
- logger.log(FQCN, Level.INFO, msg, null);
- }
-
- /**
- * Log a message at level INFO according to the specified format and argument.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the INFO level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg
- * the argument
- */
- public void info(String format, Object arg) {
- if (logger.isInfoEnabled()) {
- FormattingTuple ft = MessageFormatter.format(format, arg);
- logger.log(FQCN, Level.INFO, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log a message at the INFO level according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the INFO level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg1
- * the first argument
- * @param arg2
- * the second argument
- */
- public void info(String format, Object arg1, Object arg2) {
- if (logger.isInfoEnabled()) {
- FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
- logger.log(FQCN, Level.INFO, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log a message at level INFO according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the INFO level.
- * </p>
- *
- * @param format
- * the format string
- * @param argArray
- * an array of arguments
- */
- public void info(String format, Object... argArray) {
- if (logger.isInfoEnabled()) {
- FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
- logger.log(FQCN, Level.INFO, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log an exception (throwable) at the INFO level with an accompanying
- * message.
- *
- * @param msg
- * the message accompanying the exception
- * @param t
- * the exception (throwable) to log
- */
- public void info(String msg, Throwable t) {
- logger.log(FQCN, Level.INFO, msg, t);
- }
-
- /**
- * Is this logger instance enabled for the WARN level?
- *
- * @return True if this Logger is enabled for the WARN level, false otherwise.
- */
- public boolean isWarnEnabled() {
- return logger.isEnabledFor(Level.WARN);
- }
-
- /**
- * Log a message object at the WARN level.
- *
- * @param msg
- * - the message object to be logged
- */
- public void warn(String msg) {
- logger.log(FQCN, Level.WARN, msg, null);
- }
-
- /**
- * Log a message at the WARN level according to the specified format and
- * argument.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the WARN level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg
- * the argument
- */
- public void warn(String format, Object arg) {
- if (logger.isEnabledFor(Level.WARN)) {
- FormattingTuple ft = MessageFormatter.format(format, arg);
- logger.log(FQCN, Level.WARN, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log a message at the WARN level according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the WARN level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg1
- * the first argument
- * @param arg2
- * the second argument
- */
- public void warn(String format, Object arg1, Object arg2) {
- if (logger.isEnabledFor(Level.WARN)) {
- FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
- logger.log(FQCN, Level.WARN, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log a message at level WARN according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the WARN level.
- * </p>
- *
- * @param format
- * the format string
- * @param argArray
- * an array of arguments
- */
- public void warn(String format, Object... argArray) {
- if (logger.isEnabledFor(Level.WARN)) {
- FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
- logger.log(FQCN, Level.WARN, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log an exception (throwable) at the WARN level with an accompanying
- * message.
- *
- * @param msg
- * the message accompanying the exception
- * @param t
- * the exception (throwable) to log
- */
- public void warn(String msg, Throwable t) {
- logger.log(FQCN, Level.WARN, msg, t);
- }
-
- /**
- * Is this logger instance enabled for level ERROR?
- *
- * @return True if this Logger is enabled for level ERROR, false otherwise.
- */
- public boolean isErrorEnabled() {
- return logger.isEnabledFor(Level.ERROR);
- }
-
- /**
- * Log a message object at the ERROR level.
- *
- * @param msg
- * - the message object to be logged
- */
- public void error(String msg) {
- logger.log(FQCN, Level.ERROR, msg, null);
- }
-
- /**
- * Log a message at the ERROR level according to the specified format and
- * argument.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the ERROR level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg
- * the argument
- */
- public void error(String format, Object arg) {
- if (logger.isEnabledFor(Level.ERROR)) {
- FormattingTuple ft = MessageFormatter.format(format, arg);
- logger.log(FQCN, Level.ERROR, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log a message at the ERROR level according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the ERROR level.
- * </p>
- *
- * @param format
- * the format string
- * @param arg1
- * the first argument
- * @param arg2
- * the second argument
- */
- public void error(String format, Object arg1, Object arg2) {
- if (logger.isEnabledFor(Level.ERROR)) {
- FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
- logger.log(FQCN, Level.ERROR, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log a message at level ERROR according to the specified format and
- * arguments.
- *
- * <p>
- * This form avoids superfluous object creation when the logger is disabled
- * for the ERROR level.
- * </p>
- *
- * @param format
- * the format string
- * @param argArray
- * an array of arguments
- */
- public void error(String format, Object... argArray) {
- if (logger.isEnabledFor(Level.ERROR)) {
- FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
- logger.log(FQCN, Level.ERROR, ft.getMessage(), ft.getThrowable());
- }
- }
-
- /**
- * Log an exception (throwable) at the ERROR level with an accompanying
- * message.
- *
- * @param msg
- * the message accompanying the exception
- * @param t
- * the exception (throwable) to log
- */
- public void error(String msg, Throwable t) {
- logger.log(FQCN, Level.ERROR, msg, t);
- }
-
- public void log(Marker marker, String callerFQCN, int level, String msg, Object[] argArray, Throwable t) {
- Level log4jLevel;
- switch (level) {
- case LocationAwareLogger.TRACE_INT:
- log4jLevel = traceCapable ? Level.TRACE : Level.DEBUG;
- break;
- case LocationAwareLogger.DEBUG_INT:
- log4jLevel = Level.DEBUG;
- break;
- case LocationAwareLogger.INFO_INT:
- log4jLevel = Level.INFO;
- break;
- case LocationAwareLogger.WARN_INT:
- log4jLevel = Level.WARN;
- break;
- case LocationAwareLogger.ERROR_INT:
- log4jLevel = Level.ERROR;
- break;
- default:
- throw new IllegalStateException("Level number " + level + " is not recognized.");
- }
- logger.log(callerFQCN, log4jLevel, msg, t);
- }
-
-}
diff --git a/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
deleted file mode 100644
index 081f28a6..00000000
--- a/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
+++ /dev/null
@@ -1,88 +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 org.apache.log4j.Level;
-import org.slf4j.ILoggerFactory;
-import org.slf4j.LoggerFactory;
-import org.slf4j.helpers.Util;
-import org.slf4j.spi.LoggerFactoryBinder;
-
-/**
- * The binding of {@link LoggerFactory} class with an actual instance of
- * {@link ILoggerFactory} is performed using information returned by this class.
- *
- * @author Ceki G&uuml;lc&uuml;
- */
-public class StaticLoggerBinder implements LoggerFactoryBinder {
-
- /**
- * The unique instance of this class.
- *
- */
- private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
-
- /**
- * Return the singleton of this class.
- *
- * @return the StaticLoggerBinder singleton
- */
- public static final StaticLoggerBinder getSingleton() {
- return SINGLETON;
- }
-
- /**
- * Declare the version of the SLF4J API this implementation is compiled
- * against. The value of this field is usually modified with each release.
- */
- // to avoid constant folding by the compiler, this field must *not* be final
- public static String REQUESTED_API_VERSION = "1.6.99"; // !final
-
- private static final String loggerFactoryClassStr = Log4jLoggerFactory.class.getName();
-
- /**
- * The ILoggerFactory instance returned by the {@link #getLoggerFactory}
- * method should always be the same object
- */
- private final ILoggerFactory loggerFactory;
-
- private StaticLoggerBinder() {
- loggerFactory = new Log4jLoggerFactory();
- try {
- @SuppressWarnings("unused")
- Level level = Level.TRACE;
- } catch (NoSuchFieldError nsfe) {
- Util.report("This version of SLF4J requires log4j version 1.2.12 or later. See also http://www.slf4j.org/codes.html#log4j_version");
- }
- }
-
- public ILoggerFactory getLoggerFactory() {
- return loggerFactory;
- }
-
- public String getLoggerFactoryClassStr() {
- return loggerFactoryClassStr;
- }
-}
diff --git a/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMarkerBinder.java b/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
deleted file mode 100644
index 1d255230..00000000
--- a/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
+++ /dev/null
@@ -1,67 +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 org.slf4j.IMarkerFactory;
-import org.slf4j.MarkerFactory;
-import org.slf4j.helpers.BasicMarkerFactory;
-import org.slf4j.spi.MarkerFactoryBinder;
-
-/**
- *
- * The binding of {@link MarkerFactory} class with an actual instance of
- * {@link IMarkerFactory} is performed using information returned by this class.
- *
- * @author Ceki G&uuml;lc&uuml;
- */
-public class StaticMarkerBinder implements MarkerFactoryBinder {
-
- /**
- * The unique instance of this class.
- */
- public static final StaticMarkerBinder SINGLETON = new StaticMarkerBinder();
-
- final IMarkerFactory markerFactory = new BasicMarkerFactory();
-
- private StaticMarkerBinder() {
- }
-
- /**
- * Currently this method always returns an instance of
- * {@link BasicMarkerFactory}.
- */
- public IMarkerFactory getMarkerFactory() {
- return markerFactory;
- }
-
- /**
- * Currently, this method returns the class name of
- * {@link BasicMarkerFactory}.
- */
- public String getMarkerFactoryClassStr() {
- return BasicMarkerFactory.class.getName();
- }
-
-}
diff --git a/slf4j-log4j12/src/main/resources/META-INF/MANIFEST.MF b/slf4j-log4j12/src/main/resources/META-INF/MANIFEST.MF
deleted file mode 100644
index 23a42952..00000000
--- a/slf4j-log4j12/src/main/resources/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,9 +0,0 @@
-Implementation-Title: slf4j-log4j12
-Bundle-ManifestVersion: 2
-Bundle-SymbolicName: slf4j.log4j12
-Bundle-Name: slf4j-log4j12
-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
-Fragment-Host: slf4j.api \ No newline at end of file
diff --git a/slf4j-migrator/LICENSE.txt b/slf4j-migrator/LICENSE.txt
new file mode 100644
index 00000000..1a3d0532
--- /dev/null
+++ b/slf4j-migrator/LICENSE.txt
@@ -0,0 +1,24 @@
+Copyright (c) 2004-2022 QOS.ch Sarl (Switzerland)
+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.
+
+
+
diff --git a/slf4j-migrator/pom.xml b/slf4j-migrator/pom.xml
index 33ad8e98..98ef9ddb 100755
--- a/slf4j-migrator/pom.xml
+++ b/slf4j-migrator/pom.xml
@@ -1,14 +1,14 @@
-<project
- xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
- <version>1.7.13-SNAPSHOT</version>
+ <version>2.0.12</version>
+ <relativePath>../parent/pom.xml</relativePath>
</parent>
<artifactId>slf4j-migrator</artifactId>
@@ -17,30 +17,23 @@
<name>SLF4J Migrator</name>
<description>SLF4J Migrator</description>
-
<build>
<plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <source>${required.jdk.version}</source>
- <target>${required.jdk.version}</target>
- </configuration>
- </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
+ <version>${maven-jar-plugin.version}</version>
<configuration>
<archive>
- <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+ <manifest>
+ <mainClass>org.slf4j.migrator.Main</mainClass>
+ </manifest>
</archive>
</configuration>
</plugin>
</plugins>
-
</build>
-</project> \ No newline at end of file
+</project>
diff --git a/slf4j-migrator/src/main/java/org/slf4j/migrator/FileSelector.java b/slf4j-migrator/src/main/java/org/slf4j/migrator/FileSelector.java
index 71af29bd..0e8d13c8 100644
--- a/slf4j-migrator/src/main/java/org/slf4j/migrator/FileSelector.java
+++ b/slf4j-migrator/src/main/java/org/slf4j/migrator/FileSelector.java
@@ -32,7 +32,7 @@ import org.slf4j.migrator.internal.ProgressListener;
public class FileSelector {
- private List<File> javaFileList = new ArrayList<File>();
+ private final List<File> javaFileList = new ArrayList<>();
ProgressListener pl;
@@ -54,8 +54,8 @@ public class FileSelector {
pl.onDirectory(file);
File[] files = file.listFiles();
if (files != null) {
- for (int i = 0; i < files.length; i++) {
- selectFiles(files[i]);
+ for (File value : files) {
+ selectFiles(value);
}
}
} else {
diff --git a/slf4j-migrator/src/main/java/org/slf4j/migrator/InplaceFileConverter.java b/slf4j-migrator/src/main/java/org/slf4j/migrator/InplaceFileConverter.java
index d4bf3e63..cecb1be8 100644
--- a/slf4j-migrator/src/main/java/org/slf4j/migrator/InplaceFileConverter.java
+++ b/slf4j-migrator/src/main/java/org/slf4j/migrator/InplaceFileConverter.java
@@ -102,8 +102,8 @@ public class InplaceFileConverter {
}
private void writeReplacement(OutputStream os, String[] replacement) throws IOException {
- for (int i = 0; i < replacement.length; i++) {
- os.write(replacement[i].getBytes());
+ for (String s : replacement) {
+ os.write(s.getBytes());
os.write(lineTerminator.getBytes());
}
}
diff --git a/slf4j-migrator/src/main/java/org/slf4j/migrator/Main.java b/slf4j-migrator/src/main/java/org/slf4j/migrator/Main.java
index 5a94a41d..bbb1b9cc 100644
--- a/slf4j-migrator/src/main/java/org/slf4j/migrator/Main.java
+++ b/slf4j-migrator/src/main/java/org/slf4j/migrator/Main.java
@@ -38,12 +38,10 @@ public class Main {
public static void main(String[] args) {
System.out.println("Starting SLF4J Migrator");
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- MigratorFrame inst = new MigratorFrame();
- inst.setLocationRelativeTo(null);
- inst.setVisible(true);
- }
+ SwingUtilities.invokeLater(() -> {
+ MigratorFrame inst = new MigratorFrame();
+ inst.setLocationRelativeTo(null);
+ inst.setVisible(true);
});
}
diff --git a/slf4j-migrator/src/main/java/org/slf4j/migrator/ProjectConverter.java b/slf4j-migrator/src/main/java/org/slf4j/migrator/ProjectConverter.java
index 99f1a194..f7947577 100644
--- a/slf4j-migrator/src/main/java/org/slf4j/migrator/ProjectConverter.java
+++ b/slf4j-migrator/src/main/java/org/slf4j/migrator/ProjectConverter.java
@@ -27,7 +27,6 @@ package org.slf4j.migrator;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
import javax.swing.SwingUtilities;
@@ -38,25 +37,23 @@ import org.slf4j.migrator.line.RuleSet;
public class ProjectConverter {
- private RuleSet ruleSet;
+ private final RuleSet ruleSet;
private List<ConversionException> exception;
ProgressListener progressListener;
- public static void main(String[] args) throws IOException {
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- MigratorFrame inst = new MigratorFrame();
- inst.setLocationRelativeTo(null);
- inst.setVisible(true);
- }
+ public static void main(String[] args) {
+ SwingUtilities.invokeLater(() -> {
+ MigratorFrame inst = new MigratorFrame();
+ inst.setLocationRelativeTo(null);
+ inst.setVisible(true);
});
}
/**
* Ask for concrete matcher implementation depending on the conversion mode
* Ask for user confirmation to convert the selected source directory if valid
- * Ask for user confirmation in case of number of files to convert > 1000
+ * Ask for user confirmation in case of number of files to convert &gt; 1000
*
* @param conversionType
* @param progressListener
@@ -83,9 +80,7 @@ public class ProjectConverter {
*/
private void scanFileList(List<File> lstFiles) {
progressListener.onFileScanBegin();
- Iterator<File> itFile = lstFiles.iterator();
- while (itFile.hasNext()) {
- File currentFile = itFile.next();
+ for (File currentFile : lstFiles) {
progressListener.onFileScan(currentFile);
scanFile(currentFile);
}
@@ -108,16 +103,14 @@ public class ProjectConverter {
public void addException(ConversionException exc) {
if (exception == null) {
- exception = new ArrayList<ConversionException>();
+ exception = new ArrayList<>();
}
exception.add(exc);
}
public void printException() {
if (exception != null) {
- Iterator<ConversionException> iterator = exception.iterator();
- while (iterator.hasNext()) {
- ConversionException exc = (ConversionException) iterator.next();
+ for (ConversionException exc : exception) {
exc.print();
}
exception = null;
diff --git a/slf4j-migrator/src/main/java/org/slf4j/migrator/helper/Abbreviator.java b/slf4j-migrator/src/main/java/org/slf4j/migrator/helper/Abbreviator.java
index f2f9b35d..519a3f04 100644
--- a/slf4j-migrator/src/main/java/org/slf4j/migrator/helper/Abbreviator.java
+++ b/slf4j-migrator/src/main/java/org/slf4j/migrator/helper/Abbreviator.java
@@ -44,11 +44,11 @@ public class Abbreviator {
int firstIndex = filename.indexOf(folderSeparator, invariantPrefixLength);
if (firstIndex == -1) {
- // we cant't process this string
+ // we can't process this string
return filename;
}
StringBuilder buf = new StringBuilder(desiredLength);
- buf.append(filename.substring(0, firstIndex + 1));
+ buf.append(filename, 0, firstIndex + 1);
buf.append(FILLER);
int nextIndex = computeNextIndex(filename, firstIndex);
if (nextIndex != -1) {
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 377ac6e5..3ab15c60 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 javax.swing.WindowConstants;
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;
@@ -68,8 +58,8 @@ public class MigratorFrame extends JFrame implements ActionListener {
static final int X_SIZE = 700;
static final int Y_SIZE = 400;
- private SpringLayout layoutManager = new SpringLayout();
- private SpringLayoutHelper slh = new SpringLayoutHelper(layoutManager, BASIC_PADDING);
+ private final SpringLayout layoutManager = new SpringLayout();
+ private final SpringLayoutHelper slh = new SpringLayoutHelper(layoutManager, BASIC_PADDING);
private JLabel migrationLabel;
@@ -138,7 +128,7 @@ public class MigratorFrame extends JFrame implements ActionListener {
*/
private void constrainAll() {
- // contrain migration label
+ // constraints migration label
layoutManager.putConstraint(SpringLayout.WEST, migrationLabel, BASIC_PADDING, SpringLayout.EAST, this);
layoutManager.putConstraint(SpringLayout.NORTH, migrationLabel, BASIC_PADDING, SpringLayout.NORTH, this);
@@ -239,14 +229,14 @@ public class MigratorFrame extends JFrame implements ActionListener {
private void createAwareLabel() {
awareLabel = new JLabel();
- awareLabel.setText("<html>" + "<p>I am aware that this tool will directly modify all Java source files</p>"
- + "<p>in the selected folder without creating backup files.</p>" + "</html>");
+ awareLabel.setText("<html>" + "<p>I am aware that this tool will directly modify all Java source files"
+ + "<p>in the selected folder without creating backup files." + "</html>");
}
private void createWarningLabel() {
warningLabel = new JLabel();
- warningLabel.setText("<html>" + "<p><span color=\"red\">WARNING:</span> This SLF4J migration tool will directly modify all Java source files</p>"
- + "<p>in the selected project folder without creating a backup of the original files.</p>" + "</html>");
+ warningLabel.setText("<html>" + "<p><span color=\"red\">WARNING:</span> This SLF4J migration tool will directly modify all Java source files"
+ + "<p>in the selected project folder without creating a backup of the original files." + "</html>");
}
private void createMigrateButton() {
@@ -323,7 +313,7 @@ public class MigratorFrame extends JFrame implements ActionListener {
List<String> doSanityAnalysis() {
- List<String> errorList = new ArrayList<String>();
+ List<String> errorList = new ArrayList<>();
if (!radioJCL.isSelected() && !radioLog4j.isSelected() && !radioJUL.isSelected()) {
errorList.add("Please select the migration type: JCL, log4j, or JUL to SLF4J.");
}
@@ -351,7 +341,7 @@ public class MigratorFrame extends JFrame implements ActionListener {
buf.append(i);
buf.append(". ");
buf.append(msg);
- buf.append("</p>");
+ buf.append("");
i++;
}
buf.append("</html>");
diff --git a/slf4j-migrator/src/main/java/org/slf4j/migrator/line/EmptyRuleSet.java b/slf4j-migrator/src/main/java/org/slf4j/migrator/line/EmptyRuleSet.java
index a0393265..3533d0e3 100644
--- a/slf4j-migrator/src/main/java/org/slf4j/migrator/line/EmptyRuleSet.java
+++ b/slf4j-migrator/src/main/java/org/slf4j/migrator/line/EmptyRuleSet.java
@@ -30,7 +30,7 @@ import java.util.List;
public class EmptyRuleSet implements RuleSet {
- List<ConversionRule> list = new ArrayList<ConversionRule>();
+ List<ConversionRule> list = new ArrayList<>();
public Iterator<ConversionRule> iterator() {
return list.iterator();
diff --git a/slf4j-migrator/src/main/java/org/slf4j/migrator/line/JCLRuleSet.java b/slf4j-migrator/src/main/java/org/slf4j/migrator/line/JCLRuleSet.java
index f463e46d..8367d508 100644
--- a/slf4j-migrator/src/main/java/org/slf4j/migrator/line/JCLRuleSet.java
+++ b/slf4j-migrator/src/main/java/org/slf4j/migrator/line/JCLRuleSet.java
@@ -36,7 +36,7 @@ import java.util.regex.Pattern;
*/
public class JCLRuleSet implements RuleSet {
- private ArrayList<ConversionRule> conversionRuleList;
+ private final ArrayList<ConversionRule> conversionRuleList;
public JCLRuleSet() {
// matching : import org.apache.commons.logging.LogFactory;
@@ -54,7 +54,7 @@ public class JCLRuleSet implements RuleSet {
SingleConversionRule cr5 = new SingleConversionRule(Pattern.compile("LogFactory.getLog\\("), "LoggerFactory.getLogger(");
- conversionRuleList = new ArrayList<ConversionRule>();
+ conversionRuleList = new ArrayList<>();
conversionRuleList.add(cr0);
conversionRuleList.add(cr1);
conversionRuleList.add(cr2);
diff --git a/slf4j-migrator/src/main/java/org/slf4j/migrator/line/JULRuleSet.java b/slf4j-migrator/src/main/java/org/slf4j/migrator/line/JULRuleSet.java
index b296b70a..da5f3378 100644
--- a/slf4j-migrator/src/main/java/org/slf4j/migrator/line/JULRuleSet.java
+++ b/slf4j-migrator/src/main/java/org/slf4j/migrator/line/JULRuleSet.java
@@ -36,7 +36,7 @@ import java.util.regex.Pattern;
*/
public class JULRuleSet implements RuleSet {
- private ArrayList<ConversionRule> conversionRuleList;
+ private final ArrayList<ConversionRule> conversionRuleList;
public JULRuleSet() {
@@ -55,7 +55,7 @@ public class JULRuleSet implements RuleSet {
SingleConversionRule crWarning = new SingleConversionRule(Pattern.compile("\\.warning\\("), ".warn(");
SingleConversionRule crSevere = new SingleConversionRule(Pattern.compile("\\.severe\\("), ".error(");
- conversionRuleList = new ArrayList<ConversionRule>();
+ conversionRuleList = new ArrayList<>();
conversionRuleList.add(crImport0);
conversionRuleList.add(crImport1);
conversionRuleList.add(crImport2);
diff --git a/slf4j-migrator/src/main/java/org/slf4j/migrator/line/Log4jRuleSet.java b/slf4j-migrator/src/main/java/org/slf4j/migrator/line/Log4jRuleSet.java
index c760496c..e07aa73a 100755
--- a/slf4j-migrator/src/main/java/org/slf4j/migrator/line/Log4jRuleSet.java
+++ b/slf4j-migrator/src/main/java/org/slf4j/migrator/line/Log4jRuleSet.java
@@ -30,7 +30,7 @@ import java.util.regex.Pattern;
public class Log4jRuleSet implements RuleSet {
- private ArrayList<ConversionRule> conversionRuleList;
+ private final ArrayList<ConversionRule> conversionRuleList;
public Log4jRuleSet() {
@@ -57,7 +57,7 @@ public class Log4jRuleSet implements RuleSet {
SingleConversionRule variable1 = new SingleConversionRule(Pattern.compile("(^Category\\b)"), "Logger");
- conversionRuleList = new ArrayList<ConversionRule>();
+ conversionRuleList = new ArrayList<>();
conversionRuleList.add(crImport0);
conversionRuleList.add(catImport);
conversionRuleList.add(crImport1);
diff --git a/slf4j-migrator/src/main/java/org/slf4j/migrator/line/MultiGroupConversionRule.java b/slf4j-migrator/src/main/java/org/slf4j/migrator/line/MultiGroupConversionRule.java
index ce1ee520..f0769406 100644
--- a/slf4j-migrator/src/main/java/org/slf4j/migrator/line/MultiGroupConversionRule.java
+++ b/slf4j-migrator/src/main/java/org/slf4j/migrator/line/MultiGroupConversionRule.java
@@ -40,8 +40,8 @@ public class MultiGroupConversionRule implements ConversionRule {
// our conversion reg-expressions
final private static int MAX_GROUPS = 10;
- private Pattern pattern;
- private String[] replacementTable = new String[MAX_GROUPS];
+ private final Pattern pattern;
+ private final String[] replacementTable = new String[MAX_GROUPS];
public MultiGroupConversionRule(Pattern pattern) {
this.pattern = pattern;
diff --git a/slf4j-migrator/src/main/resources/META-INF/MANIFEST.MF b/slf4j-migrator/src/main/resources/META-INF/MANIFEST.MF
deleted file mode 100644
index 10f5bdf3..00000000
--- a/slf4j-migrator/src/main/resources/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1 +0,0 @@
-Main-Class: org.slf4j.migrator.Main \ No newline at end of file
diff --git a/slf4j-migrator/src/test/java/org/slf4j/migrator/AternativeApproach.java b/slf4j-migrator/src/test/java/org/slf4j/migrator/AternativeApproach.java
index d4b090a2..0626b871 100644
--- a/slf4j-migrator/src/test/java/org/slf4j/migrator/AternativeApproach.java
+++ b/slf4j-migrator/src/test/java/org/slf4j/migrator/AternativeApproach.java
@@ -34,7 +34,7 @@ import junit.framework.TestCase;
public class AternativeApproach extends TestCase {
/**
- * In this test we see that we cans use more simple Pattern to do the
+ * In this test we see that we can use more simple Pattern to do the
* conversion
*
*/
@@ -55,7 +55,7 @@ public class AternativeApproach extends TestCase {
/**
* In this test we replace, using the simple Pattern (Log), the full Log
- * declaration and instanciation. This is not convenient because we will also
+ * declaration and instantiation. This is not convenient because we will also
* replace all String containing "Log".
*/
public void test2() {
@@ -82,7 +82,7 @@ public class AternativeApproach extends TestCase {
}
/**
- * In this test we use a simple Pattern to replace the log instanciation
+ * In this test we use a simple Pattern to replace the log instantiation
* without influence on Log declaration.
*
*/
@@ -101,7 +101,7 @@ public class AternativeApproach extends TestCase {
/**
* In this test we try to replace keyword Log without influence on String
- * containg Log We see that we have to use two differents Patterns
+ * containing Log We see that we have to use two different Patterns
*/
public void test4() {
Pattern pat = Pattern.compile("(\\sLog\\b)");
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 9f3eb461..4e1b1382 100644
--- a/slf4j-migrator/src/test/java/org/slf4j/migrator/FileConverterTest.java
+++ b/slf4j-migrator/src/test/java/org/slf4j/migrator/FileConverterTest.java
@@ -27,29 +27,15 @@ package org.slf4j.migrator;
import java.io.File;
import java.io.IOException;
-import junit.framework.TestCase;
-
-import org.slf4j.migrator.InplaceFileConverter;
+import org.junit.Ignore;
+import org.junit.Test;
import org.slf4j.migrator.internal.NopProgressListener;
import org.slf4j.migrator.line.EmptyRuleSet;
-public class FileConverterTest extends TestCase {
-
- public FileConverterTest(String arg0) {
- super(arg0);
- }
-
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void test() {
- }
+public class FileConverterTest {
+ @Test
+ @Ignore
public void XtestNOP() throws IOException {
InplaceFileConverter fc = new InplaceFileConverter(new EmptyRuleSet(), new NopProgressListener());
fc.convert(new File("c:/varargs.txt"));
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 a8cee0bf..537ba3f4 100644
--- a/slf4j-migrator/src/test/java/org/slf4j/migrator/ProjectConverterTest.java
+++ b/slf4j-migrator/src/test/java/org/slf4j/migrator/ProjectConverterTest.java
@@ -26,17 +26,17 @@ package org.slf4j.migrator;
import java.io.File;
-import org.slf4j.migrator.Constant;
-import org.slf4j.migrator.ProjectConverter;
+import org.junit.Ignore;
+import org.junit.Test;
import org.slf4j.migrator.internal.NopProgressListener;
-import junit.framework.TestCase;
-
-public class ProjectConverterTest extends TestCase {
+public class ProjectConverterTest {
public void test() {
}
+ @Test
+ @Ignore
public void XtestBarracuda() {
ProjectConverter pc = new ProjectConverter(Constant.LOG4J_TO_SLF4J, new NopProgressListener());
File projectFolder = new File("c:/home/ceki//Varia/Barracuda");
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 ab8c8cbb..ac470b88 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
@@ -24,11 +24,12 @@
*/
package org.slf4j.migrator.helper;
-import org.slf4j.migrator.helper.Abbreviator;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
-import junit.framework.TestCase;
+import org.junit.Test;
-public class AbbreviatorTest extends TestCase {
+public class AbbreviatorTest {
static final char FS = '/';
static final String INPUT_0 = "/abc/123456/ABC";
@@ -36,18 +37,7 @@ public class AbbreviatorTest extends TestCase {
RandomHelper rh = new RandomHelper(FS);
- public AbbreviatorTest(String arg0) {
- super(arg0);
- }
-
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
+ @Test
public void testSmoke() {
{
Abbreviator abb = new Abbreviator(2, 100, FS);
@@ -67,6 +57,7 @@ public class AbbreviatorTest extends TestCase {
}
}
+ @Test
public void testImpossibleToAbbreviate() {
Abbreviator abb = new Abbreviator(2, 20, FS);
String in = "iczldqwivpgm/mgrmvbjdxrwmqgprdjusth";
@@ -74,6 +65,7 @@ public class AbbreviatorTest extends TestCase {
assertEquals(in, r);
}
+ @Test
public void testNoFS() {
Abbreviator abb = new Abbreviator(2, 100, FS);
String r = abb.abbreviate("hello");
@@ -81,6 +73,7 @@ public class AbbreviatorTest extends TestCase {
}
+ @Test
public void testZeroPrefix() {
{
Abbreviator abb = new Abbreviator(0, 100, FS);
@@ -89,6 +82,7 @@ public class AbbreviatorTest extends TestCase {
}
}
+ @Test
public void testTheories() {
int MAX_RANDOM_FIXED_LEN = 20;
int MAX_RANDOM_AVG_LEN = 20;
diff --git a/slf4j-migrator/src/test/java/org/slf4j/migrator/helper/RandomHelper.java b/slf4j-migrator/src/test/java/org/slf4j/migrator/helper/RandomHelper.java
index 1928daaa..f0e304ca 100644
--- a/slf4j-migrator/src/test/java/org/slf4j/migrator/helper/RandomHelper.java
+++ b/slf4j-migrator/src/test/java/org/slf4j/migrator/helper/RandomHelper.java
@@ -28,7 +28,7 @@ import java.util.Random;
public class RandomHelper {
- private Random random = new Random(100);
+ private final Random random = new Random(100);
final char folderSeparator;
RandomHelper(char folderSeparator) {
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 442b0cf6..f480229a 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
@@ -24,15 +24,15 @@
*/
package org.slf4j.migrator.line;
-import org.slf4j.migrator.line.JCLRuleSet;
-import org.slf4j.migrator.line.LineConverter;
+import static org.junit.Assert.assertEquals;
-import junit.framework.TestCase;
+import org.junit.Test;
-public class JCLRuleSetTest extends TestCase {
+public class JCLRuleSetTest {
LineConverter jclConverter = new LineConverter(new JCLRuleSet());
+ @Test
public void testImportReplacement() {
// LogFactory import replacement
assertEquals("import org.slf4j.LoggerFactory;", jclConverter.getOneLineReplacement("import org.apache.commons.logging.LogFactory;"));
@@ -40,6 +40,7 @@ public class JCLRuleSetTest extends TestCase {
assertEquals("import org.slf4j.Logger;", jclConverter.getOneLineReplacement("import org.apache.commons.logging.Log;"));
}
+ @Test
public void testLogFactoryGetLogReplacement() {
// Logger declaration and instanciation without modifier
assertEquals(" Logger l = LoggerFactory.getLogger(MyClass.class);",
@@ -65,6 +66,7 @@ public class JCLRuleSetTest extends TestCase {
jclConverter.getOneLineReplacement("// myLog = LogFactory.getLog(MyClass.class);//logger instanciation"));
}
+ @Test
public void testLogFactoryGetFactoryReplacement() {
// Logger declaration and instanciation without modifier
@@ -91,6 +93,7 @@ public class JCLRuleSetTest extends TestCase {
jclConverter.getOneLineReplacement("// myLog = LogFactory.getFactory().getInstance(MyClass.class);//logger instanciation"));
}
+ @Test
public void testLogDeclarationReplacement() {
// simple Logger declaration
@@ -106,6 +109,7 @@ public class JCLRuleSetTest extends TestCase {
assertEquals("//private Logger myLog;", jclConverter.getOneLineReplacement("//private Log myLog;"));
}
+ @Test
public void testMultiLineReplacement() {
// Logger declaration on a line
assertEquals("protected Logger log =", jclConverter.getOneLineReplacement("protected Log log ="));
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 7160193b..60b1fdbf 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
@@ -24,18 +24,17 @@
*/
package org.slf4j.migrator.line;
-import org.slf4j.migrator.line.JCLRuleSet;
-import org.slf4j.migrator.line.LineConverter;
-import org.slf4j.migrator.line.Log4jRuleSet;
+import static org.junit.Assert.assertEquals;
-import junit.framework.TestCase;
+import org.junit.Test;
-public class NoConversionTest extends TestCase {
+public class NoConversionTest {
/**
* This test shows that performing JCL to SLF4J conversion has no impact on
* Log4j implementation
*/
+ @Test
public void testJclOverLog4jConversion() {
// running jcl to slf4j conversion
// JCLMatcher jclMatcher =
@@ -56,6 +55,7 @@ public class NoConversionTest extends TestCase {
* This test shows that performing Log4j to SLF4J conversion has no impact on
* JCL implementation
*/
+ @Test
public void testLog4jOverJclConversion() {
// running log4j to slf4j conversion
LineConverter log4jConverter = new LineConverter(new Log4jRuleSet());
diff --git a/slf4j-migrator/src/test/java/org/slf4j/migrator/line/TrivialMatcher.java b/slf4j-migrator/src/test/java/org/slf4j/migrator/line/TrivialMatcher.java
index d392769b..032bddca 100644
--- a/slf4j-migrator/src/test/java/org/slf4j/migrator/line/TrivialMatcher.java
+++ b/slf4j-migrator/src/test/java/org/slf4j/migrator/line/TrivialMatcher.java
@@ -35,23 +35,23 @@ import org.slf4j.migrator.line.SingleConversionRule;
class TrivialMatcher implements RuleSet {
- private ArrayList<ConversionRule> conversionRuleList;
+ private final ArrayList<ConversionRule> conversionRuleList;
public TrivialMatcher() {
// simple rule no capturing group is defined, we use default capturing group which is group zero
SingleConversionRule cr = new SingleConversionRule(Pattern.compile("import org.slf4j.converter"), "simple replacement with an unique capturing group");
- // we define 4 differents capturing groups
+ // we define 4 different capturing groups
MultiGroupConversionRule cr1 = new MultiGroupConversionRule(Pattern.compile("(first group)( second group)( third group)( 4th group)"));
// group zero is ignored during treatment
// replacement for the first
cr1.addReplacement(1, "1st group");
- // no replacement for the second group it will remains the same
+ // no replacement for the second group it will remain the same
// empty string for the third group it will be deleted
cr1.addReplacement(3, "");
- // no replacement for the third group it will remains the same
+ // no replacement for the third group it will remain the same
- conversionRuleList = new ArrayList<ConversionRule>();
+ conversionRuleList = new ArrayList<>();
conversionRuleList.add(cr);
conversionRuleList.add(cr1);
}
@@ -60,4 +60,4 @@ class TrivialMatcher implements RuleSet {
return conversionRuleList.iterator();
}
-} \ No newline at end of file
+}
diff --git a/slf4j-migrator/src/test/java/org/slf4j/migrator/line/TrivialMatcherTest.java b/slf4j-migrator/src/test/java/org/slf4j/migrator/line/TrivialMatcherTest.java
index b5b3c6d4..0a9194df 100644
--- a/slf4j-migrator/src/test/java/org/slf4j/migrator/line/TrivialMatcherTest.java
+++ b/slf4j-migrator/src/test/java/org/slf4j/migrator/line/TrivialMatcherTest.java
@@ -24,12 +24,13 @@
*/
package org.slf4j.migrator.line;
-import org.slf4j.migrator.line.LineConverter;
+import static org.junit.Assert.assertEquals;
-import junit.framework.TestCase;
+import org.junit.Test;
-public class TrivialMatcherTest extends TestCase {
+public class TrivialMatcherTest {
+ @Test
public void testSimpleReplacement() {
LineConverter trivialLC = new LineConverter(new TrivialMatcher());
diff --git a/slf4j-nop/LICENSE.txt b/slf4j-nop/LICENSE.txt
index 508a2728..e4079f54 100644
--- a/slf4j-nop/LICENSE.txt
+++ b/slf4j-nop/LICENSE.txt
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2007 QOS.ch
+Copyright (c) 2004-2023 QOS.ch
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/slf4j-nop/pom.xml b/slf4j-nop/pom.xml
index e0da3a69..18fd0c44 100755
--- a/slf4j-nop/pom.xml
+++ b/slf4j-nop/pom.xml
@@ -1,23 +1,28 @@
-<project
- xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
- <version>1.7.13-SNAPSHOT</version>
+ <version>2.0.12</version>
+ <relativePath>../parent/pom.xml</relativePath>
</parent>
<artifactId>slf4j-nop</artifactId>
<packaging>jar</packaging>
- <name>SLF4J NOP Binding</name>
- <description>SLF4J NOP Binding</description>
+ <name>SLF4J NOP Provider</name>
+ <description>SLF4J NOP Provider</description>
<url>http://www.slf4j.org</url>
+ <properties>
+ <module-name>org.slf4j.nop</module-name>
+ <slf4j.provider.implementation>org.slf4j.nop.NOPServiceProvider</slf4j.provider.implementation>
+ <slf4j.provider.type>nop</slf4j.provider.type>
+ </properties>
<dependencies>
<dependency>
@@ -26,25 +31,4 @@
</dependency>
</dependencies>
- <build>
- <plugins>
-
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <archive>
- <manifestEntries>
- <Bundle-Version>${parsedVersion.osgiVersion}</Bundle-Version>
- <Bundle-Description>${project.description}</Bundle-Description>
- <Implementation-Version>${project.version}</Implementation-Version>
- </manifestEntries>
- <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
- </archive>
- </configuration>
- </plugin>
- </plugins>
-
- </build>
-
-</project> \ No newline at end of file
+</project>
diff --git a/slf4j-nop/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/slf4j-nop/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
deleted file mode 100644
index 10a947a6..00000000
--- a/slf4j-nop/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
+++ /dev/null
@@ -1,80 +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 org.slf4j.ILoggerFactory;
-import org.slf4j.LoggerFactory;
-import org.slf4j.helpers.NOPLoggerFactory;
-import org.slf4j.spi.LoggerFactoryBinder;
-
-/**
- * The binding of {@link LoggerFactory} class with an actual instance of
- * {@link ILoggerFactory} is performed using information returned by this class.
- *
- * @author Ceki G&uuml;lc&uuml;
- */
-public class StaticLoggerBinder implements LoggerFactoryBinder {
-
- /**
- * The unique instance of this class.
- *
- */
- private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
-
- /**
- * Return the singleton of this class.
- *
- * @return the StaticLoggerBinder singleton
- */
- public static final StaticLoggerBinder getSingleton() {
- return SINGLETON;
- }
-
- /**
- * Declare the version of the SLF4J API this implementation is compiled against.
- * The value of this field is usually modified with each release.
- */
- // to avoid constant folding by the compiler, this field must *not* be final
- public static String REQUESTED_API_VERSION = "1.6.99"; // !final
-
- private static final String loggerFactoryClassStr = NOPLoggerFactory.class.getName();
-
- /** The ILoggerFactory instance returned by the {@link #getLoggerFactory} method
- * should always be the same object
- */
- private final ILoggerFactory loggerFactory;
-
- private StaticLoggerBinder() {
- loggerFactory = new NOPLoggerFactory();
- }
-
- public ILoggerFactory getLoggerFactory() {
- return loggerFactory;
- }
-
- public String getLoggerFactoryClassStr() {
- return loggerFactoryClassStr;
- }
-}
diff --git a/slf4j-nop/src/main/java/org/slf4j/impl/StaticMDCBinder.java b/slf4j-nop/src/main/java/org/slf4j/impl/StaticMDCBinder.java
deleted file mode 100644
index 086b0169..00000000
--- a/slf4j-nop/src/main/java/org/slf4j/impl/StaticMDCBinder.java
+++ /dev/null
@@ -1,56 +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 org.slf4j.helpers.NOPMDCAdapter;
-import org.slf4j.spi.MDCAdapter;
-
-/**
- * This implementation is bound to {@link NOPMDCAdapter}.
- *
- * @author Ceki G&uuml;lc&uuml;
- */
-public class StaticMDCBinder {
-
- /**
- * The unique instance of this class.
- */
- public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
-
- private StaticMDCBinder() {
- }
-
- /**
- * Currently this method always returns an instance of
- * {@link StaticMDCBinder}.
- */
- public MDCAdapter getMDCA() {
- return new NOPMDCAdapter();
- }
-
- public String getMDCAdapterClassStr() {
- return NOPMDCAdapter.class.getName();
- }
-}
diff --git a/slf4j-nop/src/main/java/org/slf4j/impl/StaticMarkerBinder.java b/slf4j-nop/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
deleted file mode 100644
index 1d255230..00000000
--- a/slf4j-nop/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
+++ /dev/null
@@ -1,67 +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 org.slf4j.IMarkerFactory;
-import org.slf4j.MarkerFactory;
-import org.slf4j.helpers.BasicMarkerFactory;
-import org.slf4j.spi.MarkerFactoryBinder;
-
-/**
- *
- * The binding of {@link MarkerFactory} class with an actual instance of
- * {@link IMarkerFactory} is performed using information returned by this class.
- *
- * @author Ceki G&uuml;lc&uuml;
- */
-public class StaticMarkerBinder implements MarkerFactoryBinder {
-
- /**
- * The unique instance of this class.
- */
- public static final StaticMarkerBinder SINGLETON = new StaticMarkerBinder();
-
- final IMarkerFactory markerFactory = new BasicMarkerFactory();
-
- private StaticMarkerBinder() {
- }
-
- /**
- * Currently this method always returns an instance of
- * {@link BasicMarkerFactory}.
- */
- public IMarkerFactory getMarkerFactory() {
- return markerFactory;
- }
-
- /**
- * Currently, this method returns the class name of
- * {@link BasicMarkerFactory}.
- */
- public String getMarkerFactoryClassStr() {
- return BasicMarkerFactory.class.getName();
- }
-
-}
diff --git a/slf4j-nop/src/main/java/org/slf4j/nop/NOPServiceProvider.java b/slf4j-nop/src/main/java/org/slf4j/nop/NOPServiceProvider.java
new file mode 100755
index 00000000..515cf23b
--- /dev/null
+++ b/slf4j-nop/src/main/java/org/slf4j/nop/NOPServiceProvider.java
@@ -0,0 +1,46 @@
+package org.slf4j.nop;
+
+import org.slf4j.ILoggerFactory;
+import org.slf4j.IMarkerFactory;
+import org.slf4j.helpers.BasicMarkerFactory;
+import org.slf4j.helpers.NOPLoggerFactory;
+import org.slf4j.helpers.NOPMDCAdapter;
+import org.slf4j.spi.MDCAdapter;
+import org.slf4j.spi.SLF4JServiceProvider;
+
+public class NOPServiceProvider implements SLF4JServiceProvider {
+
+ /**
+ * Declare the version of the SLF4J API this implementation is compiled against.
+ * The value of this field is modified with each major release.
+ */
+ // to avoid constant folding by the compiler, this field must *not* be final
+ public static String REQUESTED_API_VERSION = "2.0.99"; // !final
+
+ private final ILoggerFactory loggerFactory = new NOPLoggerFactory();
+ private final IMarkerFactory markerFactory = new BasicMarkerFactory();
+ private final MDCAdapter mdcAdapter = new NOPMDCAdapter();
+
+ public ILoggerFactory getLoggerFactory() {
+ return loggerFactory;
+ }
+
+ public IMarkerFactory getMarkerFactory() {
+ return markerFactory;
+ }
+
+ public MDCAdapter getMDCAdapter() {
+ return mdcAdapter;
+ }
+
+ @Override
+ public String getRequestedApiVersion() {
+ return REQUESTED_API_VERSION;
+ }
+
+ public void initialize() {
+
+ }
+
+
+}
diff --git a/slf4j-nop/src/main/java9/module-info.java b/slf4j-nop/src/main/java9/module-info.java
new file mode 100755
index 00000000..53e1f40a
--- /dev/null
+++ b/slf4j-nop/src/main/java9/module-info.java
@@ -0,0 +1,7 @@
+module org.slf4j.nop {
+ requires org.slf4j;
+ provides org.slf4j.spi.SLF4JServiceProvider with org.slf4j.nop.NOPServiceProvider;
+
+ exports org.slf4j.nop;
+ opens org.slf4j.nop to org.slf4j;
+}
diff --git a/slf4j-nop/src/main/resources/META-INF/MANIFEST.MF b/slf4j-nop/src/main/resources/META-INF/MANIFEST.MF
deleted file mode 100644
index c009d03d..00000000
--- a/slf4j-nop/src/main/resources/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,9 +0,0 @@
-Implementation-Title: slf4j-nop
-Bundle-ManifestVersion: 2
-Bundle-SymbolicName: slf4j.nop
-Bundle-Name: slf4j-nop
-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}
-Fragment-Host: slf4j.api \ No newline at end of file
diff --git a/slf4j-nop/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider b/slf4j-nop/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider
new file mode 100755
index 00000000..9929e9df
--- /dev/null
+++ b/slf4j-nop/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider
@@ -0,0 +1 @@
+org.slf4j.nop.NOPServiceProvider \ No newline at end of file
diff --git a/slf4j-nop/src/test/java/org/slf4j/InvocationTest.java b/slf4j-nop/src/test/java/org/slf4j/nop/InvocationTest.java
index ea57d374..8cb7c036 100644
--- a/slf4j-nop/src/test/java/org/slf4j/InvocationTest.java
+++ b/slf4j-nop/src/test/java/org/slf4j/nop/InvocationTest.java
@@ -22,11 +22,16 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j;
+package org.slf4j.nop;
-import java.io.Closeable;
-import java.io.IOException;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
/**
* Test whether invoking the SLF4J API causes problems or not.
@@ -34,29 +39,19 @@ import junit.framework.TestCase;
* @author Ceki Gulcu
*
*/
-public class InvocationTest extends TestCase {
-
- public InvocationTest(String arg0) {
- super(arg0);
- }
-
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
+public class InvocationTest {
+ @Test
public void test1() {
Logger logger = LoggerFactory.getLogger("test1");
logger.debug("Hello world.");
}
+ @Test
public void test2() {
- Integer i1 = new Integer(1);
- Integer i2 = new Integer(2);
- Integer i3 = new Integer(3);
+ Integer i1 = Integer.valueOf(1);
+ Integer i2 = Integer.valueOf(2);
+ Integer i3 = Integer.valueOf(3);
Exception e = new Exception("This is a test exception.");
Logger logger = LoggerFactory.getLogger("test2");
@@ -72,10 +67,11 @@ public class InvocationTest extends TestCase {
logger.warn("Hello world 3", e);
logger.error("Hello world 4.");
- logger.error("Hello world {}", new Integer(3));
+ logger.error("Hello world {}", Integer.valueOf(3));
logger.error("Hello world 4.", e);
}
+ @Test
public void testNull() {
Logger logger = LoggerFactory.getLogger("testNull");
logger.debug(null);
@@ -90,6 +86,7 @@ public class InvocationTest extends TestCase {
logger.error(null, e);
}
+ @Test
public void testMarker() {
Logger logger = LoggerFactory.getLogger("testMarker");
Marker blue = MarkerFactory.getMarker("BLUE");
@@ -109,6 +106,7 @@ public class InvocationTest extends TestCase {
logger.error(blue, "hello {} and {} ", "world", "universe");
}
+ @Test
public void testMDC() {
MDC.put("k", "v");
assertNull(MDC.get("k"));
@@ -117,6 +115,7 @@ public class InvocationTest extends TestCase {
MDC.clear();
}
+ @Test
public void testMDCCloseable() {
MDC.MDCCloseable closeable = MDC.putCloseable("k", "v");
assertNull(MDC.get("k"));
diff --git a/slf4j-nop/src/test/java/org/slf4j/nop/MultithreadedInitializationTest.java b/slf4j-nop/src/test/java/org/slf4j/nop/MultithreadedInitializationTest.java
new file mode 100755
index 00000000..9cd0bc0c
--- /dev/null
+++ b/slf4j-nop/src/test/java/org/slf4j/nop/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.nop;
+
+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 final 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<String> 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-reload4j/LICENSE.txt b/slf4j-reload4j/LICENSE.txt
new file mode 100644
index 00000000..96084119
--- /dev/null
+++ b/slf4j-reload4j/LICENSE.txt
@@ -0,0 +1,24 @@
+Copyright (c) 2004-2023 QOS.ch Sarl (Switzerland)
+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.
+
+
+
diff --git a/slf4j-reload4j/pom.xml b/slf4j-reload4j/pom.xml
new file mode 100644
index 00000000..3dadcd66
--- /dev/null
+++ b/slf4j-reload4j/pom.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-parent</artifactId>
+ <version>2.0.12</version>
+ <relativePath>../parent/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>slf4j-reload4j</artifactId>
+
+
+ <packaging>jar</packaging>
+ <name>SLF4J Reload4j Provider</name>
+ <description>SLF4J Reload4j Provider</description>
+ <url>http://reload4j.qos.ch</url>
+
+ <properties>
+ <slf4j.provider.implementation>org.slf4j.reload4j.Reload4jServiceProvider</slf4j.provider.implementation>
+ <slf4j.provider.type>reload4j</slf4j.provider.type>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>ch.qos.reload4j</groupId>
+ <artifactId>reload4j</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <type>test-jar</type>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.19.1</version>
+ <configuration>
+ <forkCount>1</forkCount>
+ <reuseForks>false</reuseForks>
+ <reportFormat>plain</reportFormat>
+ <trimStackTrace>false</trimStackTrace>
+ <excludes>
+ <exclude>**/AllTest.java</exclude>
+ <exclude>**/PackageTest.java</exclude>
+ </excludes>
+ <argLine>-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8001</argLine>
+ <!--<argLine>XXadd-opens log4j/org.apache.log4j=org.slf4j.log4j12</argLine>-->
+ </configuration>
+ </plugin>
+
+ </plugins>
+ </build>
+</project>
diff --git a/slf4j-reload4j/src/main/java/org/slf4j/reload4j/Reload4jLoggerAdapter.java b/slf4j-reload4j/src/main/java/org/slf4j/reload4j/Reload4jLoggerAdapter.java
new file mode 100644
index 00000000..90a305d3
--- /dev/null
+++ b/slf4j-reload4j/src/main/java/org/slf4j/reload4j/Reload4jLoggerAdapter.java
@@ -0,0 +1,213 @@
+/**
+ * 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.reload4j;
+
+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.DefaultLoggingEvent;
+import org.slf4j.event.LoggingEvent;
+import org.slf4j.event.SubstituteLoggingEvent;
+import org.slf4j.helpers.LegacyAbstractLogger;
+import org.slf4j.helpers.MessageFormatter;
+import org.slf4j.helpers.NormalizedParameters;
+import org.slf4j.helpers.SubstituteLogger;
+import org.slf4j.spi.LocationAwareLogger;
+import org.slf4j.spi.LoggingEventAware;
+import org.slf4j.spi.LoggingEventBuilder;
+
+/**
+ * A wrapper over {@link org.apache.log4j.Logger org.apache.log4j.Logger}
+ * conforming to the {@link Logger} interface.
+ *
+ * <p>
+ * Note that the logging levels mentioned in this class refer to those defined
+ * in the <a href=
+ * "http://logging.apache.org/log4j/docs/api/org/apache/log4j/Level.html">
+ * <code>org.apache.log4j.Level</code></a> class.
+ *
+ * <p>This class is a copy-and-paste of Log4j12LoggerAdapter from the
+ * slf4j-log4j12 module.</p>
+ *
+ * @author Ceki G&uuml;lc&uuml;
+ * @since 2.0.0-alpha6
+ */
+public final class Reload4jLoggerAdapter extends LegacyAbstractLogger implements LocationAwareLogger, LoggingEventAware, Serializable {
+
+ private static final long serialVersionUID = 6989384227325275811L;
+
+ final transient org.apache.log4j.Logger logger;
+
+ final static String FQCN_NOMINAL = org.slf4j.helpers.AbstractLogger.class.getName();
+ final static String FQCN_SUBSTITUE = FQCN_NOMINAL;
+ final static String FQCN_FLUENT = org.slf4j.spi.DefaultLoggingEventBuilder.class.getName();
+
+ // WARN: Reload4jLoggerAdapter constructor should have only package access so
+ // that only Reload4jLoggerFactory be able to create one.
+ Reload4jLoggerAdapter(org.apache.log4j.Logger logger) {
+ this.logger = logger;
+ this.name = logger.getName();
+ }
+
+ /**
+ * Is this logger instance enabled for the TRACE level?
+ *
+ * @return True if this Logger is enabled for level TRACE, false otherwise.
+ */
+ public boolean isTraceEnabled() {
+ return logger.isTraceEnabled();
+ }
+
+ /**
+ * Is this logger instance enabled for the DEBUG level?
+ *
+ * @return True if this Logger is enabled for level DEBUG, false otherwise.
+ */
+ public boolean isDebugEnabled() {
+ return logger.isDebugEnabled();
+ }
+
+ /**
+ * Is this logger instance enabled for the INFO level?
+ *
+ * @return True if this Logger is enabled for the INFO level, false otherwise.
+ */
+ public boolean isInfoEnabled() {
+ return logger.isInfoEnabled();
+ }
+
+ /**
+ * Is this logger instance enabled for the WARN level?
+ *
+ * @return True if this Logger is enabled for the WARN level, false otherwise.
+ */
+ public boolean isWarnEnabled() {
+ return logger.isEnabledFor(Level.WARN);
+ }
+
+ /**
+ * Is this logger instance enabled for level ERROR?
+ *
+ * @return True if this Logger is enabled for level ERROR, false otherwise.
+ */
+ public boolean isErrorEnabled() {
+ return logger.isEnabledFor(Level.ERROR);
+ }
+
+ @Override
+ public void log(Marker marker, String callerFQCN, int level, String msg, Object[] arguments, Throwable t) {
+ Level log4jLevel = toLog4jLevel(level);
+ NormalizedParameters np = NormalizedParameters.normalize(msg, arguments, t);
+ String formattedMessage = MessageFormatter.basicArrayFormat(np.getMessage(), np.getArguments());
+ logger.log(callerFQCN, log4jLevel, formattedMessage, np.getThrowable());
+ }
+
+ @Override
+ protected void handleNormalizedLoggingCall(org.slf4j.event.Level level, Marker marker, String msg, Object[] arguments, Throwable throwable) {
+ Level log4jLevel = toLog4jLevel(level.toInt());
+ String formattedMessage = MessageFormatter.basicArrayFormat(msg, arguments);
+ logger.log(getFullyQualifiedCallerName(), log4jLevel, formattedMessage, throwable);
+ }
+
+ /**
+ * Called by {@link SubstituteLogger} or by {@link LoggingEventBuilder} instances
+ * @param event
+ */
+ public void log(LoggingEvent event) {
+ Level log4jLevel = toLog4jLevel(event.getLevel().toInt());
+ if (!logger.isEnabledFor(log4jLevel))
+ return;
+
+ org.apache.log4j.spi.LoggingEvent log4jevent = event2Log4jEvent(event, log4jLevel);
+ logger.callAppenders(log4jevent);
+
+ }
+
+ private org.apache.log4j.spi.LoggingEvent event2Log4jEvent(LoggingEvent event, Level log4jLevel) {
+
+ String formattedMessage = MessageFormatter.basicArrayFormat(event.getMessage(), event.getArgumentArray());
+
+ LocationInfo locationInfo = null;
+ String fqcn = null;
+
+ if (event instanceof SubstituteLoggingEvent) {
+ locationInfo = new LocationInfo(NA_SUBST, NA_SUBST, NA_SUBST, "0");
+ fqcn = FQCN_SUBSTITUE;
+ } else {
+ fqcn = FQCN_FLUENT;
+ }
+
+ ThrowableInformation ti = null;
+ Throwable t = event.getThrowable();
+ if (t != null)
+ ti = new ThrowableInformation(t);
+
+ if(event instanceof DefaultLoggingEvent) {
+ DefaultLoggingEvent defaultLoggingEvent = (DefaultLoggingEvent) event;
+ defaultLoggingEvent.setTimeStamp(System.currentTimeMillis());
+ }
+
+ org.apache.log4j.spi.LoggingEvent log4jEvent = new org.apache.log4j.spi.LoggingEvent(fqcn, logger, event.getTimeStamp(), log4jLevel, formattedMessage,
+ event.getThreadName(), ti, null, locationInfo, null);
+
+ return log4jEvent;
+ }
+
+ private Level toLog4jLevel(int slf4jLevelInt) {
+ Level log4jLevel;
+ switch (slf4jLevelInt) {
+ case LocationAwareLogger.TRACE_INT:
+ log4jLevel = Level.TRACE;
+ break;
+ case LocationAwareLogger.DEBUG_INT:
+ log4jLevel = Level.DEBUG;
+ break;
+ case LocationAwareLogger.INFO_INT:
+ log4jLevel = Level.INFO;
+ break;
+ case LocationAwareLogger.WARN_INT:
+ log4jLevel = Level.WARN;
+ break;
+ case LocationAwareLogger.ERROR_INT:
+ log4jLevel = Level.ERROR;
+ break;
+ default:
+ throw new IllegalStateException("Level number " + slf4jLevelInt + " is not recognized.");
+ }
+ return log4jLevel;
+ }
+
+ @Override
+ protected String getFullyQualifiedCallerName() {
+ return FQCN_NOMINAL;
+ }
+
+}
diff --git a/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerFactory.java b/slf4j-reload4j/src/main/java/org/slf4j/reload4j/Reload4jLoggerFactory.java
index e801f9cc..0aca814e 100644
--- a/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerFactory.java
+++ b/slf4j-reload4j/src/main/java/org/slf4j/reload4j/Reload4jLoggerFactory.java
@@ -22,7 +22,7 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j.impl;
+package org.slf4j.reload4j;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -30,20 +30,41 @@ import java.util.concurrent.ConcurrentMap;
import org.apache.log4j.LogManager;
import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
+import org.slf4j.helpers.Reporter;
+import org.slf4j.helpers.Util;
/**
* Log4jLoggerFactory is an implementation of {@link ILoggerFactory} returning
- * the appropriate named {@link Log4jLoggerAdapter} instance.
+ * the appropriate named {@link Reload4jLoggerAdapter} instance.
*
* @author Ceki G&uuml;lc&uuml;
*/
-public class Log4jLoggerFactory implements ILoggerFactory {
+public class Reload4jLoggerFactory implements ILoggerFactory {
+
+ private static final String LOG4J_DELEGATION_LOOP_URL = "http://www.slf4j.org/codes.html#log4jDelegationLoop";
+
+ // check for delegation loops
+ static {
+ try {
+ Class.forName("org.apache.log4j.Log4jLoggerFactory");
+ String part1 = "Detected both log4j-over-slf4j.jar AND bound slf4j-log4j12.jar on the class path, preempting StackOverflowError. ";
+ String part2 = "See also " + LOG4J_DELEGATION_LOOP_URL + " for more details.";
+
+ Reporter.error(part1);
+ Reporter.error(part2);
+ throw new IllegalStateException(part1 + part2);
+ } catch (ClassNotFoundException e) {
+ // this is the good case
+ }
+ }
// key: name (String), value: a Log4jLoggerAdapter;
ConcurrentMap<String, Logger> loggerMap;
- public Log4jLoggerFactory() {
- loggerMap = new ConcurrentHashMap<String, Logger>();
+ public Reload4jLoggerFactory() {
+ loggerMap = new ConcurrentHashMap<>();
+ // force log4j to initialize
+ org.apache.log4j.LogManager.getRootLogger();
}
/*
@@ -62,7 +83,7 @@ public class Log4jLoggerFactory implements ILoggerFactory {
else
log4jLogger = LogManager.getLogger(name);
- Logger newInstance = new Log4jLoggerAdapter(log4jLogger);
+ Logger newInstance = new Reload4jLoggerAdapter(log4jLogger);
Logger oldInstance = loggerMap.putIfAbsent(name, newInstance);
return oldInstance == null ? newInstance : oldInstance;
}
diff --git a/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jMDCAdapter.java b/slf4j-reload4j/src/main/java/org/slf4j/reload4j/Reload4jMDCAdapter.java
index 95b8ed02..8c874a68 100644
--- a/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jMDCAdapter.java
+++ b/slf4j-reload4j/src/main/java/org/slf4j/reload4j/Reload4jMDCAdapter.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2004-2011 QOS.ch
+ * Copyright (c) 2004-2022 QOS.ch Sarl (Switzerland)
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
@@ -22,16 +22,20 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j.impl;
+package org.slf4j.reload4j;
+import java.util.Deque;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
+import org.slf4j.helpers.ThreadLocalMapOfStacks;
import org.slf4j.spi.MDCAdapter;
-public class Log4jMDCAdapter implements MDCAdapter {
+public class Reload4jMDCAdapter implements MDCAdapter {
+ private final ThreadLocalMapOfStacks threadLocalMapOfDeques = new ThreadLocalMapOfStacks();
+
+ @Override
public void clear() {
@SuppressWarnings("rawtypes")
Map map = org.apache.log4j.MDC.getContext();
@@ -40,6 +44,7 @@ public class Log4jMDCAdapter implements MDCAdapter {
}
}
+ @Override
public String get(String key) {
return (String) org.apache.log4j.MDC.get(key);
}
@@ -47,19 +52,21 @@ public class Log4jMDCAdapter implements MDCAdapter {
/**
* Put a context value (the <code>val</code> parameter) as identified with
* the <code>key</code> parameter into the current thread's context map. The
- * <code>key</code> parameter cannot be null. Log4j does <em>not</em>
+ * <code>key</code> parameter cannot be null. Log4j does <em>not</em>
* support null for the <code>val</code> parameter.
*
* <p>
* This method delegates all work to log4j's MDC.
*
* @throws IllegalArgumentException
- * in case the "key" or <b>"val"</b> parameter is null
+ * in case the "key" or <b>"val"</b> parameter is null
*/
+ @Override
public void put(String key, String val) {
org.apache.log4j.MDC.put(key, val);
}
+ @Override
public void remove(String key) {
org.apache.log4j.MDC.remove(key);
}
@@ -75,17 +82,45 @@ public class Log4jMDCAdapter implements MDCAdapter {
}
@SuppressWarnings({ "rawtypes", "unchecked" })
- public void setContextMap(Map contextMap) {
+ @Override
+ public void setContextMap(Map<String, String> contextMap) {
Map old = org.apache.log4j.MDC.getContext();
+
+ // we must cater for the case where the contextMap argument is null
+ if (contextMap == null) {
+ if (old != null) {
+ old.clear();
+ }
+ return;
+ }
+
if (old == null) {
- Iterator entrySetIterator = contextMap.entrySet().iterator();
- while (entrySetIterator.hasNext()) {
- Map.Entry mapEntry = (Map.Entry) entrySetIterator.next();
- org.apache.log4j.MDC.put((String) mapEntry.getKey(), mapEntry.getValue());
+ for (Map.Entry<String, String> mapEntry : contextMap.entrySet()) {
+ org.apache.log4j.MDC.put(mapEntry.getKey(), mapEntry.getValue());
}
} else {
old.clear();
old.putAll(contextMap);
}
}
+
+ @Override
+ public void pushByKey(String key, String value) {
+ threadLocalMapOfDeques.pushByKey(key, value);
+ }
+
+ @Override
+ public String popByKey(String key) {
+ return threadLocalMapOfDeques.popByKey(key);
+ }
+
+ @Override
+ public Deque<String> getCopyOfDequeByKey(String key) {
+ return threadLocalMapOfDeques.getCopyOfDequeByKey(key);
+ }
+
+ @Override
+ public void clearDequeByKey(String key) {
+ threadLocalMapOfDeques.clearDequeByKey(key);
+ }
}
diff --git a/slf4j-reload4j/src/main/java/org/slf4j/reload4j/Reload4jServiceProvider.java b/slf4j-reload4j/src/main/java/org/slf4j/reload4j/Reload4jServiceProvider.java
new file mode 100644
index 00000000..ed023b31
--- /dev/null
+++ b/slf4j-reload4j/src/main/java/org/slf4j/reload4j/Reload4jServiceProvider.java
@@ -0,0 +1,62 @@
+package org.slf4j.reload4j;
+
+import org.apache.log4j.Level;
+import org.slf4j.ILoggerFactory;
+import org.slf4j.IMarkerFactory;
+import org.slf4j.helpers.BasicMarkerFactory;
+import org.slf4j.helpers.Reporter;
+import org.slf4j.helpers.Util;
+import org.slf4j.spi.MDCAdapter;
+import org.slf4j.spi.SLF4JServiceProvider;
+
+public class Reload4jServiceProvider implements SLF4JServiceProvider {
+
+ /**
+ * Declare the version of the SLF4J API this implementation is compiled against.
+ * The value of this field is modified with each major release.
+ */
+ // to avoid constant folding by the compiler, this field must *not* be final
+ public static String REQUESTED_API_VERSION = "2.0.99"; // !final
+
+ private ILoggerFactory loggerFactory;
+ private IMarkerFactory markerFactory;
+ private MDCAdapter mdcAdapter;
+
+ public Reload4jServiceProvider() {
+ try {
+ @SuppressWarnings("unused")
+ Level level = Level.TRACE;
+ } catch (NoSuchFieldError nsfe) {
+ Reporter.error("This version of SLF4J requires log4j version 1.2.12 or later. See also http://www.slf4j.org/codes.html#log4j_version");
+ }
+ }
+
+ @Override
+ public void initialize() {
+ loggerFactory = new Reload4jLoggerFactory();
+ markerFactory = new BasicMarkerFactory();
+ mdcAdapter = new Reload4jMDCAdapter();
+ }
+
+ @Override
+ public ILoggerFactory getLoggerFactory() {
+ return loggerFactory;
+ }
+
+
+ @Override
+ public IMarkerFactory getMarkerFactory() {
+ return markerFactory;
+ }
+
+
+ @Override
+ public MDCAdapter getMDCAdapter() {
+ return mdcAdapter;
+ }
+
+ @Override
+ public String getRequestedApiVersion() {
+ return REQUESTED_API_VERSION;
+ }
+}
diff --git a/slf4j-reload4j/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider b/slf4j-reload4j/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider
new file mode 100644
index 00000000..b81f3e12
--- /dev/null
+++ b/slf4j-reload4j/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider
@@ -0,0 +1 @@
+org.slf4j.reload4j.Reload4jServiceProvider
diff --git a/slf4j-reload4j/src/test/java/org/slf4j/reload4j/EventFieldsTest.java b/slf4j-reload4j/src/test/java/org/slf4j/reload4j/EventFieldsTest.java
new file mode 100644
index 00000000..bfff3e3f
--- /dev/null
+++ b/slf4j-reload4j/src/test/java/org/slf4j/reload4j/EventFieldsTest.java
@@ -0,0 +1,61 @@
+package org.slf4j.reload4j;
+
+import org.apache.log4j.spi.LoggingEvent;
+import org.junit.After;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+public class EventFieldsTest {
+
+ // value of LogManager.DEFAULT_CONFIGURATION_KEY;
+ static String CONFIG_FILE_KEY = "log4j.configuration";
+
+ @After
+ public void tearDown() throws Exception {
+ System.clearProperty(CONFIG_FILE_KEY);
+ }
+
+ @Test
+ public void testWhetherEventsFieldsAreSet() {
+ System.setProperty(CONFIG_FILE_KEY, "eventFields.properties");
+ Logger logger = LoggerFactory.getLogger(this.getClass());
+ logger.info("hello");
+ logger.atInfo().setMessage("hello").log();
+
+ org.slf4j.reload4j.Reload4jLoggerAdapter rootReload4j = (org.slf4j.reload4j.Reload4jLoggerAdapter) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+
+
+ ListAppender listAppender = (ListAppender) rootReload4j.logger.getAppender("LIST");
+
+ assertNotNull(listAppender);
+ assertNotNull(listAppender.list);
+
+ List<LoggingEvent> eventList = listAppender.list;
+
+ assertEquals(2, eventList.size());
+
+ LoggingEvent loggingEvent0 = eventList.get(0);
+ long timeStamp0 = loggingEvent0.getTimeStamp();
+ String threadName0 = loggingEvent0.getThreadName();
+ assertTrue(timeStamp0 != 0);
+ assertNotNull(threadName0);
+ assertFalse(threadName0.isEmpty());
+
+ LoggingEvent loggingEvent1 = eventList.get(1);
+ long timeStamp1 = loggingEvent1.getTimeStamp();
+ String threadName1 = loggingEvent1.getThreadName();
+ assertTrue(timeStamp1 != 0);
+ assertTrue(timeStamp1 >= timeStamp0);
+ assertNotNull(threadName1);
+ assertFalse(threadName1.isEmpty());
+ assertEquals(threadName0, threadName1);
+
+ }
+
+
+}
diff --git a/slf4j-log4j12/src/test/java/org/slf4j/InvocationTest.java b/slf4j-reload4j/src/test/java/org/slf4j/reload4j/InvocationTest.java
index b3246f50..12d6db19 100644
--- a/slf4j-log4j12/src/test/java/org/slf4j/InvocationTest.java
+++ b/slf4j-reload4j/src/test/java/org/slf4j/reload4j/InvocationTest.java
@@ -22,14 +22,25 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j;
+package org.slf4j.reload4j;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.spi.LoggingEvent;
-
-import junit.framework.TestCase;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
/**
* Test whether invoking the SLF4J API causes problems or not.
@@ -37,37 +48,35 @@ import junit.framework.TestCase;
* @author Ceki Gulcu
*
*/
-public class InvocationTest extends TestCase {
+public class InvocationTest {
ListAppender listAppender = new ListAppender();
org.apache.log4j.Logger root;
- public InvocationTest(String arg0) {
- super(arg0);
- }
-
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() throws Exception {
root = org.apache.log4j.Logger.getRootLogger();
root.addAppender(listAppender);
-
}
- protected void tearDown() throws Exception {
- super.tearDown();
+ @After
+ public void tearDown() throws Exception {
root.getLoggerRepository().resetConfiguration();
}
+ @Test
public void test1() {
+
Logger logger = LoggerFactory.getLogger("test1");
logger.debug("Hello world.");
assertEquals(1, listAppender.list.size());
}
+ @Test
public void test2() {
- Integer i1 = new Integer(1);
- Integer i2 = new Integer(2);
- Integer i3 = new Integer(3);
+ Integer i1 = Integer.valueOf(1);
+ Integer i2 = Integer.valueOf(2);
+ Integer i3 = Integer.valueOf(3);
Exception e = new Exception("This is a test exception.");
Logger logger = LoggerFactory.getLogger("test2");
@@ -85,11 +94,12 @@ public class InvocationTest extends TestCase {
logger.warn("Hello world 3", e);
logger.error("Hello world 4.");
- logger.error("Hello world {}", new Integer(3));
+ logger.error("Hello world {}", Integer.valueOf(3));
logger.error("Hello world 4.", e);
assertEquals(11, listAppender.list.size());
}
+ @Test
public void testNull() {
Logger logger = LoggerFactory.getLogger("testNull");
logger.trace(null);
@@ -106,18 +116,22 @@ public class InvocationTest extends TestCase {
assertEquals(8, listAppender.list.size());
}
- // http://bugzilla.slf4j.org/show_bug.cgi?id=78
+ // http://jira.qos.ch/browse/SLF4J-69
+ // formerly http://bugzilla.slf4j.org/show_bug.cgi?id=78
+ @Test
public void testNullParameter_BUG78() {
Logger logger = LoggerFactory.getLogger("testNullParameter_BUG78");
String[] parameters = null;
String msg = "hello {}";
- logger.debug(msg, parameters);
+ logger.debug(msg, (Object[]) parameters);
+
assertEquals(1, listAppender.list.size());
LoggingEvent e = (LoggingEvent) listAppender.list.get(0);
assertEquals(msg, e.getMessage());
}
+ @Test
public void testMarker() {
Logger logger = LoggerFactory.getLogger("testMarker");
Marker blue = MarkerFactory.getMarker("BLUE");
@@ -139,6 +153,7 @@ public class InvocationTest extends TestCase {
assertEquals(12, listAppender.list.size());
}
+ @Test
public void testMDC() {
MDC.put("k", "v");
assertNotNull(MDC.get("k"));
@@ -159,8 +174,9 @@ public class InvocationTest extends TestCase {
}
}
+ @Test
public void testMDCContextMapValues() {
- Map<String, String> map = new HashMap<String, String>();
+ Map<String, String> map = new HashMap<>();
map.put("ka", "va");
map.put("kb", "vb");
@@ -172,4 +188,22 @@ public class InvocationTest extends TestCase {
assertEquals("vb", MDC.get("kb"));
}
+ @Test
+ public void testCallerInfo() {
+ Logger logger = LoggerFactory.getLogger("testMarker");
+ listAppender.extractLocationInfo = true;
+ logger.debug("hello");
+ LoggingEvent event = listAppender.list.get(0);
+ assertEquals(this.getClass().getName(), event.getLocationInformation().getClassName());
+ }
+
+ @Test
+ public void testCallerInfoWithFluentAPI() {
+ Logger logger = LoggerFactory.getLogger("testMarker");
+ listAppender.extractLocationInfo = true;
+ logger.atDebug().log("hello");
+ LoggingEvent event = listAppender.list.get(0);
+ assertEquals(this.getClass().getName(), event.getLocationInformation().getClassName());
+ }
+
}
diff --git a/slf4j-log4j12/src/test/java/org/slf4j/ListAppender.java b/slf4j-reload4j/src/test/java/org/slf4j/reload4j/ListAppender.java
index 29596899..92cd9d32 100644
--- a/slf4j-log4j12/src/test/java/org/slf4j/ListAppender.java
+++ b/slf4j-reload4j/src/test/java/org/slf4j/reload4j/ListAppender.java
@@ -22,7 +22,7 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j;
+package org.slf4j.reload4j;
import java.util.ArrayList;
import java.util.List;
@@ -32,7 +32,7 @@ import org.apache.log4j.spi.LoggingEvent;
public class ListAppender extends AppenderSkeleton {
- public List<LoggingEvent> list = new ArrayList<LoggingEvent>();
+ public List<LoggingEvent> list = new ArrayList<>();
public boolean extractLocationInfo = false;
diff --git a/slf4j-log4j12/src/test/java/org/slf4j/impl/RecursiveInitializationTest.java b/slf4j-reload4j/src/test/java/org/slf4j/reload4j/RecursiveInitializationTest.java
index 23a24437..ff68f2da 100644
--- a/slf4j-log4j12/src/test/java/org/slf4j/impl/RecursiveInitializationTest.java
+++ b/slf4j-reload4j/src/test/java/org/slf4j/reload4j/RecursiveInitializationTest.java
@@ -22,35 +22,32 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j.impl;
+package org.slf4j.reload4j;
import java.util.Random;
-import junit.framework.TestCase;
-
+import org.junit.After;
+import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class RecursiveInitializationTest extends TestCase {
+public class RecursiveInitializationTest {
// value of LogManager.DEFAULT_CONFIGURATION_KEY;
static String CONFIG_FILE_KEY = "log4j.configuration";
int diff = new Random().nextInt(10000);
+ String loggerName = "org.slf4j.impl.RecursiveInitializationTest";
- protected void setUp() throws Exception {
- System.setProperty(CONFIG_FILE_KEY, "recursiveInit.properties");
- super.setUp();
- }
-
- protected void tearDown() throws Exception {
+ @After
+ public void tearDown() throws Exception {
System.clearProperty(CONFIG_FILE_KEY);
- super.tearDown();
}
- public void testLog4j() {
- Logger logger = LoggerFactory.getLogger("x" + diff);
- System.out.println("logger class=" + logger.getClass().getName());
+ @Test
+ public void loggingDuringInitialization() {
+ System.setProperty(CONFIG_FILE_KEY, "recursiveInit.properties");
+ Logger logger = LoggerFactory.getLogger(loggerName + ".loggingDuringInitialization-" + diff);
logger.info("hello");
}
diff --git a/slf4j-reload4j/src/test/java/org/slf4j/reload4j/Reload4jMDCAdapterTest.java b/slf4j-reload4j/src/test/java/org/slf4j/reload4j/Reload4jMDCAdapterTest.java
new file mode 100644
index 00000000..fa343b45
--- /dev/null
+++ b/slf4j-reload4j/src/test/java/org/slf4j/reload4j/Reload4jMDCAdapterTest.java
@@ -0,0 +1,39 @@
+package org.slf4j.reload4j;
+
+import org.junit.Test;
+import org.slf4j.helpers.MDCAdapterTestBase;
+import org.slf4j.spi.MDCAdapter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+
+public class Reload4jMDCAdapterTest extends MDCAdapterTestBase {
+
+ protected MDCAdapter instantiateMDC() {
+ return new Reload4jMDCAdapter();
+ }
+
+
+ @Test
+ public void testClearingMDC() {
+ mdc.put("testKey", "testValue");
+ assertFalse(mdc.getCopyOfContextMap().isEmpty());
+ mdc.clear();
+ assertTrue(mdc.getCopyOfContextMap().isEmpty());
+ }
+
+ @Test
+ public void testSetContextMap() {
+ Map<String, String> map0 = new HashMap<>();
+ map0.put("key0", "val0");
+
+ mdc.setContextMap(map0);
+ Map map1 = mdc.getCopyOfContextMap();
+
+ assertEquals(map0, map1);
+ }
+
+
+}
diff --git a/slf4j-reload4j/src/test/java/org/slf4j/reload4j/Reload4jMultithreadedInitializationTest.java b/slf4j-reload4j/src/test/java/org/slf4j/reload4j/Reload4jMultithreadedInitializationTest.java
new file mode 100644
index 00000000..febde1e8
--- /dev/null
+++ b/slf4j-reload4j/src/test/java/org/slf4j/reload4j/Reload4jMultithreadedInitializationTest.java
@@ -0,0 +1,72 @@
+/**
+ * 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.reload4j;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.util.List;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.spi.LoggingEvent;
+import org.junit.After;
+import org.junit.Before;
+import org.slf4j.reload4j.testHarness.RecursiveAppender;
+
+public class Reload4jMultithreadedInitializationTest extends org.slf4j.testHarness.MultithreadedInitializationTest {
+ static int NUM_LINES_BY_RECURSIVE_APPENDER = 3;
+
+ // value of LogManager.DEFAULT_CONFIGURATION_KEY;
+ static String CONFIG_FILE_KEY = "log4j.configuration";
+ final String loggerName = this.getClass().getName();
+
+ @Before
+ public void setup() {
+ System.setProperty(CONFIG_FILE_KEY, "recursiveInitWithActivationDelay.properties");
+ System.out.println("THREAD_COUNT=" + THREAD_COUNT);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ System.clearProperty(CONFIG_FILE_KEY);
+ }
+
+ protected long getRecordedEventCount() {
+ List<LoggingEvent> eventList = getRecordedEvents();
+ assertNotNull(eventList);
+ return eventList.size();
+ }
+
+ protected int extraLogEvents() {
+ return NUM_LINES_BY_RECURSIVE_APPENDER;
+ }
+
+ private List<LoggingEvent> getRecordedEvents() {
+ org.apache.log4j.Logger root = LogManager.getRootLogger();
+ RecursiveAppender ra = (RecursiveAppender) root.getAppender("RECURSIVE");
+ assertNotNull(ra);
+ return ra.events;
+ }
+
+}
diff --git a/slf4j-log4j12/src/test/java/org/slf4j/impl/RecursiveAppender.java b/slf4j-reload4j/src/test/java/org/slf4j/reload4j/testHarness/RecursiveAppender.java
index 0dc34b01..3857ba32 100644
--- a/slf4j-log4j12/src/test/java/org/slf4j/impl/RecursiveAppender.java
+++ b/slf4j-reload4j/src/test/java/org/slf4j/reload4j/testHarness/RecursiveAppender.java
@@ -22,8 +22,10 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j.impl;
+package org.slf4j.reload4j.testHarness;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Random;
import org.apache.log4j.AppenderSkeleton;
@@ -34,15 +36,20 @@ import org.slf4j.LoggerFactory;
public class RecursiveAppender extends AppenderSkeleton {
int diff = new Random().nextInt();
+ int activationDelay = 0;
+ String loggerName = "org.slf4j.impl.RecursiveAppender" + diff;
+
+ public List<LoggingEvent> 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("XXXXXXX 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 class RecursiveAppender extends AppenderSkeleton {
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-reload4j/src/test/resources/eventFields.properties b/slf4j-reload4j/src/test/resources/eventFields.properties
new file mode 100644
index 00000000..5922ca9f
--- /dev/null
+++ b/slf4j-reload4j/src/test/resources/eventFields.properties
@@ -0,0 +1,4 @@
+log4j.debug=true
+log4j.rootLogger=DEBUG, LIST
+
+log4j.appender.LIST=org.slf4j.reload4j.ListAppender
diff --git a/slf4j-log4j12/src/test/resources/recursiveInit.properties b/slf4j-reload4j/src/test/resources/recursiveInit.properties
index a8d5d765..a62a15e2 100644
--- a/slf4j-log4j12/src/test/resources/recursiveInit.properties
+++ b/slf4j-reload4j/src/test/resources/recursiveInit.properties
@@ -3,6 +3,7 @@ log4j.rootLogger=DEBUG, RECURSIVE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
-log4j.appender.CONSOLE.layout.ConversionPattern=%d [%t] %c - %m%n
+log4j.appender.CONSOLE.layout.ConversionPattern=[%t] %c - %m%n
-log4j.appender.RECURSIVE=org.slf4j.impl.RecursiveAppender \ No newline at end of file
+log4j.appender.RECURSIVE=org.slf4j.reload4j.testHarness.RecursiveAppender
+ \ No newline at end of file
diff --git a/slf4j-reload4j/src/test/resources/recursiveInitWithActivationDelay.properties b/slf4j-reload4j/src/test/resources/recursiveInitWithActivationDelay.properties
new file mode 100644
index 00000000..957894dd
--- /dev/null
+++ b/slf4j-reload4j/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 [%t] %c - %m%n
+
+log4j.appender.RECURSIVE=org.slf4j.reload4j.testHarness.RecursiveAppender
+log4j.appender.RECURSIVE.activationDelay=10
diff --git a/slf4j-simple/LICENSE.txt b/slf4j-simple/LICENSE.txt
index 508a2728..e4079f54 100644
--- a/slf4j-simple/LICENSE.txt
+++ b/slf4j-simple/LICENSE.txt
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2007 QOS.ch
+Copyright (c) 2004-2023 QOS.ch
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/slf4j-simple/pom.xml b/slf4j-simple/pom.xml
index 79d5b966..776efc66 100755
--- a/slf4j-simple/pom.xml
+++ b/slf4j-simple/pom.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
@@ -6,42 +7,35 @@
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
- <version>1.7.13-SNAPSHOT</version>
+ <version>2.0.12</version>
+ <relativePath>../parent/pom.xml</relativePath>
</parent>
<artifactId>slf4j-simple</artifactId>
<packaging>jar</packaging>
- <name>SLF4J Simple Binding</name>
- <description>SLF4J Simple binding</description>
+ <name>SLF4J Simple Provider</name>
+ <description>SLF4J Simple Provider</description>
<url>http://www.slf4j.org</url>
+ <properties>
+ <module-name>org.slf4j.simple</module-name>
+ <slf4j.provider.implementation>org.slf4j.simple.SimpleServiceProvider</slf4j.provider.implementation>
+ <slf4j.provider.type>simple</slf4j.provider.type>
+ </properties>
+
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
- </dependencies>
-
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <archive>
- <manifestEntries>
- <Bundle-Version>${parsedVersion.osgiVersion}</Bundle-Version>
- <Bundle-Description>${project.description}</Bundle-Description>
- <Implementation-Version>${project.version}</Implementation-Version>
- </manifestEntries>
- <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
- </archive>
- </configuration>
- </plugin>
-
- </plugins>
- </build>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <type>test-jar</type>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
-</project> \ No newline at end of file
+</project>
diff --git a/slf4j-simple/src/main/java/org/slf4j/impl/SimpleLogger.java b/slf4j-simple/src/main/java/org/slf4j/impl/SimpleLogger.java
deleted file mode 100644
index 7b0abf95..00000000
--- a/slf4j-simple/src/main/java/org/slf4j/impl/SimpleLogger.java
+++ /dev/null
@@ -1,648 +0,0 @@
-/**
- * Copyright (c) 2004-2012 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 java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.helpers.FormattingTuple;
-import org.slf4j.helpers.MarkerIgnoringBase;
-import org.slf4j.helpers.MessageFormatter;
-import org.slf4j.helpers.Util;
-import org.slf4j.spi.LocationAwareLogger;
-
-/**
- * <p>Simple implementation of {@link Logger} that sends all enabled log messages,
- * for all defined loggers, to the console ({@code System.err}).
- * The following system properties are supported to configure the behavior of this logger:</p>
- *
- * <ul>
- * <li><code>org.slf4j.simpleLogger.logFile</code> - The output target which can be the <em>path</em> to a file, or
- * the special values "System.out" and "System.err". Default is "System.err".
- *
- * <li><code>org.slf4j.simpleLogger.defaultLogLevel</code> - Default log level for all instances of SimpleLogger.
- * Must be one of ("trace", "debug", "info", "warn", or "error"). If not specified, defaults to "info". </li>
- *
- * <li><code>org.slf4j.simpleLogger.log.<em>a.b.c</em></code> - Logging detail level for a SimpleLogger instance
- * named "a.b.c". Right-side value must be one of "trace", "debug", "info", "warn", or "error". When a SimpleLogger
- * named "a.b.c" is initialized, its level is assigned from this property. If unspecified, the level of nearest parent
- * logger will be used, and if none is set, then the value specified by
- * <code>org.slf4j.simpleLogger.defaultLogLevel</code> will be used.</li>
- *
- * <li><code>org.slf4j.simpleLogger.showDateTime</code> - Set to <code>true</code> if you want the current date and
- * time to be included in output messages. Default is <code>false</code></li>
- *
- * <li><code>org.slf4j.simpleLogger.dateTimeFormat</code> - The date and time format to be used in the output messages.
- * The pattern describing the date and time format is defined by
- * <a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/text/SimpleDateFormat.html"><code>SimpleDateFormat</code></a>.
- * If the format is not specified or is invalid, the number of milliseconds since start up will be output. </li>
- *
- * <li><code>org.slf4j.simpleLogger.showThreadName</code> -Set to <code>true</code> if you want to output the current
- * thread name. Defaults to <code>true</code>.</li>
- *
- * <li><code>org.slf4j.simpleLogger.showLogName</code> - Set to <code>true</code> if you want the Logger instance name
- * to be included in output messages. Defaults to <code>true</code>.</li>
- *
- * <li><code>org.slf4j.simpleLogger.showShortLogName</code> - Set to <code>true</code> if you want the last component
- * of the name to be included in output messages. Defaults to <code>false</code>.</li>
- *
- * <li><code>org.slf4j.simpleLogger.levelInBrackets</code> - Should the level string be output in brackets? Defaults
- * to <code>false</code>.</li>
- *
- * <li><code>org.slf4j.simpleLogger.warnLevelString</code> - The string value output for the warn level. Defaults
- * to <code>WARN</code>.</li>
-
- * </ul>
- *
- * <p>In addition to looking for system properties with the names specified above, this implementation also checks for
- * a class loader resource named <code>"simplelogger.properties"</code>, and includes any matching definitions
- * from this resource (if it exists).</p>
- *
- * <p>With no configuration, the default output includes the relative time in milliseconds, thread name, the level,
- * logger name, and the message followed by the line separator for the host. In log4j terms it amounts to the "%r [%t]
- * %level %logger - %m%n" pattern. </p>
- * <p>Sample output follows.</p>
- * <pre>
- * 176 [main] INFO examples.Sort - Populating an array of 2 elements in reverse order.
- * 225 [main] INFO examples.SortAlgo - Entered the sort method.
- * 304 [main] INFO examples.SortAlgo - Dump of integer array:
- * 317 [main] INFO examples.SortAlgo - Element [0] = 0
- * 331 [main] INFO examples.SortAlgo - Element [1] = 1
- * 343 [main] INFO examples.Sort - The next log statement should be an error message.
- * 346 [main] ERROR examples.SortAlgo - Tried to dump an uninitialized array.
- * at org.log4j.examples.SortAlgo.dump(SortAlgo.java:58)
- * at org.log4j.examples.Sort.main(Sort.java:64)
- * 467 [main] INFO examples.Sort - Exiting main method.
- * </pre>
- *
- * <p>This implementation is heavily inspired by
- * <a href="http://commons.apache.org/logging/">Apache Commons Logging</a>'s SimpleLog.</p>
- *
- * @author Ceki G&uuml;lc&uuml;
- * @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
- * @author Rod Waldhoff
- * @author Robert Burrell Donkin
- * @author C&eacute;drik LIME
- */
-public class SimpleLogger extends MarkerIgnoringBase {
-
- private static final long serialVersionUID = -632788891211436180L;
- private static final String CONFIGURATION_FILE = "simplelogger.properties";
-
- private static long START_TIME = System.currentTimeMillis();
- private static final Properties SIMPLE_LOGGER_PROPS = new Properties();
-
- private static final int LOG_LEVEL_TRACE = LocationAwareLogger.TRACE_INT;
- private static final int LOG_LEVEL_DEBUG = LocationAwareLogger.DEBUG_INT;
- private static final int LOG_LEVEL_INFO = LocationAwareLogger.INFO_INT;
- private static final int LOG_LEVEL_WARN = LocationAwareLogger.WARN_INT;
- private static final int LOG_LEVEL_ERROR = LocationAwareLogger.ERROR_INT;
-
- private static boolean INITIALIZED = false;
-
- private static int DEFAULT_LOG_LEVEL = LOG_LEVEL_INFO;
- private static boolean SHOW_DATE_TIME = false;
- private static String DATE_TIME_FORMAT_STR = null;
- private static DateFormat DATE_FORMATTER = null;
- private static boolean SHOW_THREAD_NAME = true;
- private static boolean SHOW_LOG_NAME = true;
- private static boolean SHOW_SHORT_LOG_NAME = false;
- private static String LOG_FILE = "System.err";
- private static PrintStream TARGET_STREAM = null;
- private static boolean LEVEL_IN_BRACKETS = false;
- private static String WARN_LEVEL_STRING = "WARN";
-
- /** All system properties used by <code>SimpleLogger</code> start with this prefix */
- public static final String SYSTEM_PREFIX = "org.slf4j.simpleLogger.";
-
- public static final String DEFAULT_LOG_LEVEL_KEY = SYSTEM_PREFIX + "defaultLogLevel";
- public static final String SHOW_DATE_TIME_KEY = SYSTEM_PREFIX + "showDateTime";
- public static final String DATE_TIME_FORMAT_KEY = SYSTEM_PREFIX + "dateTimeFormat";
- public static final String SHOW_THREAD_NAME_KEY = SYSTEM_PREFIX + "showThreadName";
- public static final String SHOW_LOG_NAME_KEY = SYSTEM_PREFIX + "showLogName";
- public static final String SHOW_SHORT_LOG_NAME_KEY = SYSTEM_PREFIX + "showShortLogName";
- public static final String LOG_FILE_KEY = SYSTEM_PREFIX + "logFile";
- public static final String LEVEL_IN_BRACKETS_KEY = SYSTEM_PREFIX + "levelInBrackets";
- public static final String WARN_LEVEL_STRING_KEY = SYSTEM_PREFIX + "warnLevelString";
-
- public static final String LOG_KEY_PREFIX = SYSTEM_PREFIX + "log.";
-
- private static String getStringProperty(String name) {
- String prop = null;
- try {
- prop = System.getProperty(name);
- } catch (SecurityException e) {
- ; // Ignore
- }
- return (prop == null) ? SIMPLE_LOGGER_PROPS.getProperty(name) : prop;
- }
-
- private static String getStringProperty(String name, String defaultValue) {
- String prop = getStringProperty(name);
- return (prop == null) ? defaultValue : prop;
- }
-
- private static boolean getBooleanProperty(String name, boolean defaultValue) {
- String prop = getStringProperty(name);
- return (prop == null) ? defaultValue : "true".equalsIgnoreCase(prop);
- }
-
- // Initialize class attributes.
- // Load properties file, if found.
- // Override with system properties.
- static void init() {
- INITIALIZED = true;
- loadProperties();
-
- String defaultLogLevelString = getStringProperty(DEFAULT_LOG_LEVEL_KEY, null);
- if (defaultLogLevelString != null)
- DEFAULT_LOG_LEVEL = stringToLevel(defaultLogLevelString);
-
- SHOW_LOG_NAME = getBooleanProperty(SHOW_LOG_NAME_KEY, SHOW_LOG_NAME);
- SHOW_SHORT_LOG_NAME = getBooleanProperty(SHOW_SHORT_LOG_NAME_KEY, SHOW_SHORT_LOG_NAME);
- SHOW_DATE_TIME = getBooleanProperty(SHOW_DATE_TIME_KEY, SHOW_DATE_TIME);
- SHOW_THREAD_NAME = getBooleanProperty(SHOW_THREAD_NAME_KEY, SHOW_THREAD_NAME);
- DATE_TIME_FORMAT_STR = getStringProperty(DATE_TIME_FORMAT_KEY, DATE_TIME_FORMAT_STR);
- LEVEL_IN_BRACKETS = getBooleanProperty(LEVEL_IN_BRACKETS_KEY, LEVEL_IN_BRACKETS);
- WARN_LEVEL_STRING = getStringProperty(WARN_LEVEL_STRING_KEY, WARN_LEVEL_STRING);
-
- LOG_FILE = getStringProperty(LOG_FILE_KEY, LOG_FILE);
- TARGET_STREAM = computeTargetStream(LOG_FILE);
-
- if (DATE_TIME_FORMAT_STR != null) {
- try {
- DATE_FORMATTER = new SimpleDateFormat(DATE_TIME_FORMAT_STR);
- } catch (IllegalArgumentException e) {
- Util.report("Bad date format in " + CONFIGURATION_FILE + "; will output relative time", e);
- }
- }
- }
-
- private static PrintStream computeTargetStream(String logFile) {
- if ("System.err".equalsIgnoreCase(logFile))
- return System.err;
- else if ("System.out".equalsIgnoreCase(logFile)) {
- return System.out;
- } else {
- try {
- FileOutputStream fos = new FileOutputStream(logFile);
- PrintStream printStream = new PrintStream(fos);
- return printStream;
- } catch (FileNotFoundException e) {
- Util.report("Could not open [" + logFile + "]. Defaulting to System.err", e);
- return System.err;
- }
- }
- }
-
- private static void loadProperties() {
- // Add props from the resource simplelogger.properties
- InputStream in = AccessController.doPrivileged(new PrivilegedAction<InputStream>() {
- public InputStream run() {
- ClassLoader threadCL = Thread.currentThread().getContextClassLoader();
- if (threadCL != null) {
- return threadCL.getResourceAsStream(CONFIGURATION_FILE);
- } else {
- return ClassLoader.getSystemResourceAsStream(CONFIGURATION_FILE);
- }
- }
- });
- if (null != in) {
- try {
- SIMPLE_LOGGER_PROPS.load(in);
- in.close();
- } catch (java.io.IOException e) {
- // ignored
- }
- }
- }
-
- /** The current log level */
- protected int currentLogLevel = LOG_LEVEL_INFO;
- /** The short name of this simple log instance */
- private transient String shortLogName = null;
-
- /**
- * Package access allows only {@link SimpleLoggerFactory} to instantiate
- * SimpleLogger instances.
- */
- SimpleLogger(String name) {
- if (!INITIALIZED) {
- init();
- }
- this.name = name;
-
- String levelString = recursivelyComputeLevelString();
- if (levelString != null) {
- this.currentLogLevel = stringToLevel(levelString);
- } else {
- this.currentLogLevel = DEFAULT_LOG_LEVEL;
- }
- }
-
- String recursivelyComputeLevelString() {
- String tempName = name;
- String levelString = null;
- int indexOfLastDot = tempName.length();
- while ((levelString == null) && (indexOfLastDot > -1)) {
- tempName = tempName.substring(0, indexOfLastDot);
- levelString = getStringProperty(LOG_KEY_PREFIX + tempName, null);
- indexOfLastDot = String.valueOf(tempName).lastIndexOf(".");
- }
- return levelString;
- }
-
- private static int stringToLevel(String levelStr) {
- if ("trace".equalsIgnoreCase(levelStr)) {
- return LOG_LEVEL_TRACE;
- } else if ("debug".equalsIgnoreCase(levelStr)) {
- return LOG_LEVEL_DEBUG;
- } else if ("info".equalsIgnoreCase(levelStr)) {
- return LOG_LEVEL_INFO;
- } else if ("warn".equalsIgnoreCase(levelStr)) {
- return LOG_LEVEL_WARN;
- } else if ("error".equalsIgnoreCase(levelStr)) {
- return LOG_LEVEL_ERROR;
- }
- // assume INFO by default
- return LOG_LEVEL_INFO;
- }
-
- /**
- * This is our internal implementation for logging regular (non-parameterized)
- * log messages.
- *
- * @param level One of the LOG_LEVEL_XXX constants defining the log level
- * @param message The message itself
- * @param t The exception whose stack trace should be logged
- */
- private void log(int level, String message, Throwable t) {
- if (!isLevelEnabled(level)) {
- return;
- }
-
- StringBuilder buf = new StringBuilder(32);
-
- // Append date-time if so configured
- if (SHOW_DATE_TIME) {
- if (DATE_FORMATTER != null) {
- buf.append(getFormattedDate());
- buf.append(' ');
- } else {
- buf.append(System.currentTimeMillis() - START_TIME);
- buf.append(' ');
- }
- }
-
- // Append current thread name if so configured
- if (SHOW_THREAD_NAME) {
- buf.append('[');
- buf.append(Thread.currentThread().getName());
- buf.append("] ");
- }
-
- if (LEVEL_IN_BRACKETS)
- buf.append('[');
-
- // Append a readable representation of the log level
- switch (level) {
- case LOG_LEVEL_TRACE:
- buf.append("TRACE");
- break;
- case LOG_LEVEL_DEBUG:
- buf.append("DEBUG");
- break;
- case LOG_LEVEL_INFO:
- buf.append("INFO");
- break;
- case LOG_LEVEL_WARN:
- buf.append(WARN_LEVEL_STRING);
- break;
- case LOG_LEVEL_ERROR:
- buf.append("ERROR");
- break;
- }
- if (LEVEL_IN_BRACKETS)
- buf.append(']');
- buf.append(' ');
-
- // Append the name of the log instance if so configured
- if (SHOW_SHORT_LOG_NAME) {
- if (shortLogName == null)
- shortLogName = computeShortName();
- buf.append(String.valueOf(shortLogName)).append(" - ");
- } else if (SHOW_LOG_NAME) {
- buf.append(String.valueOf(name)).append(" - ");
- }
-
- // Append the message
- buf.append(message);
-
- write(buf, t);
-
- }
-
- void write(StringBuilder buf, Throwable t) {
- TARGET_STREAM.println(buf.toString());
- if (t != null) {
- t.printStackTrace(TARGET_STREAM);
- }
- TARGET_STREAM.flush();
- }
-
- private String getFormattedDate() {
- Date now = new Date();
- String dateText;
- synchronized (DATE_FORMATTER) {
- dateText = DATE_FORMATTER.format(now);
- }
- return dateText;
- }
-
- private String computeShortName() {
- return name.substring(name.lastIndexOf(".") + 1);
- }
-
- /**
- * For formatted messages, first substitute arguments and then log.
- *
- * @param level
- * @param format
- * @param arg1
- * @param arg2
- */
- private void formatAndLog(int level, String format, Object arg1, Object arg2) {
- if (!isLevelEnabled(level)) {
- return;
- }
- FormattingTuple tp = MessageFormatter.format(format, arg1, arg2);
- log(level, tp.getMessage(), tp.getThrowable());
- }
-
- /**
- * For formatted messages, first substitute arguments and then log.
- *
- * @param level
- * @param format
- * @param arguments a list of 3 ore more arguments
- */
- private void formatAndLog(int level, String format, Object... arguments) {
- if (!isLevelEnabled(level)) {
- return;
- }
- FormattingTuple tp = MessageFormatter.arrayFormat(format, arguments);
- log(level, tp.getMessage(), tp.getThrowable());
- }
-
- /**
- * Is the given log level currently enabled?
- *
- * @param logLevel is this level enabled?
- */
- protected boolean isLevelEnabled(int logLevel) {
- // log level are numerically ordered so can use simple numeric
- // comparison
- return (logLevel >= currentLogLevel);
- }
-
- /** Are {@code trace} messages currently enabled? */
- public boolean isTraceEnabled() {
- return isLevelEnabled(LOG_LEVEL_TRACE);
- }
-
- /**
- * A simple implementation which logs messages of level TRACE according
- * to the format outlined above.
- */
- public void trace(String msg) {
- log(LOG_LEVEL_TRACE, msg, null);
- }
-
- /**
- * Perform single parameter substitution before logging the message of level
- * TRACE according to the format outlined above.
- */
- public void trace(String format, Object param1) {
- formatAndLog(LOG_LEVEL_TRACE, format, param1, null);
- }
-
- /**
- * Perform double parameter substitution before logging the message of level
- * TRACE according to the format outlined above.
- */
- public void trace(String format, Object param1, Object param2) {
- formatAndLog(LOG_LEVEL_TRACE, format, param1, param2);
- }
-
- /**
- * Perform double parameter substitution before logging the message of level
- * TRACE according to the format outlined above.
- */
- public void trace(String format, Object... argArray) {
- formatAndLog(LOG_LEVEL_TRACE, format, argArray);
- }
-
- /** Log a message of level TRACE, including an exception. */
- public void trace(String msg, Throwable t) {
- log(LOG_LEVEL_TRACE, msg, t);
- }
-
- /** Are {@code debug} messages currently enabled? */
- public boolean isDebugEnabled() {
- return isLevelEnabled(LOG_LEVEL_DEBUG);
- }
-
- /**
- * A simple implementation which logs messages of level DEBUG according
- * to the format outlined above.
- */
- public void debug(String msg) {
- log(LOG_LEVEL_DEBUG, msg, null);
- }
-
- /**
- * Perform single parameter substitution before logging the message of level
- * DEBUG according to the format outlined above.
- */
- public void debug(String format, Object param1) {
- formatAndLog(LOG_LEVEL_DEBUG, format, param1, null);
- }
-
- /**
- * Perform double parameter substitution before logging the message of level
- * DEBUG according to the format outlined above.
- */
- public void debug(String format, Object param1, Object param2) {
- formatAndLog(LOG_LEVEL_DEBUG, format, param1, param2);
- }
-
- /**
- * Perform double parameter substitution before logging the message of level
- * DEBUG according to the format outlined above.
- */
- public void debug(String format, Object... argArray) {
- formatAndLog(LOG_LEVEL_DEBUG, format, argArray);
- }
-
- /** Log a message of level DEBUG, including an exception. */
- public void debug(String msg, Throwable t) {
- log(LOG_LEVEL_DEBUG, msg, t);
- }
-
- /** Are {@code info} messages currently enabled? */
- public boolean isInfoEnabled() {
- return isLevelEnabled(LOG_LEVEL_INFO);
- }
-
- /**
- * A simple implementation which logs messages of level INFO according
- * to the format outlined above.
- */
- public void info(String msg) {
- log(LOG_LEVEL_INFO, msg, null);
- }
-
- /**
- * Perform single parameter substitution before logging the message of level
- * INFO according to the format outlined above.
- */
- public void info(String format, Object arg) {
- formatAndLog(LOG_LEVEL_INFO, format, arg, null);
- }
-
- /**
- * Perform double parameter substitution before logging the message of level
- * INFO according to the format outlined above.
- */
- public void info(String format, Object arg1, Object arg2) {
- formatAndLog(LOG_LEVEL_INFO, format, arg1, arg2);
- }
-
- /**
- * Perform double parameter substitution before logging the message of level
- * INFO according to the format outlined above.
- */
- public void info(String format, Object... argArray) {
- formatAndLog(LOG_LEVEL_INFO, format, argArray);
- }
-
- /** Log a message of level INFO, including an exception. */
- public void info(String msg, Throwable t) {
- log(LOG_LEVEL_INFO, msg, t);
- }
-
- /** Are {@code warn} messages currently enabled? */
- public boolean isWarnEnabled() {
- return isLevelEnabled(LOG_LEVEL_WARN);
- }
-
- /**
- * A simple implementation which always logs messages of level WARN according
- * to the format outlined above.
- */
- public void warn(String msg) {
- log(LOG_LEVEL_WARN, msg, null);
- }
-
- /**
- * Perform single parameter substitution before logging the message of level
- * WARN according to the format outlined above.
- */
- public void warn(String format, Object arg) {
- formatAndLog(LOG_LEVEL_WARN, format, arg, null);
- }
-
- /**
- * Perform double parameter substitution before logging the message of level
- * WARN according to the format outlined above.
- */
- public void warn(String format, Object arg1, Object arg2) {
- formatAndLog(LOG_LEVEL_WARN, format, arg1, arg2);
- }
-
- /**
- * Perform double parameter substitution before logging the message of level
- * WARN according to the format outlined above.
- */
- public void warn(String format, Object... argArray) {
- formatAndLog(LOG_LEVEL_WARN, format, argArray);
- }
-
- /** Log a message of level WARN, including an exception. */
- public void warn(String msg, Throwable t) {
- log(LOG_LEVEL_WARN, msg, t);
- }
-
- /** Are {@code error} messages currently enabled? */
- public boolean isErrorEnabled() {
- return isLevelEnabled(LOG_LEVEL_ERROR);
- }
-
- /**
- * A simple implementation which always logs messages of level ERROR according
- * to the format outlined above.
- */
- public void error(String msg) {
- log(LOG_LEVEL_ERROR, msg, null);
- }
-
- /**
- * Perform single parameter substitution before logging the message of level
- * ERROR according to the format outlined above.
- */
- public void error(String format, Object arg) {
- formatAndLog(LOG_LEVEL_ERROR, format, arg, null);
- }
-
- /**
- * Perform double parameter substitution before logging the message of level
- * ERROR according to the format outlined above.
- */
- public void error(String format, Object arg1, Object arg2) {
- formatAndLog(LOG_LEVEL_ERROR, format, arg1, arg2);
- }
-
- /**
- * Perform double parameter substitution before logging the message of level
- * ERROR according to the format outlined above.
- */
- public void error(String format, Object... argArray) {
- formatAndLog(LOG_LEVEL_ERROR, format, argArray);
- }
-
- /** Log a message of level ERROR, including an exception. */
- public void error(String msg, Throwable t) {
- log(LOG_LEVEL_ERROR, msg, t);
- }
-}
diff --git a/slf4j-simple/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/slf4j-simple/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
deleted file mode 100644
index a08ff675..00000000
--- a/slf4j-simple/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
+++ /dev/null
@@ -1,81 +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 org.slf4j.ILoggerFactory;
-import org.slf4j.LoggerFactory;
-import org.slf4j.spi.LoggerFactoryBinder;
-
-/**
- * The binding of {@link LoggerFactory} class with an actual instance of
- * {@link ILoggerFactory} is performed using information returned by this class.
- *
- *
- * @author Ceki G&uuml;lc&uuml;
- */
-public class StaticLoggerBinder implements LoggerFactoryBinder {
-
- /**
- * The unique instance of this class.
- *
- */
- private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
-
- /**
- * Return the singleton of this class.
- *
- * @return the StaticLoggerBinder singleton
- */
- public static final StaticLoggerBinder getSingleton() {
- return SINGLETON;
- }
-
- /**
- * Declare the version of the SLF4J API this implementation is compiled
- * against. The value of this field is usually modified with each release.
- */
- // to avoid constant folding by the compiler, this field must *not* be final
- public static String REQUESTED_API_VERSION = "1.6.99"; // !final
-
- private static final String loggerFactoryClassStr = SimpleLoggerFactory.class.getName();
-
- /**
- * The ILoggerFactory instance returned by the {@link #getLoggerFactory}
- * method should always be the same object
- */
- private final ILoggerFactory loggerFactory;
-
- private StaticLoggerBinder() {
- loggerFactory = new SimpleLoggerFactory();
- }
-
- public ILoggerFactory getLoggerFactory() {
- return loggerFactory;
- }
-
- public String getLoggerFactoryClassStr() {
- return loggerFactoryClassStr;
- }
-}
diff --git a/slf4j-simple/src/main/java/org/slf4j/impl/StaticMDCBinder.java b/slf4j-simple/src/main/java/org/slf4j/impl/StaticMDCBinder.java
deleted file mode 100644
index 086b0169..00000000
--- a/slf4j-simple/src/main/java/org/slf4j/impl/StaticMDCBinder.java
+++ /dev/null
@@ -1,56 +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 org.slf4j.helpers.NOPMDCAdapter;
-import org.slf4j.spi.MDCAdapter;
-
-/**
- * This implementation is bound to {@link NOPMDCAdapter}.
- *
- * @author Ceki G&uuml;lc&uuml;
- */
-public class StaticMDCBinder {
-
- /**
- * The unique instance of this class.
- */
- public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
-
- private StaticMDCBinder() {
- }
-
- /**
- * Currently this method always returns an instance of
- * {@link StaticMDCBinder}.
- */
- public MDCAdapter getMDCA() {
- return new NOPMDCAdapter();
- }
-
- public String getMDCAdapterClassStr() {
- return NOPMDCAdapter.class.getName();
- }
-}
diff --git a/slf4j-simple/src/main/java/org/slf4j/impl/StaticMarkerBinder.java b/slf4j-simple/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
deleted file mode 100644
index 435a924b..00000000
--- a/slf4j-simple/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
+++ /dev/null
@@ -1,68 +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 org.slf4j.IMarkerFactory;
-import org.slf4j.MarkerFactory;
-import org.slf4j.helpers.BasicMarkerFactory;
-import org.slf4j.spi.MarkerFactoryBinder;
-
-/**
- *
- * The binding of {@link MarkerFactory} class with an actual instance of
- * {@link IMarkerFactory} is performed using information returned by this class.
- *
- * @author Ceki G&uuml;lc&uuml;
- */
-public class StaticMarkerBinder implements MarkerFactoryBinder {
-
- /**
- * The unique instance of this class.
- */
- public static final StaticMarkerBinder SINGLETON = new StaticMarkerBinder();
-
- final IMarkerFactory markerFactory = new BasicMarkerFactory();
-
- private StaticMarkerBinder() {
- }
-
- /**
- * Currently this method always returns an instance of
- * {@link BasicMarkerFactory}.
- */
- public IMarkerFactory getMarkerFactory() {
- return markerFactory;
- }
-
- /**
- * Currently, this method returns the class name of
- * {@link BasicMarkerFactory}.
- */
- public String getMarkerFactoryClassStr() {
- return BasicMarkerFactory.class.getName();
- }
-
-}
diff --git a/slf4j-simple/src/main/java/org/slf4j/simple/OutputChoice.java b/slf4j-simple/src/main/java/org/slf4j/simple/OutputChoice.java
new file mode 100755
index 00000000..87a988e2
--- /dev/null
+++ b/slf4j-simple/src/main/java/org/slf4j/simple/OutputChoice.java
@@ -0,0 +1,55 @@
+package org.slf4j.simple;
+
+import java.io.PrintStream;
+
+/**
+ * This class encapsulates the user's choice of output target.
+ *
+ * @author Ceki G&uuml;lc&uuml;
+ *
+ */
+class OutputChoice {
+
+ enum OutputChoiceType {
+ SYS_OUT, CACHED_SYS_OUT, SYS_ERR, CACHED_SYS_ERR, FILE;
+ }
+
+ final OutputChoiceType outputChoiceType;
+ final PrintStream targetPrintStream;
+
+ OutputChoice(OutputChoiceType outputChoiceType) {
+ if (outputChoiceType == OutputChoiceType.FILE) {
+ throw new IllegalArgumentException();
+ }
+ this.outputChoiceType = outputChoiceType;
+ if (outputChoiceType == OutputChoiceType.CACHED_SYS_OUT) {
+ this.targetPrintStream = System.out;
+ } else if (outputChoiceType == OutputChoiceType.CACHED_SYS_ERR) {
+ this.targetPrintStream = System.err;
+ } else {
+ this.targetPrintStream = null;
+ }
+ }
+
+ OutputChoice(PrintStream printStream) {
+ this.outputChoiceType = OutputChoiceType.FILE;
+ this.targetPrintStream = printStream;
+ }
+
+ PrintStream getTargetPrintStream() {
+ switch (outputChoiceType) {
+ case SYS_OUT:
+ return System.out;
+ case SYS_ERR:
+ return System.err;
+ case CACHED_SYS_ERR:
+ case CACHED_SYS_OUT:
+ case FILE:
+ return targetPrintStream;
+ default:
+ throw new IllegalArgumentException();
+ }
+
+ }
+
+}
diff --git a/slf4j-simple/src/main/java/org/slf4j/simple/SimpleLogger.java b/slf4j-simple/src/main/java/org/slf4j/simple/SimpleLogger.java
new file mode 100644
index 00000000..c1b6c788
--- /dev/null
+++ b/slf4j-simple/src/main/java/org/slf4j/simple/SimpleLogger.java
@@ -0,0 +1,475 @@
+/**
+ * Copyright (c) 2004-2022 QOS.ch Sarl (Switzerland)
+ * 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.simple;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.Marker;
+import org.slf4j.event.Level;
+import org.slf4j.event.LoggingEvent;
+import org.slf4j.helpers.LegacyAbstractLogger;
+import org.slf4j.helpers.MessageFormatter;
+import org.slf4j.helpers.NormalizedParameters;
+import org.slf4j.spi.LocationAwareLogger;
+
+/**
+ * <p>
+ * Simple implementation of {@link Logger} that sends all enabled log messages,
+ * for all defined loggers, to the console ({@code System.err}). The following
+ * system properties are supported to configure the behavior of this logger:
+ *
+ *
+ * <ul>
+ * <li><code>org.slf4j.simpleLogger.logFile</code> - The output target which can
+ * be the <em>path</em> to a file, or the special values "System.out" and
+ * "System.err". Default is "System.err".</li>
+ *
+ * <li><code>org.slf4j.simpleLogger.cacheOutputStream</code> - If the output
+ * target is set to "System.out" or "System.err" (see preceding entry), by
+ * default, logs will be output to the latest value referenced by
+ * <code>System.out/err</code> variables. By setting this parameter to true, the
+ * output stream will be cached, i.e. assigned once at initialization time and
+ * re-used independently of the current value referenced by
+ * <code>System.out/err</code>.</li>
+ *
+ * <li><code>org.slf4j.simpleLogger.defaultLogLevel</code> - Default log level
+ * for all instances of SimpleLogger. Must be one of ("trace", "debug", "info",
+ * "warn", "error" or "off"). If not specified, defaults to "info".</li>
+ *
+ * <li><code>org.slf4j.simpleLogger.log.<em>a.b.c</em></code> - Logging detail
+ * level for a SimpleLogger instance named "a.b.c". Right-side value must be one
+ * of "trace", "debug", "info", "warn", "error" or "off". When a SimpleLogger
+ * named "a.b.c" is initialized, its level is assigned from this property. If
+ * unspecified, the level of nearest parent logger will be used, and if none is
+ * set, then the value specified by
+ * <code>org.slf4j.simpleLogger.defaultLogLevel</code> will be used.</li>
+ *
+ * <li><code>org.slf4j.simpleLogger.showDateTime</code> - Set to
+ * <code>true</code> if you want the current date and time to be included in
+ * output messages. Default is <code>false</code></li>
+ *
+ * <li><code>org.slf4j.simpleLogger.dateTimeFormat</code> - The date and time
+ * format to be used in the output messages. The pattern describing the date and
+ * time format is defined by <a href=
+ * "http://docs.oracle.com/javase/1.5.0/docs/api/java/text/SimpleDateFormat.html">
+ * <code>SimpleDateFormat</code></a>. If the format is not specified or is
+ * invalid, the number of milliseconds since start up will be output.</li>
+ *
+ * <li><code>org.slf4j.simpleLogger.showThreadName</code> -Set to
+ * <code>true</code> if you want to output the current thread name. Defaults to
+ * <code>true</code>.</li>
+ *
+ * <li>(since version 1.7.33 and 2.0.0-alpha6) <code>org.slf4j.simpleLogger.showThreadId</code> -
+ * If you would like to output the current thread id, then set to
+ * <code>true</code>. Defaults to <code>false</code>.</li>
+ *
+ * <li><code>org.slf4j.simpleLogger.showLogName</code> - Set to
+ * <code>true</code> if you want the Logger instance name to be included in
+ * output messages. Defaults to <code>true</code>.</li>
+ *
+ * <li><code>org.slf4j.simpleLogger.showShortLogName</code> - Set to
+ * <code>true</code> if you want the last component of the name to be included
+ * in output messages. Defaults to <code>false</code>.</li>
+ *
+ * <li><code>org.slf4j.simpleLogger.levelInBrackets</code> - Should the level
+ * string be output in brackets? Defaults to <code>false</code>.</li>
+ *
+ * <li><code>org.slf4j.simpleLogger.warnLevelString</code> - The string value
+ * output for the warn level. Defaults to <code>WARN</code>.</li>
+ *
+ * </ul>
+ *
+ * <p>
+ * In addition to looking for system properties with the names specified above,
+ * this implementation also checks for a class loader resource named
+ * <code>"simplelogger.properties"</code>, and includes any matching definitions
+ * from this resource (if it exists).
+ *
+ *
+ * <p>
+ * With no configuration, the default output includes the relative time in
+ * milliseconds, thread name, the level, logger name, and the message followed
+ * by the line separator for the host. In log4j terms it amounts to the "%r [%t]
+ * %level %logger - %m%n" pattern.
+ *
+ * <p>
+ * Sample output follows.
+ *
+ *
+ * <pre>
+ * 176 [main] INFO examples.Sort - Populating an array of 2 elements in reverse order.
+ * 225 [main] INFO examples.SortAlgo - Entered the sort method.
+ * 304 [main] INFO examples.SortAlgo - Dump of integer array:
+ * 317 [main] INFO examples.SortAlgo - Element [0] = 0
+ * 331 [main] INFO examples.SortAlgo - Element [1] = 1
+ * 343 [main] INFO examples.Sort - The next log statement should be an error message.
+ * 346 [main] ERROR examples.SortAlgo - Tried to dump an uninitialized array.
+ * at org.log4j.examples.SortAlgo.dump(SortAlgo.java:58)
+ * at org.log4j.examples.Sort.main(Sort.java:64)
+ * 467 [main] INFO examples.Sort - Exiting main method.
+ * </pre>
+ *
+ * <p>
+ * This implementation is heavily inspired by
+ * <a href="http://commons.apache.org/logging/">Apache Commons Logging</a>'s
+ * SimpleLog.
+ *
+ *
+ * @author Ceki G&uuml;lc&uuml;
+ * @author Scott Sanders
+ * @author Rod Waldhoff
+ * @author Robert Burrell Donkin
+ * @author C&eacute;drik LIME
+ */
+public class SimpleLogger extends LegacyAbstractLogger {
+
+ private static final long serialVersionUID = -632788891211436180L;
+
+ private static final long START_TIME = System.currentTimeMillis();
+
+ protected static final int LOG_LEVEL_TRACE = LocationAwareLogger.TRACE_INT;
+ protected static final int LOG_LEVEL_DEBUG = LocationAwareLogger.DEBUG_INT;
+ protected static final int LOG_LEVEL_INFO = LocationAwareLogger.INFO_INT;
+ protected static final int LOG_LEVEL_WARN = LocationAwareLogger.WARN_INT;
+ protected static final int LOG_LEVEL_ERROR = LocationAwareLogger.ERROR_INT;
+
+ static char SP = ' ';
+ static final String TID_PREFIX = "tid=";
+
+
+ // The OFF level can only be used in configuration files to disable logging.
+ // It has
+ // no printing method associated with it in o.s.Logger interface.
+ protected static final int LOG_LEVEL_OFF = LOG_LEVEL_ERROR + 10;
+
+ private static boolean INITIALIZED = false;
+ static final SimpleLoggerConfiguration CONFIG_PARAMS = new SimpleLoggerConfiguration();
+
+ static void lazyInit() {
+ if (INITIALIZED) {
+ return;
+ }
+ INITIALIZED = true;
+ init();
+ }
+
+ // external software might be invoking this method directly. Do not rename
+ // or change its semantics.
+ static void init() {
+ CONFIG_PARAMS.init();
+ }
+
+ /** The current log level */
+ protected int currentLogLevel = LOG_LEVEL_INFO;
+ /** The short name of this simple log instance */
+ private transient String shortLogName = null;
+
+ /**
+ * All system properties used by <code>SimpleLogger</code> start with this
+ * prefix
+ */
+ public static final String SYSTEM_PREFIX = "org.slf4j.simpleLogger.";
+
+ public static final String LOG_KEY_PREFIX = SimpleLogger.SYSTEM_PREFIX + "log.";
+
+ public static final String CACHE_OUTPUT_STREAM_STRING_KEY = SimpleLogger.SYSTEM_PREFIX + "cacheOutputStream";
+
+ public static final String WARN_LEVEL_STRING_KEY = SimpleLogger.SYSTEM_PREFIX + "warnLevelString";
+
+ public static final String LEVEL_IN_BRACKETS_KEY = SimpleLogger.SYSTEM_PREFIX + "levelInBrackets";
+
+ public static final String LOG_FILE_KEY = SimpleLogger.SYSTEM_PREFIX + "logFile";
+
+ public static final String SHOW_SHORT_LOG_NAME_KEY = SimpleLogger.SYSTEM_PREFIX + "showShortLogName";
+
+ public static final String SHOW_LOG_NAME_KEY = SimpleLogger.SYSTEM_PREFIX + "showLogName";
+
+ public static final String SHOW_THREAD_NAME_KEY = SimpleLogger.SYSTEM_PREFIX + "showThreadName";
+
+ public static final String SHOW_THREAD_ID_KEY = SimpleLogger.SYSTEM_PREFIX + "showThreadId";
+
+ public static final String DATE_TIME_FORMAT_KEY = SimpleLogger.SYSTEM_PREFIX + "dateTimeFormat";
+
+ public static final String SHOW_DATE_TIME_KEY = SimpleLogger.SYSTEM_PREFIX + "showDateTime";
+
+ public static final String DEFAULT_LOG_LEVEL_KEY = SimpleLogger.SYSTEM_PREFIX + "defaultLogLevel";
+
+ /**
+ * Protected access allows only {@link SimpleLoggerFactory} and also derived classes to instantiate
+ * SimpleLogger instances.
+ */
+ protected SimpleLogger(String name) {
+ this.name = name;
+
+ String levelString = recursivelyComputeLevelString();
+ if (levelString != null) {
+ this.currentLogLevel = SimpleLoggerConfiguration.stringToLevel(levelString);
+ } else {
+ this.currentLogLevel = CONFIG_PARAMS.defaultLogLevel;
+ }
+ }
+
+ String recursivelyComputeLevelString() {
+ String tempName = name;
+ String levelString = null;
+ int indexOfLastDot = tempName.length();
+ while ((levelString == null) && (indexOfLastDot > -1)) {
+ tempName = tempName.substring(0, indexOfLastDot);
+ levelString = CONFIG_PARAMS.getStringProperty(SimpleLogger.LOG_KEY_PREFIX + tempName, null);
+ indexOfLastDot = String.valueOf(tempName).lastIndexOf(".");
+ }
+ return levelString;
+ }
+
+ /**
+ * To avoid intermingling of log messages and associated stack traces, the two
+ * operations are done in a synchronized block.
+ *
+ * @param buf
+ * @param t
+ */
+ void write(StringBuilder buf, Throwable t) {
+ PrintStream targetStream = CONFIG_PARAMS.outputChoice.getTargetPrintStream();
+
+ synchronized (CONFIG_PARAMS) {
+ targetStream.println(buf.toString());
+ writeThrowable(t, targetStream);
+ targetStream.flush();
+ }
+
+ }
+
+ protected void writeThrowable(Throwable t, PrintStream targetStream) {
+ if (t != null) {
+ t.printStackTrace(targetStream);
+ }
+ }
+
+ private String getFormattedDate() {
+ Date now = new Date();
+ String dateText;
+ synchronized (CONFIG_PARAMS.dateFormatter) {
+ dateText = CONFIG_PARAMS.dateFormatter.format(now);
+ }
+ return dateText;
+ }
+
+ private String computeShortName() {
+ return name.substring(name.lastIndexOf(".") + 1);
+ }
+
+ // /**
+ // * For formatted messages, first substitute arguments and then log.
+ // *
+ // * @param level
+ // * @param format
+ // * @param arg1
+ // * @param arg2
+ // */
+ // private void formatAndLog(int level, String format, Object arg1, Object arg2) {
+ // if (!isLevelEnabled(level)) {
+ // return;
+ // }
+ // FormattingTuple tp = MessageFormatter.format(format, arg1, arg2);
+ // log(level, tp.getMessage(), tp.getThrowable());
+ // }
+
+ // /**
+ // * For formatted messages, first substitute arguments and then log.
+ // *
+ // * @param level
+ // * @param format
+ // * @param arguments
+ // * a list of 3 ore more arguments
+ // */
+ // private void formatAndLog(int level, String format, Object... arguments) {
+ // if (!isLevelEnabled(level)) {
+ // return;
+ // }
+ // FormattingTuple tp = MessageFormatter.arrayFormat(format, arguments);
+ // log(level, tp.getMessage(), tp.getThrowable());
+ // }
+
+ /**
+ * Is the given log level currently enabled?
+ *
+ * @param logLevel is this level enabled?
+ * @return whether the logger is enabled for the given level
+ */
+ protected boolean isLevelEnabled(int logLevel) {
+ // log level are numerically ordered so can use simple numeric
+ // comparison
+ return (logLevel >= currentLogLevel);
+ }
+
+ /** Are {@code trace} messages currently enabled? */
+ public boolean isTraceEnabled() {
+ return isLevelEnabled(LOG_LEVEL_TRACE);
+ }
+
+ /** Are {@code debug} messages currently enabled? */
+ public boolean isDebugEnabled() {
+ return isLevelEnabled(LOG_LEVEL_DEBUG);
+ }
+
+ /** Are {@code info} messages currently enabled? */
+ public boolean isInfoEnabled() {
+ return isLevelEnabled(LOG_LEVEL_INFO);
+ }
+
+ /** Are {@code warn} messages currently enabled? */
+ public boolean isWarnEnabled() {
+ return isLevelEnabled(LOG_LEVEL_WARN);
+ }
+
+ /** Are {@code error} messages currently enabled? */
+ public boolean isErrorEnabled() {
+ return isLevelEnabled(LOG_LEVEL_ERROR);
+ }
+
+ /**
+ * SimpleLogger's implementation of
+ * {@link org.slf4j.helpers.AbstractLogger#handleNormalizedLoggingCall(Level, Marker, String, Object[], Throwable) AbstractLogger#handleNormalizedLoggingCall}
+ * }
+ *
+ * @param level the SLF4J level for this event
+ * @param marker The marker to be used for this event, may be null.
+ * @param messagePattern The message pattern which will be parsed and formatted
+ * @param arguments the array of arguments to be formatted, may be null
+ * @param throwable The exception whose stack trace should be logged, may be null
+ */
+ @Override
+ protected void handleNormalizedLoggingCall(Level level, Marker marker, String messagePattern, Object[] arguments, Throwable throwable) {
+
+ List<Marker> markers = null;
+
+ if (marker != null) {
+ markers = new ArrayList<>();
+ markers.add(marker);
+ }
+
+ innerHandleNormalizedLoggingCall(level, markers, messagePattern, arguments, throwable);
+ }
+
+ private void innerHandleNormalizedLoggingCall(Level level, List<Marker> markers, String messagePattern, Object[] arguments, Throwable t) {
+
+ StringBuilder buf = new StringBuilder(32);
+
+ // Append date-time if so configured
+ if (CONFIG_PARAMS.showDateTime) {
+ if (CONFIG_PARAMS.dateFormatter != null) {
+ buf.append(getFormattedDate());
+ buf.append(SP);
+ } else {
+ buf.append(System.currentTimeMillis() - START_TIME);
+ buf.append(SP);
+ }
+ }
+
+ // Append current thread name if so configured
+ if (CONFIG_PARAMS.showThreadName) {
+ buf.append('[');
+ buf.append(Thread.currentThread().getName());
+ buf.append("] ");
+ }
+
+ if (CONFIG_PARAMS.showThreadId) {
+ buf.append(TID_PREFIX);
+ buf.append(Thread.currentThread().getId());
+ buf.append(SP);
+ }
+
+ if (CONFIG_PARAMS.levelInBrackets)
+ buf.append('[');
+
+ // Append a readable representation of the log level
+ String levelStr = renderLevel(level.toInt());
+ buf.append(levelStr);
+ if (CONFIG_PARAMS.levelInBrackets)
+ buf.append(']');
+ buf.append(SP);
+
+ // Append the name of the log instance if so configured
+ if (CONFIG_PARAMS.showShortLogName) {
+ if (shortLogName == null)
+ shortLogName = computeShortName();
+ buf.append(String.valueOf(shortLogName)).append(" - ");
+ } else if (CONFIG_PARAMS.showLogName) {
+ buf.append(String.valueOf(name)).append(" - ");
+ }
+
+ if (markers != null) {
+ buf.append(SP);
+ for (Marker marker : markers) {
+ buf.append(marker.getName()).append(SP);
+ }
+ }
+
+ String formattedMessage = MessageFormatter.basicArrayFormat(messagePattern, arguments);
+
+ // Append the message
+ buf.append(formattedMessage);
+
+ write(buf, t);
+ }
+
+ protected String renderLevel(int levelInt) {
+ switch (levelInt) {
+ case LOG_LEVEL_TRACE:
+ return "TRACE";
+ case LOG_LEVEL_DEBUG:
+ return("DEBUG");
+ case LOG_LEVEL_INFO:
+ return "INFO";
+ case LOG_LEVEL_WARN:
+ return "WARN";
+ case LOG_LEVEL_ERROR:
+ return "ERROR";
+ }
+ throw new IllegalStateException("Unrecognized level ["+levelInt+"]");
+ }
+
+ public void log(LoggingEvent event) {
+ int levelInt = event.getLevel().toInt();
+
+ if (!isLevelEnabled(levelInt)) {
+ return;
+ }
+
+ NormalizedParameters np = NormalizedParameters.normalize(event);
+
+ innerHandleNormalizedLoggingCall(event.getLevel(), event.getMarkers(), np.getMessage(), np.getArguments(), event.getThrowable());
+ }
+
+ @Override
+ protected String getFullyQualifiedCallerName() {
+ return null;
+ }
+
+}
diff --git a/slf4j-simple/src/main/java/org/slf4j/simple/SimpleLoggerConfiguration.java b/slf4j-simple/src/main/java/org/slf4j/simple/SimpleLoggerConfiguration.java
new file mode 100755
index 00000000..0a7f1310
--- /dev/null
+++ b/slf4j-simple/src/main/java/org/slf4j/simple/SimpleLoggerConfiguration.java
@@ -0,0 +1,193 @@
+package org.slf4j.simple;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Properties;
+
+import org.slf4j.helpers.Reporter;
+import org.slf4j.helpers.Util;
+import org.slf4j.simple.OutputChoice.OutputChoiceType;
+
+/**
+ * This class holds configuration values for {@link SimpleLogger}. The
+ * values are computed at runtime. See {@link SimpleLogger} documentation for
+ * more information.
+ *
+ *
+ * @author Ceki G&uuml;lc&uuml;
+ * @author Scott Sanders
+ * @author Rod Waldhoff
+ * @author Robert Burrell Donkin
+ * @author C&eacute;drik LIME
+ *
+ * @since 1.7.25
+ */
+public class SimpleLoggerConfiguration {
+
+ private static final String CONFIGURATION_FILE = "simplelogger.properties";
+
+ static int DEFAULT_LOG_LEVEL_DEFAULT = SimpleLogger.LOG_LEVEL_INFO;
+ int defaultLogLevel = DEFAULT_LOG_LEVEL_DEFAULT;
+
+ private static final boolean SHOW_DATE_TIME_DEFAULT = false;
+ boolean showDateTime = SHOW_DATE_TIME_DEFAULT;
+
+ private static final String DATE_TIME_FORMAT_STR_DEFAULT = null;
+ private static String dateTimeFormatStr = DATE_TIME_FORMAT_STR_DEFAULT;
+
+ DateFormat dateFormatter = null;
+
+ private static final boolean SHOW_THREAD_NAME_DEFAULT = true;
+ boolean showThreadName = SHOW_THREAD_NAME_DEFAULT;
+
+ /**
+ * See https://jira.qos.ch/browse/SLF4J-499
+ * @since 1.7.33 and 2.0.0-alpha6
+ */
+ private static final boolean SHOW_THREAD_ID_DEFAULT = false;
+ boolean showThreadId = SHOW_THREAD_ID_DEFAULT;
+
+ final static boolean SHOW_LOG_NAME_DEFAULT = true;
+ boolean showLogName = SHOW_LOG_NAME_DEFAULT;
+
+ private static final boolean SHOW_SHORT_LOG_NAME_DEFAULT = false;
+ boolean showShortLogName = SHOW_SHORT_LOG_NAME_DEFAULT;
+
+ private static final boolean LEVEL_IN_BRACKETS_DEFAULT = false;
+ boolean levelInBrackets = LEVEL_IN_BRACKETS_DEFAULT;
+
+ private static final String LOG_FILE_DEFAULT = "System.err";
+ private String logFile = LOG_FILE_DEFAULT;
+ OutputChoice outputChoice = null;
+
+ private static final boolean CACHE_OUTPUT_STREAM_DEFAULT = false;
+ private boolean cacheOutputStream = CACHE_OUTPUT_STREAM_DEFAULT;
+
+ private static final String WARN_LEVELS_STRING_DEFAULT = "WARN";
+ String warnLevelString = WARN_LEVELS_STRING_DEFAULT;
+
+ private final Properties properties = new Properties();
+
+ void init() {
+ loadProperties();
+
+ String defaultLogLevelString = getStringProperty(SimpleLogger.DEFAULT_LOG_LEVEL_KEY, null);
+ if (defaultLogLevelString != null)
+ defaultLogLevel = stringToLevel(defaultLogLevelString);
+
+ showLogName = getBooleanProperty(SimpleLogger.SHOW_LOG_NAME_KEY, SimpleLoggerConfiguration.SHOW_LOG_NAME_DEFAULT);
+ showShortLogName = getBooleanProperty(SimpleLogger.SHOW_SHORT_LOG_NAME_KEY, SHOW_SHORT_LOG_NAME_DEFAULT);
+ showDateTime = getBooleanProperty(SimpleLogger.SHOW_DATE_TIME_KEY, SHOW_DATE_TIME_DEFAULT);
+ showThreadName = getBooleanProperty(SimpleLogger.SHOW_THREAD_NAME_KEY, SHOW_THREAD_NAME_DEFAULT);
+ showThreadId = getBooleanProperty(SimpleLogger.SHOW_THREAD_ID_KEY, SHOW_THREAD_ID_DEFAULT);
+ dateTimeFormatStr = getStringProperty(SimpleLogger.DATE_TIME_FORMAT_KEY, DATE_TIME_FORMAT_STR_DEFAULT);
+ levelInBrackets = getBooleanProperty(SimpleLogger.LEVEL_IN_BRACKETS_KEY, LEVEL_IN_BRACKETS_DEFAULT);
+ warnLevelString = getStringProperty(SimpleLogger.WARN_LEVEL_STRING_KEY, WARN_LEVELS_STRING_DEFAULT);
+
+ logFile = getStringProperty(SimpleLogger.LOG_FILE_KEY, logFile);
+
+ cacheOutputStream = getBooleanProperty(SimpleLogger.CACHE_OUTPUT_STREAM_STRING_KEY, CACHE_OUTPUT_STREAM_DEFAULT);
+ outputChoice = computeOutputChoice(logFile, cacheOutputStream);
+
+ if (dateTimeFormatStr != null) {
+ try {
+ dateFormatter = new SimpleDateFormat(dateTimeFormatStr);
+ } catch (IllegalArgumentException e) {
+ Reporter.error("Bad date format in " + CONFIGURATION_FILE + "; will output relative time", e);
+ }
+ }
+ }
+
+ private void loadProperties() {
+ // Add props from the resource simplelogger.properties
+ InputStream in = AccessController.doPrivileged((PrivilegedAction<InputStream>) () -> {
+ ClassLoader threadCL = Thread.currentThread().getContextClassLoader();
+ if (threadCL != null) {
+ return threadCL.getResourceAsStream(CONFIGURATION_FILE);
+ } else {
+ return ClassLoader.getSystemResourceAsStream(CONFIGURATION_FILE);
+ }
+ });
+ if (null != in) {
+ try {
+ properties.load(in);
+ } catch (java.io.IOException e) {
+ // ignored
+ } finally {
+ try {
+ in.close();
+ } catch (java.io.IOException e) {
+ // ignored
+ }
+ }
+ }
+ }
+
+ String getStringProperty(String name, String defaultValue) {
+ String prop = getStringProperty(name);
+ return (prop == null) ? defaultValue : prop;
+ }
+
+ boolean getBooleanProperty(String name, boolean defaultValue) {
+ String prop = getStringProperty(name);
+ return (prop == null) ? defaultValue : "true".equalsIgnoreCase(prop);
+ }
+
+ String getStringProperty(String name) {
+ String prop = null;
+ try {
+ prop = System.getProperty(name);
+ } catch (SecurityException e) {
+ ; // Ignore
+ }
+ return (prop == null) ? properties.getProperty(name) : prop;
+ }
+
+ static int stringToLevel(String levelStr) {
+ if ("trace".equalsIgnoreCase(levelStr)) {
+ return SimpleLogger.LOG_LEVEL_TRACE;
+ } else if ("debug".equalsIgnoreCase(levelStr)) {
+ return SimpleLogger.LOG_LEVEL_DEBUG;
+ } else if ("info".equalsIgnoreCase(levelStr)) {
+ return SimpleLogger.LOG_LEVEL_INFO;
+ } else if ("warn".equalsIgnoreCase(levelStr)) {
+ return SimpleLogger.LOG_LEVEL_WARN;
+ } else if ("error".equalsIgnoreCase(levelStr)) {
+ return SimpleLogger.LOG_LEVEL_ERROR;
+ } else if ("off".equalsIgnoreCase(levelStr)) {
+ return SimpleLogger.LOG_LEVEL_OFF;
+ }
+ // assume INFO by default
+ return SimpleLogger.LOG_LEVEL_INFO;
+ }
+
+ private static OutputChoice computeOutputChoice(String logFile, boolean cacheOutputStream) {
+ if ("System.err".equalsIgnoreCase(logFile))
+ if (cacheOutputStream)
+ return new OutputChoice(OutputChoiceType.CACHED_SYS_ERR);
+ else
+ return new OutputChoice(OutputChoiceType.SYS_ERR);
+ else if ("System.out".equalsIgnoreCase(logFile)) {
+ if (cacheOutputStream)
+ return new OutputChoice(OutputChoiceType.CACHED_SYS_OUT);
+ else
+ return new OutputChoice(OutputChoiceType.SYS_OUT);
+ } else {
+ try {
+ FileOutputStream fos = new FileOutputStream(logFile);
+ PrintStream printStream = new PrintStream(fos);
+ return new OutputChoice(printStream);
+ } catch (FileNotFoundException e) {
+ Reporter.error("Could not open [" + logFile + "]. Defaulting to System.err", e);
+ return new OutputChoice(OutputChoiceType.SYS_ERR);
+ }
+ }
+ }
+
+}
diff --git a/slf4j-simple/src/main/java/org/slf4j/impl/SimpleLoggerFactory.java b/slf4j-simple/src/main/java/org/slf4j/simple/SimpleLoggerFactory.java
index 4c59f2dc..ceb0d4ee 100644
--- a/slf4j-simple/src/main/java/org/slf4j/impl/SimpleLoggerFactory.java
+++ b/slf4j-simple/src/main/java/org/slf4j/simple/SimpleLoggerFactory.java
@@ -22,7 +22,7 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j.impl;
+package org.slf4j.simple;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -41,33 +41,37 @@ public class SimpleLoggerFactory implements ILoggerFactory {
ConcurrentMap<String, Logger> loggerMap;
public SimpleLoggerFactory() {
- loggerMap = new ConcurrentHashMap<String, Logger>();
+ loggerMap = new ConcurrentHashMap<>();
+ SimpleLogger.lazyInit();
}
/**
* Return an appropriate {@link SimpleLogger} instance by name.
+ *
+ * This method will call {@link #createLogger(String)} if the logger
+ * has not been created yet.
*/
public Logger getLogger(String name) {
- Logger simpleLogger = loggerMap.get(name);
- if (simpleLogger != null) {
- return simpleLogger;
- } else {
- Logger newInstance = new SimpleLogger(name);
- Logger oldInstance = loggerMap.putIfAbsent(name, newInstance);
- return oldInstance == null ? newInstance : oldInstance;
- }
+ return loggerMap.computeIfAbsent(name, this::createLogger);
+ }
+
+ /**
+ * Actually creates the logger for the given name.
+ */
+ protected Logger createLogger(String name) {
+ return new SimpleLogger(name);
}
/**
* Clear the internal logger cache.
*
- * This method is intended to be called by classes (in the same package) for
- * testing purposes. This method is internal. It can be modified, renamed or
- * removed at any time without notice.
+ * This method is intended to be called by classes (in the same package or
+ * subclasses) for testing purposes. This method is internal. It can be
+ * modified, renamed or removed at any time without notice.
*
* You are strongly discouraged from calling this method in production code.
*/
- void reset() {
+ protected void reset() {
loggerMap.clear();
}
}
diff --git a/slf4j-simple/src/main/java/org/slf4j/simple/SimpleServiceProvider.java b/slf4j-simple/src/main/java/org/slf4j/simple/SimpleServiceProvider.java
new file mode 100755
index 00000000..795200dc
--- /dev/null
+++ b/slf4j-simple/src/main/java/org/slf4j/simple/SimpleServiceProvider.java
@@ -0,0 +1,50 @@
+package org.slf4j.simple;
+
+import org.slf4j.ILoggerFactory;
+import org.slf4j.IMarkerFactory;
+import org.slf4j.helpers.BasicMarkerFactory;
+import org.slf4j.helpers.NOPMDCAdapter;
+import org.slf4j.spi.MDCAdapter;
+import org.slf4j.spi.SLF4JServiceProvider;
+
+public class SimpleServiceProvider implements SLF4JServiceProvider {
+
+ /**
+ * Declare the version of the SLF4J API this implementation is compiled against.
+ * The value of this field is modified with each major release.
+ */
+ // to avoid constant folding by the compiler, this field must *not* be final
+ public static String REQUESTED_API_VERSION = "2.0.99"; // !final
+
+ private ILoggerFactory loggerFactory;
+ private IMarkerFactory markerFactory;
+ private MDCAdapter mdcAdapter;
+
+ public ILoggerFactory getLoggerFactory() {
+ return loggerFactory;
+ }
+
+ @Override
+ public IMarkerFactory getMarkerFactory() {
+ return markerFactory;
+ }
+
+ @Override
+ public MDCAdapter getMDCAdapter() {
+ return mdcAdapter;
+ }
+
+ @Override
+ public String getRequestedApiVersion() {
+ return REQUESTED_API_VERSION;
+ }
+
+ @Override
+ public void initialize() {
+
+ loggerFactory = new SimpleLoggerFactory();
+ markerFactory = new BasicMarkerFactory();
+ mdcAdapter = new NOPMDCAdapter();
+ }
+
+}
diff --git a/slf4j-simple/src/main/java9/module-info.java b/slf4j-simple/src/main/java9/module-info.java
new file mode 100755
index 00000000..9b8e3d24
--- /dev/null
+++ b/slf4j-simple/src/main/java9/module-info.java
@@ -0,0 +1,6 @@
+module org.slf4j.simple {
+ requires org.slf4j;
+ provides org.slf4j.spi.SLF4JServiceProvider with org.slf4j.simple.SimpleServiceProvider;
+ exports org.slf4j.simple;
+ opens org.slf4j.simple to org.slf4j;
+}
diff --git a/slf4j-simple/src/main/resources/META-INF/MANIFEST.MF b/slf4j-simple/src/main/resources/META-INF/MANIFEST.MF
deleted file mode 100644
index 897c9727..00000000
--- a/slf4j-simple/src/main/resources/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,10 +0,0 @@
-Implementation-Title: slf4j-simple
-Bundle-ManifestVersion: 2
-Bundle-SymbolicName: slf4j.simple
-Bundle-Name: slf4j-simple
-Bundle-Vendor: SLF4J.ORG
-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}
-Fragment-Host: slf4j.api \ No newline at end of file
diff --git a/slf4j-simple/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider b/slf4j-simple/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider
new file mode 100755
index 00000000..5cda4490
--- /dev/null
+++ b/slf4j-simple/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider
@@ -0,0 +1 @@
+org.slf4j.simple.SimpleServiceProvider \ No newline at end of file
diff --git a/slf4j-simple/src/test/java/org/slf4j/impl/SimpleLoggerTest.java b/slf4j-simple/src/test/java/org/slf4j/impl/SimpleLoggerTest.java
deleted file mode 100644
index 4c84762d..00000000
--- a/slf4j-simple/src/test/java/org/slf4j/impl/SimpleLoggerTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * Copyright (c) 2004-2012 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 org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNull;
-
-public class SimpleLoggerTest {
-
- String A_KEY = SimpleLogger.LOG_KEY_PREFIX + "a";
-
- @Before
- public void before() {
- System.setProperty(A_KEY, "info");
- }
-
- @After
- public void after() {
- System.clearProperty(A_KEY);
- }
-
- @Test
- public void emptyLoggerName() {
- SimpleLogger simpleLogger = new SimpleLogger("a");
- assertEquals("info", simpleLogger.recursivelyComputeLevelString());
- }
-
- @Test
- public void loggerNameWithNoDots_WithLevel() {
- SimpleLogger simpleLogger = new SimpleLogger("a");
- assertEquals("info", simpleLogger.recursivelyComputeLevelString());
- }
-
- @Test
- public void loggerNameWithOneDotShouldInheritFromParent() {
- SimpleLogger simpleLogger = new SimpleLogger("a.b");
- assertEquals("info", simpleLogger.recursivelyComputeLevelString());
- }
-
- @Test
- public void loggerNameWithNoDots_WithNoSetLevel() {
- SimpleLogger simpleLogger = new SimpleLogger("x");
- assertNull(simpleLogger.recursivelyComputeLevelString());
- }
-
- @Test
- public void loggerNameWithOneDot_NoSetLevel() {
- SimpleLogger simpleLogger = new SimpleLogger("x.y");
- assertNull(simpleLogger.recursivelyComputeLevelString());
- }
-
-}
diff --git a/slf4j-simple/src/test/java/org/slf4j/simple/AcceptanceTest.java b/slf4j-simple/src/test/java/org/slf4j/simple/AcceptanceTest.java
new file mode 100644
index 00000000..76985073
--- /dev/null
+++ b/slf4j-simple/src/test/java/org/slf4j/simple/AcceptanceTest.java
@@ -0,0 +1,50 @@
+package org.slf4j.simple;
+
+import org.junit.Ignore;
+import org.slf4j.Logger;
+import org.slf4j.event.Level;
+
+import java.io.PrintStream;
+
+@Ignore
+public class AcceptanceTest extends LoggerTestSuite {
+
+ @Override
+ public Logger createLogger(ListAppendingOutputStream outputStream, Level level) {
+ SimpleLogger.CONFIG_PARAMS.outputChoice = new OutputChoice(new PrintStream(outputStream));
+
+ SimpleLogger logger = new SimpleLogger("TestSuiteLogger");
+ logger.currentLogLevel = SimpleLoggerConfiguration.stringToLevel(level.toString());
+ return logger;
+ }
+
+ @Override
+ public String extractMessage(String message) {
+ return message
+ .split("\n")[0]
+ .split("- ")[1];
+ }
+
+ @Override
+ public String extractExceptionMessage(String message) {
+ String[] logLines = message.split("\n");
+
+ if (logLines.length < 2) {
+ return null;
+ }
+ String exceptionLine = logLines[1];
+ return exceptionLine.split(": ")[1];
+ }
+
+ @Override
+ public String extractExceptionType(String message) {
+ String[] logLines = message.split("\n");
+
+ if (logLines.length < 2) {
+ return null;
+ }
+ String exceptionLine = logLines[1];
+ return exceptionLine.split(": ")[0];
+ }
+
+} \ No newline at end of file
diff --git a/slf4j-simple/src/test/java/org/slf4j/DetectLoggerNameMismatchTest.java b/slf4j-simple/src/test/java/org/slf4j/simple/DetectLoggerNameMismatchTest.java
index c6c6f205..516ce8e4 100755
--- a/slf4j-simple/src/test/java/org/slf4j/DetectLoggerNameMismatchTest.java
+++ b/slf4j-simple/src/test/java/org/slf4j/simple/DetectLoggerNameMismatchTest.java
@@ -22,7 +22,7 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j;
+package org.slf4j.simple;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -30,6 +30,9 @@ import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.LoggerFactoryFriend;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -48,6 +51,8 @@ public class DetectLoggerNameMismatchTest {
private static final String MISMATCH_STRING = "Detected logger name mismatch";
+ static String NAME_OF_THIS_CLASS = DetectLoggerNameMismatchTest.class.getName();
+
private final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
private final PrintStream oldErr = System.err;
@@ -90,8 +95,9 @@ public class DetectLoggerNameMismatchTest {
public void testTriggerWholeMessage() {
setTrialEnabled(true);
LoggerFactory.getLogger(String.class);
- assertTrue("Actual value of byteArrayOutputStream: " + String.valueOf(byteArrayOutputStream), String.valueOf(byteArrayOutputStream).contains(
- "Detected logger name mismatch. Given name: \"java.lang.String\"; " + "computed name: \"org.slf4j.DetectLoggerNameMismatchTest\"."));
+ boolean success = String.valueOf(byteArrayOutputStream)
+ .contains("Detected logger name mismatch. Given name: \"java.lang.String\"; " + "computed name: \"" + NAME_OF_THIS_CLASS + "\".");
+ assertTrue("Actual value of byteArrayOutputStream: " + String.valueOf(byteArrayOutputStream), success);
}
/*
@@ -101,7 +107,7 @@ public class DetectLoggerNameMismatchTest {
public void testPassIfMatch() {
setTrialEnabled(true);
Logger logger = LoggerFactory.getLogger(DetectLoggerNameMismatchTest.class);
- assertEquals("org.slf4j.DetectLoggerNameMismatchTest", logger.getName());
+ assertEquals(DetectLoggerNameMismatchTest.class.getName(), logger.getName());
assertMismatchDetected(false);
}
@@ -113,7 +119,7 @@ public class DetectLoggerNameMismatchTest {
public void verifyLoggerDefinedInBaseWithOverridenGetClassMethod() {
setTrialEnabled(true);
Square square = new Square();
- assertEquals("org.slf4j.Square", square.logger.getName());
+ assertEquals(Square.class.getName(), square.logger.getName());
assertMismatchDetected(false);
}
@@ -121,7 +127,7 @@ public class DetectLoggerNameMismatchTest {
// The system property is read into a static variable at initialization time
// so we cannot just reset the system property to test this feature.
// Therefore we set the variable directly.
- LoggerFactory.DETECT_LOGGER_NAME_MISMATCH = enabled;
+ LoggerFactoryFriend.setDetectLoggerNameMismatch(enabled);
}
}
diff --git a/slf4j-simple/src/test/java/org/slf4j/simple/DoubleInitializationPitfallTest.java b/slf4j-simple/src/test/java/org/slf4j/simple/DoubleInitializationPitfallTest.java
new file mode 100644
index 00000000..e4e39d5e
--- /dev/null
+++ b/slf4j-simple/src/test/java/org/slf4j/simple/DoubleInitializationPitfallTest.java
@@ -0,0 +1,37 @@
+package org.slf4j.simple;
+
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+import org.slf4j.ILoggerFactory;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+import org.slf4j.MarkerFactory;
+
+// See https://jira.qos.ch/browse/SLF4J-463
+public class DoubleInitializationPitfallTest {
+
+ // See https://jira.qos.ch/browse/SLF4J-463
+ @Test
+ public void verifyImpactOfMarkerFactory() {
+ ILoggerFactory firstFactory = LoggerFactory.getILoggerFactory();
+ MarkerFactory.getMarker("DOUBLE_INIT");
+ ILoggerFactory secondFactory = LoggerFactory.getILoggerFactory();
+
+ if (firstFactory != secondFactory) {
+ fail("MarkerFactory.getMarker causes multiple provider initialization");
+ }
+ }
+
+ @Test
+ public void verifyImpactOfMDC() {
+ ILoggerFactory firstFactory = LoggerFactory.getILoggerFactory();
+ MDC.put("DoubleInitializationPitfallTest", "a");
+ ILoggerFactory secondFactory = LoggerFactory.getILoggerFactory();
+
+ if (firstFactory != secondFactory) {
+ fail("MarkerFactory.getMarker causes multiple provider initialization");
+ }
+ }
+
+}
diff --git a/slf4j-simple/src/test/java/org/slf4j/InvocationTest.java b/slf4j-simple/src/test/java/org/slf4j/simple/InvocationTest.java
index 6842d07c..39d3da0e 100644
--- a/slf4j-simple/src/test/java/org/slf4j/InvocationTest.java
+++ b/slf4j-simple/src/test/java/org/slf4j/simple/InvocationTest.java
@@ -22,11 +22,20 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j;
+package org.slf4j.simple;
+
+import static org.junit.Assert.assertNull;
import java.io.PrintStream;
-import junit.framework.TestCase;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
/**
* Test whether invoking the SLF4J API causes problems or not.
@@ -34,33 +43,31 @@ import junit.framework.TestCase;
* @author Ceki Gulcu
*
*/
-public class InvocationTest extends TestCase {
+public class InvocationTest {
PrintStream old = System.err;
- public InvocationTest(String arg0) {
- super(arg0);
- }
-
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() throws Exception {
System.setErr(new SilentPrintStream(old));
}
- protected void tearDown() throws Exception {
- super.tearDown();
+ @After
+ public void tearDown() throws Exception {
System.setErr(old);
}
+ @Test
public void test1() {
Logger logger = LoggerFactory.getLogger("test1");
logger.debug("Hello world.");
}
+ @Test
public void test2() {
- Integer i1 = new Integer(1);
- Integer i2 = new Integer(2);
- Integer i3 = new Integer(3);
+ Integer i1 = Integer.valueOf(1);
+ Integer i2 = Integer.valueOf(2);
+ Integer i3 = Integer.valueOf(3);
Exception e = new Exception("This is a test exception.");
Logger logger = LoggerFactory.getLogger("test2");
@@ -76,18 +83,21 @@ public class InvocationTest extends TestCase {
logger.warn("Hello world 3", e);
logger.error("Hello world 4.");
- logger.error("Hello world {}", new Integer(3));
+ logger.error("Hello world {}", Integer.valueOf(3));
logger.error("Hello world 4.", e);
}
- // http://bugzilla.slf4j.org/show_bug.cgi?id=78
+ // http://jira.qos.ch/browse/SLF4J-69
+ // formerly http://bugzilla.slf4j.org/show_bug.cgi?id=78
+ @Test
public void testNullParameter_BUG78() {
Logger logger = LoggerFactory.getLogger("testNullParameter_BUG78");
String[] parameters = null;
String msg = "hello {}";
- logger.info(msg, parameters);
+ logger.info(msg, (Object[]) parameters);
}
+ @Test
public void testNull() {
Logger logger = LoggerFactory.getLogger("testNull");
logger.debug(null);
@@ -102,6 +112,7 @@ public class InvocationTest extends TestCase {
logger.error(null, e);
}
+ @Test
public void testMarker() {
Logger logger = LoggerFactory.getLogger("testMarker");
Marker blue = MarkerFactory.getMarker("BLUE");
@@ -121,6 +132,7 @@ public class InvocationTest extends TestCase {
logger.error(blue, "hello {} and {} ", "world", "universe");
}
+ @Test
public void testMDC() {
MDC.put("k", "v");
assertNull(MDC.get("k"));
diff --git a/slf4j-simple/src/test/java/org/slf4j/simple/LoggerTestSuite.java b/slf4j-simple/src/test/java/org/slf4j/simple/LoggerTestSuite.java
new file mode 100644
index 00000000..5784c1bd
--- /dev/null
+++ b/slf4j-simple/src/test/java/org/slf4j/simple/LoggerTestSuite.java
@@ -0,0 +1,274 @@
+package org.slf4j.simple;
+
+
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.event.Level;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+
+public abstract class LoggerTestSuite {
+
+ public static class ListAppendingOutputStream extends OutputStream {
+ private final StringBuilder word = new StringBuilder();
+ private int index = 0;
+ private final List<String> list;
+
+ private ListAppendingOutputStream(List<String> list) {this.list = list;}
+
+
+ @Override
+ public void write(int b) throws IOException {
+ word.append((char) b);
+ }
+
+ @Override
+ public void flush() {
+ list.add(word.toString());
+ word.delete(0, word.length());
+ index++;
+ }
+ }
+
+ private ListAppendingOutputStream prepareSink(List<String> source) {
+ return new ListAppendingOutputStream(source);
+
+ }
+
+ @Test
+ public void testTrace() {
+ ArrayList<String> loggingEvents = new ArrayList<>();
+ Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.TRACE);
+
+ assertTrue("Trace level should be enabled for this test", configuredLogger.isTraceEnabled());
+ configuredLogger.trace("Simple trace message");
+
+ assertEquals("Trace message should've been captured", 1, loggingEvents.size());
+ assertTrue("Message should be logged in trace level", isTraceMessage(loggingEvents.get(0)));
+ assertEquals("Supplied trace message wasn't found in the log",
+ "Simple trace message",
+ extractMessage(loggingEvents.get(0)));
+
+ loggingEvents.clear();
+
+ configuredLogger.debug("Simple debug message");
+ configuredLogger.info("Simple info message");
+ configuredLogger.warn("Simple warn message");
+ configuredLogger.error("Simple error message");
+ assertEquals("The other levels should have been captured", 4, loggingEvents.size());
+
+ }
+
+ @Test
+ public void testDebug() {
+ ArrayList<String> loggingEvents = new ArrayList<>();
+ Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.DEBUG);
+
+ configuredLogger.trace("Simple trace message");
+ assertEquals("Lower levels should have been ignored", 0, loggingEvents.size());
+
+ assertTrue("Debug level should be enabled for this test", configuredLogger.isDebugEnabled());
+ configuredLogger.debug("Simple debug message");
+
+ assertEquals("Debug message should've been captured", 1, loggingEvents.size());
+ assertTrue("Message should be logged in debug level", isDebugMessage(loggingEvents.get(0)));
+ assertEquals("Supplied debug message wasn't found in the log",
+ "Simple debug message",
+ extractMessage(loggingEvents.get(0)));
+
+ loggingEvents.clear();
+
+ configuredLogger.info("Simple info message");
+ configuredLogger.warn("Simple warn message");
+ configuredLogger.error("Simple error message");
+ assertEquals("The other levels should have been captured", 3, loggingEvents.size());
+ }
+
+
+ @Test
+ public void testInfo() {
+ ArrayList<String> loggingEvents = new ArrayList<>();
+ Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.INFO);
+
+ configuredLogger.trace("Simple trace message");
+ configuredLogger.debug("Simple debug message");
+ assertEquals("Lower levels should have been ignored", 0, loggingEvents.size());
+
+ assertTrue("Info level should be enabled for this test", configuredLogger.isInfoEnabled());
+ configuredLogger.info("Simple info message");
+
+ assertEquals("Info message should've been captured", 1, loggingEvents.size());
+ assertTrue("Message should be logged in debug level", isInfoMessage(loggingEvents.get(0)));
+ assertEquals("Supplied info message wasn't found in the log",
+ "Simple info message",
+ extractMessage(loggingEvents.get(0)));
+
+ loggingEvents.clear();
+
+ configuredLogger.warn("Simple warn message");
+ configuredLogger.error("Simple error message");
+ assertEquals("The other levels should have been captured", 2, loggingEvents.size());
+ }
+
+ @Test
+ public void testWarn() {
+ ArrayList<String> loggingEvents = new ArrayList<>();
+ Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.WARN);
+
+ configuredLogger.trace("Simple trace message");
+ configuredLogger.debug("Simple debug message");
+ configuredLogger.info("Simple info message");
+ assertEquals("Lower levels should have been ignored", 0, loggingEvents.size());
+
+ assertTrue("Warn level should be enabled for this test", configuredLogger.isWarnEnabled());
+ configuredLogger.warn("Simple warn message");
+
+ assertEquals("Warn message should've been captured", 1, loggingEvents.size());
+ assertTrue("Message should be logged in warn level", isWarnMessage(loggingEvents.get(0)));
+ assertEquals("Supplied warn message wasn't found in the log",
+ "Simple warn message",
+ extractMessage(loggingEvents.get(0)));
+
+ loggingEvents.clear();
+
+ configuredLogger.error("Simple error message");
+ assertEquals("The other levels should have been captured", 1, loggingEvents.size());
+ }
+
+ @Test
+ public void testError() {
+ ArrayList<String> loggingEvents = new ArrayList<>();
+ Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.ERROR);
+
+ configuredLogger.trace("Simple trace message");
+ configuredLogger.debug("Simple debug message");
+ configuredLogger.info("Simple info message");
+ configuredLogger.warn("Simple warn message");
+ assertEquals("Lower levels should have been ignored", 0, loggingEvents.size());
+
+ assertTrue("Error level should be enabled for this test", configuredLogger.isErrorEnabled());
+ configuredLogger.error("Simple error message");
+
+ assertEquals("Error message should've been captured", 1, loggingEvents.size());
+ assertTrue("Message should be logged in error level", isErrorMessage(loggingEvents.get(0)));
+ assertEquals("Supplied error message wasn't found in the log",
+ "Simple error message",
+ extractMessage(loggingEvents.get(0)));
+ }
+
+ @Test
+ public void testFormatting() {
+ ArrayList<String> loggingEvents = new ArrayList<>();
+ Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.INFO);
+
+ configuredLogger.info("Some {} string", "formatted");
+ assertEquals("The formatted message should've been captured", 1, loggingEvents.size());
+ assertEquals("Message should've been formatted", "Some formatted string", extractMessage(loggingEvents.get(0)));
+ }
+
+ @Test
+ public void testException() {
+ ArrayList<String> loggingEvents = new ArrayList<>();
+ Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.INFO);
+
+ Exception exception = new RuntimeException("My error");
+
+ configuredLogger.info("Logging with an exception", exception);
+ assertEquals("The formatted message should've been captured", 1, loggingEvents.size());
+ assertEquals("Message should've been formatted",
+ "My error",
+ extractExceptionMessage(loggingEvents.get(0)));
+
+ assertEquals("Message should've been formatted",
+ "java.lang.RuntimeException",
+ extractExceptionType(loggingEvents.get(0)));
+ }
+
+
+ /**
+ * Allows tests to check whether the log message contains a trace message.
+ * Override if needed.
+ * @param message String containing the full log message
+ * @return whether it is a trace message or not
+ */
+ protected boolean isTraceMessage(String message) {
+ return message.toLowerCase().contains("trace");
+ }
+
+ /**
+ * Allows tests to check whether the log message contains a debug message.
+ * Override if needed.
+ * @param message String containing the full log message
+ * @return whether it is a debug message or not
+ */
+ protected boolean isDebugMessage(String message) {
+ return message.toLowerCase().contains("debug");
+ }
+
+ /**
+ * Allows tests to check whether the log message contains an info message.
+ * Override if needed.
+ * @param message String containing the full log message
+ * @return whether it is an info message or not
+ */
+ protected boolean isInfoMessage(String message) {
+ return message.toLowerCase().contains("info");
+ }
+
+ /**
+ * Allows tests to check whether the log message contains a warn message.
+ * Override if needed.
+ * @param message String containing the full log message
+ * @return whether it is a warn message or not
+ */
+ protected boolean isWarnMessage(String message) {
+ return message.toLowerCase().contains("warn");
+ }
+
+ /**
+ * Allows tests to check whether the log message contains an error message.
+ * Override if needed.
+ * @param message String containing the full log message
+ * @return whether it is an error message or not
+ */
+ protected boolean isErrorMessage(String message) {
+ return message.toLowerCase().contains("error");
+ }
+
+ /**
+ * Extracts only the part of the log string that should represent the `message` string.
+ * @param message the full log message
+ * @return only the supplied message
+ */
+ public abstract String extractMessage(String message);
+
+ /**
+ * Extracts only the part of the log string that should represent the supplied exception message, if any.
+ * @param message the full log message
+ * @return only the supplied exception message
+ */
+ public abstract String extractExceptionMessage(String message);
+
+ /**
+ * Extracts only the part of the log string that should represent the supplied exception type.
+ * @param message the full log message
+ * @return only the supplied exception type name
+ */
+ public abstract String extractExceptionType(String message);
+
+ /**
+ * Configures the logger for running the tests.
+ * @param outputStream The output stream for logs to be written to
+ * @param level The expected level the tests will run for this logger
+ * @return a configured logger able to run the tests
+ */
+ public abstract Logger createLogger(ListAppendingOutputStream outputStream, Level level);
+
+} \ No newline at end of file
diff --git a/slf4j-simple/src/test/java/org/slf4j/SilentPrintStream.java b/slf4j-simple/src/test/java/org/slf4j/simple/SilentPrintStream.java
index 1d710d98..a440d2d7 100644
--- a/slf4j-simple/src/test/java/org/slf4j/SilentPrintStream.java
+++ b/slf4j-simple/src/test/java/org/slf4j/simple/SilentPrintStream.java
@@ -22,7 +22,7 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-package org.slf4j;
+package org.slf4j.simple;
import java.io.PrintStream;
diff --git a/slf4j-simple/src/test/java/org/slf4j/simple/SimpleLoggerMultithreadedInitializationTest.java b/slf4j-simple/src/test/java/org/slf4j/simple/SimpleLoggerMultithreadedInitializationTest.java
new file mode 100644
index 00000000..3abcb639
--- /dev/null
+++ b/slf4j-simple/src/test/java/org/slf4j/simple/SimpleLoggerMultithreadedInitializationTest.java
@@ -0,0 +1,73 @@
+/**
+ * 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.simple;
+
+import java.io.PrintStream;
+
+import org.junit.After;
+import org.junit.Before;
+import org.slf4j.LoggerFactoryFriend;
+import org.slf4j.helpers.StringPrintStream;
+import org.slf4j.testHarness.MultithreadedInitializationTest;
+
+public class SimpleLoggerMultithreadedInitializationTest extends MultithreadedInitializationTest {
+ // final static int THREAD_COUNT = 4 + Runtime.getRuntime().availableProcessors() * 2;
+ // private final List<Logger> createdLoggers = Collections.synchronizedList(new ArrayList<Logger>());
+ // private final AtomicLong eventCount = new AtomicLong(0);
+ //
+ // private final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1);
+ //
+ // final int diff = new Random().nextInt(10000);
+ static int NUM_LINES_IN_SLF4J_REPLAY_WARNING = 3;
+ private final PrintStream oldErr = System.err;
+ final String loggerName = this.getClass().getName();
+ StringPrintStream sps = new StringPrintStream(oldErr, false);
+
+ @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);
+ }
+
+ @Override
+ protected long getRecordedEventCount() {
+ return sps.stringList.size();
+ };
+
+ @Override
+ protected int extraLogEvents() {
+ return NUM_LINES_IN_SLF4J_REPLAY_WARNING;
+ }
+
+}
diff --git a/slf4j-simple/src/test/java/org/slf4j/simple/SimpleLoggerTest.java b/slf4j-simple/src/test/java/org/slf4j/simple/SimpleLoggerTest.java
new file mode 100644
index 00000000..ced12671
--- /dev/null
+++ b/slf4j-simple/src/test/java/org/slf4j/simple/SimpleLoggerTest.java
@@ -0,0 +1,152 @@
+/**
+ * Copyright (c) 2004-2022 QOS.ch Sarl (Switzerland)
+ * 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.simple;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.regex.Pattern;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SimpleLoggerTest {
+
+ String A_KEY = SimpleLogger.LOG_KEY_PREFIX + "a";
+ PrintStream original = System.out;
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ PrintStream replacement = new PrintStream(bout);
+
+ @Before
+ public void before() {
+ System.setProperty(A_KEY, "info");
+ }
+
+ @After
+ public void after() {
+ System.clearProperty(A_KEY);
+ System.clearProperty(SimpleLogger.CACHE_OUTPUT_STREAM_STRING_KEY);
+ System.clearProperty(SimpleLogger.SHOW_THREAD_ID_KEY);
+ System.clearProperty(SimpleLogger.SHOW_THREAD_NAME_KEY);
+ System.setErr(original);
+ }
+
+ @Test
+ public void emptyLoggerName() {
+ SimpleLogger simpleLogger = new SimpleLogger("a");
+ assertEquals("info", simpleLogger.recursivelyComputeLevelString());
+ }
+
+ @Test
+ public void offLevel() {
+ System.setProperty(A_KEY, "off");
+ SimpleLogger.init();
+ SimpleLogger simpleLogger = new SimpleLogger("a");
+ assertEquals("off", simpleLogger.recursivelyComputeLevelString());
+ assertFalse(simpleLogger.isErrorEnabled());
+ }
+
+ @Test
+ public void loggerNameWithNoDots_WithLevel() {
+ SimpleLogger.init();
+ SimpleLogger simpleLogger = new SimpleLogger("a");
+
+ assertEquals("info", simpleLogger.recursivelyComputeLevelString());
+ }
+
+ @Test
+ public void loggerNameWithOneDotShouldInheritFromParent() {
+ SimpleLogger simpleLogger = new SimpleLogger("a.b");
+ assertEquals("info", simpleLogger.recursivelyComputeLevelString());
+ }
+
+ @Test
+ public void loggerNameWithNoDots_WithNoSetLevel() {
+ SimpleLogger simpleLogger = new SimpleLogger("x");
+ assertNull(simpleLogger.recursivelyComputeLevelString());
+ }
+
+ @Test
+ public void loggerNameWithOneDot_NoSetLevel() {
+ SimpleLogger simpleLogger = new SimpleLogger("x.y");
+ assertNull(simpleLogger.recursivelyComputeLevelString());
+ }
+
+ @Test
+ public void checkUseOfLastSystemStreamReference() {
+ SimpleLogger.init();
+ SimpleLogger simpleLogger = new SimpleLogger(this.getClass().getName());
+
+ System.setErr(replacement);
+ simpleLogger.info("hello");
+ replacement.flush();
+ assertTrue(bout.toString().contains("INFO " + this.getClass().getName() + " - hello"));
+ }
+
+ @Test
+ public void checkUseOfCachedOutputStream() {
+ System.setErr(replacement);
+ System.setProperty(SimpleLogger.CACHE_OUTPUT_STREAM_STRING_KEY, "true");
+ SimpleLogger.init();
+ SimpleLogger simpleLogger = new SimpleLogger(this.getClass().getName());
+ // change reference to original before logging
+ System.setErr(original);
+
+ simpleLogger.info("hello");
+ replacement.flush();
+ assertTrue(bout.toString().contains("INFO " + this.getClass().getName() + " - hello"));
+ }
+
+ @Test
+ public void testTheadIdWithoutThreadName() {
+ System.setProperty(SimpleLogger.SHOW_THREAD_NAME_KEY, Boolean.FALSE.toString());
+ String patternStr = "^tid=\\d{1,12} INFO org.slf4j.simple.SimpleLoggerTest - hello";
+ commonTestThreadId(patternStr);
+ }
+
+ @Test
+ public void testThreadId() {
+ String patternStr = "^\\[.*\\] tid=\\d{1,12} INFO org.slf4j.simple.SimpleLoggerTest - hello";
+ commonTestThreadId(patternStr);
+ }
+
+ private void commonTestThreadId(String patternStr) {
+ System.setErr(replacement);
+ System.setProperty(SimpleLogger.SHOW_THREAD_ID_KEY, Boolean.TRUE.toString());
+ SimpleLogger.init();
+ SimpleLogger simpleLogger = new SimpleLogger(this.getClass().getName());
+ simpleLogger.info("hello");
+ replacement.flush();
+ String output = bout.toString();
+ System.out.println(patternStr);
+ System.out.println(output);
+ assertTrue(Pattern.compile(patternStr).matcher(output).lookingAt());
+ }
+}
diff --git a/slf4j-simple/src/test/java/org/slf4j/simple/multiThreadedExecution/MultithereadedExecutionTest.java b/slf4j-simple/src/test/java/org/slf4j/simple/multiThreadedExecution/MultithereadedExecutionTest.java
new file mode 100755
index 00000000..bb79ac54
--- /dev/null
+++ b/slf4j-simple/src/test/java/org/slf4j/simple/multiThreadedExecution/MultithereadedExecutionTest.java
@@ -0,0 +1,131 @@
+/**
+ * Copyright (c) 2004-2021 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.simple.multiThreadedExecution;
+
+import java.io.PrintStream;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Tests that output in multithreaded environments is not mingled.
+ *
+ * See also https://jira.qos.ch/browse/SLF4J-515
+ */
+public class MultithereadedExecutionTest {
+
+ private static final int THREAD_COUNT = 2;
+ private final Thread[] threads = new Thread[THREAD_COUNT];
+
+ private static final long TEST_DURATION_IN_MILLIS = 100;
+
+ private final PrintStream oldOut = System.out;
+ StateCheckingPrintStream scps = new StateCheckingPrintStream(oldOut);
+
+ volatile boolean signal = false;
+
+ @Before
+ public void setup() {
+ System.setErr(scps);
+ // 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(oldOut);
+ }
+
+ @Test
+ public void test() throws Throwable {
+ WithException withException = new WithException();
+ Other other = new Other();
+ threads[0] = new Thread(withException);
+ threads[1] = new Thread(other);
+ threads[0].start();
+ threads[1].start();
+ Thread.sleep(TEST_DURATION_IN_MILLIS);
+ signal = true;
+ threads[0].join();
+ threads[1].join();
+
+ if (withException.throwable != null) {
+ throw withException.throwable;
+ }
+
+ if (other.throwable != null) {
+ throw other.throwable;
+ }
+
+ }
+
+ class WithException implements Runnable {
+
+ volatile Throwable throwable;
+ Logger logger = LoggerFactory.getLogger(WithException.class);
+
+ @Override
+ public void run() { // TODO Auto-generated method stub
+ int i = 0;
+
+ while (!signal) {
+ try {
+ logger.info("Hello {}", i, new Throwable("i=" + i));
+ i++;
+ } catch (Throwable t) {
+ throwable = t;
+ MultithereadedExecutionTest.this.signal = true;
+ return;
+ }
+ }
+
+ }
+ }
+
+ class Other implements Runnable {
+ volatile Throwable throwable;
+ Logger logger = LoggerFactory.getLogger(Other.class);
+
+ @Override
+ public void run() {
+ int i = 0;
+ while (!signal) {
+ try {
+ logger.info("Other {}", i++);
+ } catch (Throwable t) {
+ throwable = t;
+ MultithereadedExecutionTest.this.signal = true;
+ return;
+ }
+ }
+ }
+ }
+
+}
diff --git a/slf4j-simple/src/test/java/org/slf4j/simple/multiThreadedExecution/StateCheckingPrintStream.java b/slf4j-simple/src/test/java/org/slf4j/simple/multiThreadedExecution/StateCheckingPrintStream.java
new file mode 100755
index 00000000..dee4d0d9
--- /dev/null
+++ b/slf4j-simple/src/test/java/org/slf4j/simple/multiThreadedExecution/StateCheckingPrintStream.java
@@ -0,0 +1,140 @@
+/**
+ * Copyright (c) 2004-2021 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.simple.multiThreadedExecution;
+
+import java.io.PrintStream;
+import java.util.regex.Pattern;
+
+public class StateCheckingPrintStream extends PrintStream {
+
+ static String PACKAGE_NAME = "org.slf4j.simple.multiThreadedExecution";
+
+
+ enum State {
+ INITIAL, UNKNOWN, HELLO, THROWABLE, AT1, AT2, OTHER;
+ }
+
+ PrintStream other;
+
+ volatile State currentState = State.INITIAL;
+
+ public StateCheckingPrintStream(PrintStream ps) {
+ super(ps);
+ }
+
+ public void print(String s) {
+ }
+
+ public void println(String s) {
+
+ State next = computeState(s);
+ //System.out.println(next + " " + s);
+ switch (currentState) {
+ case INITIAL:
+ currentState = next;
+ break;
+
+ case UNKNOWN:
+ currentState = next;
+ break;
+
+ case OTHER:
+ if (next == State.UNKNOWN) {
+ currentState = State.UNKNOWN;
+ return;
+ }
+
+ if (next != State.OTHER && next != State.HELLO) {
+ throw badState(s, currentState, next);
+ }
+ currentState = next;
+ break;
+
+ case HELLO:
+ if (next != State.THROWABLE) {
+ throw badState(s, currentState, next);
+ }
+ currentState = next;
+ break;
+ case THROWABLE:
+ if (next != State.AT1) {
+ throw badState(s, currentState, next);
+ }
+ currentState = next;
+ break;
+
+ case AT1:
+ if (next != State.AT2) {
+ throw badState(s, currentState, next);
+ }
+ currentState = next;
+ break;
+
+ case AT2:
+ currentState = next;
+ break;
+ default:
+ throw new IllegalStateException("Unreachable code");
+ }
+ }
+
+ private IllegalStateException badState(String s, State currentState2, State next) {
+ return new IllegalStateException("Unexpected state " + next + " for current state " + currentState2 + " for " + s);
+
+ }
+
+ String OTHER_PATTERN_STR = ".*Other \\d{1,5}";
+ String HELLO_PATTERN_STR = ".*Hello \\d{1,5}";
+ String THROWABLE_PATTERN_STR = "java.lang.Throwable: i=\\d{1,5}";
+ String AT1_PATTERN_STR = "\\s*at " + PACKAGE_NAME + ".*";
+ String AT2_PATTERN_STR = "\\s*at " + ".*Thread.java.*";
+
+ Pattern PATTERN_OTHER = Pattern.compile(OTHER_PATTERN_STR);
+ Pattern PATTERN_HELLO = Pattern.compile(HELLO_PATTERN_STR);
+ Pattern PATTERN_THROWABLE = Pattern.compile(THROWABLE_PATTERN_STR);
+ Pattern PATTERN_AT1 = Pattern.compile(AT1_PATTERN_STR);
+ Pattern PATTERN_AT2 = Pattern.compile(AT2_PATTERN_STR);
+
+ private State computeState(String s) {
+
+ if (PATTERN_OTHER.matcher(s).matches()) {
+ return State.OTHER;
+ } else if (PATTERN_HELLO.matcher(s).matches()) {
+ return State.HELLO;
+ } else if (PATTERN_THROWABLE.matcher(s).matches()) {
+ return State.THROWABLE;
+ } else if (PATTERN_AT1.matcher(s).matches()) {
+ return State.AT1;
+ } else if (PATTERN_AT2.matcher(s).matches()) {
+ return State.AT2;
+ } else {
+ return State.UNKNOWN;
+ }
+ }
+
+ public void println(Object o) {
+ println(o.toString());
+ }
+} \ No newline at end of file
diff --git a/slf4j-site/pom.xml b/slf4j-site/pom.xml
deleted file mode 100755
index 2e0c180d..00000000
--- a/slf4j-site/pom.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-parent</artifactId>
- <version>1.7.13-SNAPSHOT</version>
- </parent>
-
- <artifactId>slf4j-site</artifactId>
-
- <packaging>jar</packaging>
- <name>SLF4J Site</name>
- <description>SLF4J Site</description>
- <url>http://www.slf4j.org</url>
-
- <build>
- <resources>
- <resource>
- <directory>src/site/pages</directory>
- <!--We're saving filtered html docs in a temporary folder-->
- <!--and telling the site plug in to get the docs there.-->
- <targetPath>../../../target/site</targetPath>
- <filtering>true</filtering>
- </resource>
- </resources>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-site-plugin</artifactId>
- <version>${maven-site-plugin.version}</version>
- <configuration>
- <outputDirectory>${project.parent.basedir}/target/site
- </outputDirectory>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project> \ No newline at end of file
diff --git a/slf4j-site/src/site/images.src/bindings.flw b/slf4j-site/src/site/images.src/bindings.flw
deleted file mode 100644
index 15ca876c..00000000
--- a/slf4j-site/src/site/images.src/bindings.flw
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/images.src/bridging-black.flw b/slf4j-site/src/site/images.src/bridging-black.flw
deleted file mode 100755
index 1552a824..00000000
--- a/slf4j-site/src/site/images.src/bridging-black.flw
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/images.src/bridging.flw b/slf4j-site/src/site/images.src/bridging.flw
deleted file mode 100644
index 3efbf2ba..00000000
--- a/slf4j-site/src/site/images.src/bridging.flw
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/images.src/concrete-bindings.odg b/slf4j-site/src/site/images.src/concrete-bindings.odg
deleted file mode 100644
index ea1a712d..00000000
--- a/slf4j-site/src/site/images.src/concrete-bindings.odg
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/images.src/core-bindings.flw b/slf4j-site/src/site/images.src/core-bindings.flw
deleted file mode 100644
index 72333e54..00000000
--- a/slf4j-site/src/site/images.src/core-bindings.flw
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/images.src/core-bindings1.flw b/slf4j-site/src/site/images.src/core-bindings1.flw
deleted file mode 100644
index 727f54ae..00000000
--- a/slf4j-site/src/site/images.src/core-bindings1.flw
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/images.src/core-bindings2.flw b/slf4j-site/src/site/images.src/core-bindings2.flw
deleted file mode 100644
index a0fcc282..00000000
--- a/slf4j-site/src/site/images.src/core-bindings2.flw
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/images.src/core-bindings3.flw b/slf4j-site/src/site/images.src/core-bindings3.flw
deleted file mode 100644
index d87c4035..00000000
--- a/slf4j-site/src/site/images.src/core-bindings3.flw
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/images.src/follow_us.odg b/slf4j-site/src/site/images.src/follow_us.odg
deleted file mode 100644
index 3b7c8474..00000000
--- a/slf4j-site/src/site/images.src/follow_us.odg
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/images.src/legacy.odg b/slf4j-site/src/site/images.src/legacy.odg
deleted file mode 100644
index 52ab455c..00000000
--- a/slf4j-site/src/site/images.src/legacy.odg
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/pages/.htaccess b/slf4j-site/src/site/pages/.htaccess
deleted file mode 100644
index eb903bf0..00000000
--- a/slf4j-site/src/site/pages/.htaccess
+++ /dev/null
@@ -1 +0,0 @@
-Redirect permanent /log4j-over-slf4j.html http://www.slf4j.org/legacy.html#log4j-over-slf4j \ No newline at end of file
diff --git a/slf4j-site/src/site/pages/bug-reporting.html b/slf4j-site/src/site/pages/bug-reporting.html
deleted file mode 100755
index 259d7625..00000000
--- a/slf4j-site/src/site/pages/bug-reporting.html
+++ /dev/null
@@ -1,90 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <title>SLF4J Bug reporting</title>
- <link rel="stylesheet" type="text/css" media="screen" href="css/site.css" />
- </head>
- <body>
- <script type="text/javascript">prefix='';
- </script>
-
- <script src="templates/header.js" type="text/javascript"></script>
- <div id="left">
- <script src="templates/left.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
-
- <h1>Before you report a bug</h1>
-
- <p>The SLF4J community consists of those who use SLF4J and its
- implementations, help answer questions on discussions lists,
- contribute documentation and patches, and those who develop and
- maintain the code for SLF4J and its implementations. Almost all
- those who assist on a day to day basis resolving bug reports do
- this for a wide variety of reasons, and almost all of them do this
- on their own time.
- </p>
-
- <p>Many bugs reported end up not being a bug in SLF4J, but are due
- to misconfiguration, problems caused by installed applications,
- the operating system, etc.
- </p>
-
- <p>Before reporting a bug please make every effort to resolve the
- problem yourself. <em>Just reporting a bug will not fix it. A good
- bug report includes a detailed description of the problem and a
- succinct test case which can reproduce the problem.</em>
- </p>
-
- <h3>Review the documentation</h3>
-
- <p>Review the documentation for the version of component you are
- using. The problem you are having may already be addressed in the
- docs.
- </p>
-
- <h3>Search the mailing list archives</h3>
-
- <p>It is very likely you are not the first to run into a problem.
- Others may have already found a solution. Our various <a
- href="mailing-lists.html">mailing lists</a> are likely to have
- discussed this problem before.
- </p>
-
- <h3>Search JIRA</h3>
-
- <p>Please search the bug database to see if the bug you are seeing
- has already been reported. The bug may have already been fixed
- and is available in a later version. If someone else has reported
- the same bug, you could add supporting information to help
- reproduce and resolve the bug.
- </p>
-
- <ul>
- <li><a
- href="http://jira.qos.ch/issues/?jql=project%20%3D%20SLF4J">Search for
- SLF4J bugs</a></li>
- </ul>
-
- <h3>Reporting a bug</h3>
-
- <p>Only after you have exhausted the aforementioned steps, should
- you file a formal report in JIRA, our bug tracking system.
- </p>
-
- <p>Please make sure you provide as much information as
- possible. Its very hard to fix a bug if the person looking into
- the problem can't reproduce it.
- </p>
-
- <script src="templates/footer.js" type="text/javascript"></script>
-
-
-</div>
-</body>
-</html>
diff --git a/slf4j-site/src/site/pages/changes/changes-1.3.txt b/slf4j-site/src/site/pages/changes/changes-1.3.txt
deleted file mode 100644
index 40797650..00000000
--- a/slf4j-site/src/site/pages/changes/changes-1.3.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-
-Changes in SLF4J 1.3.0 with respect to 1.2 as reported by the clirr
-tool.
-
-slf4j-api
-=========
-
-INFO: 6000: org.slf4j.Logger: Added public field ROOT_LOGGER_NAME
-INFO: 8000: org.slf4j.LoggerFactory: Class org.slf4j.LoggerFactory added
-INFO: 8000: org.slf4j.MarkerFactory: Class org.slf4j.MarkerFactory added
-INFO: 8000: org.slf4j.helpers.BasicMarker: Class org.slf4j.helpers.BasicMarker added
-INFO: 8000: org.slf4j.helpers.BasicMarkerFactory: Class org.slf4j.helpers.BasicMarkerFactory added
-INFO: 8000: org.slf4j.helpers.MarkerIgnoringBase: Class org.slf4j.helpers.MarkerIgnoringBase added
-INFO: 8000: org.slf4j.helpers.MessageFormatter: Class org.slf4j.helpers.MessageFormatter added
-INFO: 8000: org.slf4j.helpers.Util: Class org.slf4j.helpers.Util added
-ERROR: 8001: org.slf4j.impl.BasicMarker: Class org.slf4j.impl.BasicMarker removed
-ERROR: 8001: org.slf4j.impl.BasicMarkerFactory: Class org.slf4j.impl.BasicMarkerFactory removed
-ERROR: 8001: org.slf4j.impl.MarkerIgnoringBase: Class org.slf4j.impl.MarkerIgnoringBase removed
-ERROR: 8001: org.slf4j.impl.MessageFormatter: Class org.slf4j.impl.MessageFormatter removed
-ERROR: 8001: org.slf4j.impl.Util: Class org.slf4j.impl.Util removed
-INFO: 8000: org.slf4j.spi.LocationAwareLogger: Class org.slf4j.spi.LocationAwareLogger added
-
-slf4j-nop
-=========
-
-ERROR: 8001: org.slf4j.LoggerFactory: Class org.slf4j.LoggerFactory removed
-ERROR: 8001: org.slf4j.MarkerFactory: Class org.slf4j.MarkerFactory removed
-
-slf4j-simple
-============
-
-ERROR: 8001: org.slf4j.LoggerFactory: Class org.slf4j.LoggerFactory removed
-ERROR: 8001: org.slf4j.MarkerFactory: Class org.slf4j.MarkerFactory removed
-
-slf4j-log4j12
-=============
-
-ERROR: 8001: org.slf4j.LoggerFactory: Class org.slf4j.LoggerFactory removed
-ERROR: 8001: org.slf4j.MarkerFactory: Class org.slf4j.MarkerFactory removed
-
-slf4j-jdk14
-===========
-
-ERROR: 8001: org.slf4j.LoggerFactory: Class org.slf4j.LoggerFactory removed
-ERROR: 8001: org.slf4j.MarkerFactory: Class org.slf4j.MarkerFactory removed \ No newline at end of file
diff --git a/slf4j-site/src/site/pages/codes.html b/slf4j-site/src/site/pages/codes.html
deleted file mode 100755
index f331be3b..00000000
--- a/slf4j-site/src/site/pages/codes.html
+++ /dev/null
@@ -1,483 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <title>SLF4J Error Codes</title>
- <link rel="stylesheet" type="text/css" media="screen" href="css/site.css" />
- <link rel="stylesheet" type="text/css" href="css/prettify.css" />
-
- <style>
- h3.doAnchor {
- border-top: 2px solid #888;
- padding-top: 1ex;
- }
- </style>
-</head>
-<body onload="prettyPrint(); decorate();">
- <script type="text/javascript" src="js/prettify.js"></script>
- <script type="text/javascript">prefix='';</script>
- <script type="text/javascript" src="templates/header.js"></script>
- <script type="text/javascript" src="js/jquery-min.js"></script>
- <script type="text/javascript" src="js/decorator.js"></script>
-
- <div id="left">
- <script src="templates/left.js" type="text/javascript"></script>
- </div>
-
-
- <div id="content">
-
- <center>
- <h2>SLF4J warning or error messages and their meanings</h2>
-
- </center>
-
-
- <h3 class="doAnchor" name="release">The method
- <code>o.a.commons.logging.impl.SLF4FLogFactory#release</code> was
- invoked.
- </h3>
-
- <p>Given the structure of the commons-logging API, in particular
- as implemented by SLF4J, the
- <code>o.a.commons.logging.impl.SLF4FLogFactory#release()</code>
- method should never be called. However, depending on the
- deployment of <em>commons-logging.jar</em> files in your servlet
- container, <code>release()</code> method may be unexpectedly
- invoked by a copy of
- <code>org.apache.commons.logging.LogFactory</code> class shipping
- with <em>commons-logging.jar</em>.
- </p>
-
- <p>This is a relatively common occurrence with recent versions of
- Tomcat, especially if you place <em>jcl-over-slf4j.jar</em> in
- <em>WEB-INF/lib</em> directory of your web-application instead of
- <em>$TOMCAT_HOME/common/lib</em>, where $TOMCAT_HOME stands for
- the directory where Tomcat is installed. In order to fully benefit
- from the stability offered by <em>jcl-over-slf4j.jar</em>, we
- recommend that you place <em>jcl-over-slf4j.jar</em> in
- <em>$TOMCAT_HOME/common/lib</em> without placing a copy in your
- web-applications.
- </p>
-
- <p>Please also see <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=22">bug
- #22</a>.</p>
-
- <!-- ====================================================== -->
-
- <h3 class="doAnchor" name="unsupported_operation_in_jcl_over_slf4j">Operation
- [suchAndSuch] is not supported in jcl-over-slf4j.
- </h3>
-
- <p>An <code>UnsupportedOperationException</code> is thrown whenever
- one of the protected methods introduced in JCL 1.1 are
- invoked. These methods are invoked by <code>LogFactory</code>
- implementations shipping with
- <em>commons-logging.jar</em>. However, the <code>LogFactory</code>
- implemented by <em>jcl-over-slf4j.jar</em>, namely
- SLF4FLogFactory, does not call any of these methods.
- </p>
-
- <p>If you observe this problem, then it is highly probable that you
- have a copy of <em>commons-logging.jar</em> in your class path
- overriding the classes shipping with
- <em>jcl-over-slf4j.jar</em>. Note that this issue is very similar
- in nature to the warning issued when the
- "o.a.commons.logging.impl.SLF4FLogFactory.release()" method is
- invoked, discussed in the previous item.
- </p>
-
- <!-- ====================================================== -->
- <h3 class="doAnchor" name="loggerNameMismatch">Detected logger
- name mismatch</h3>
-
- <p>Logger name mismatch warnings are printed only if the
- <code>slf4j.detectLoggerNameMismatch</code> system property is set
- to true. By default, this property is not set and no warnings will
- be printed even in case of a logger name mismatch.
- </p>
-
- <p><span class="label">since 1.7.9</span> The warning will
- be printed in case the name of the logger specified via a class
- passed as an argument to the
- <code>LoggerFactory.getLogger(Class)</code> method differs from
- the name of the caller as computed internally by SLF4J.
- </p>
-
- <p>For example, the following code snippet</p>
-
-<pre class="prettyprint source">package com.acme;
-import com.foo.Kangaroo;
-
-class <b>Fruit</b> {
- Logger logger = LoggerFactory.getLogger(<b>Kangaroo.class</b>);
-}</pre>
-
- <p>will result in the warning</p>
-
- <pre class="prettyprint source">SLF4J: Detected logger name mismatch. Given name: "com.foo.Kangaroo"; computed name: "com.acme.Fruit".</pre>
-
- <p>but only if <code>slf4j.detectLoggerNameMismatch</code> system
- property is set to true.</p>
-
- <p>No warning will be issued for the special case where the class
- in which the logger is defined is a super-type of the class
- parameter passed as argument. For example,</p>
-
- <pre class="prettyprint source">class A {
- Logger logger = LoggerFactory.getLogger(getClass());
-}
-class B extends A {
- // no mismatch warning will be issued when B is instantiated
- // given that class A is a super-type of class B
-}</pre>
-
- <p>If you come across a mismatch warning which cannot be
- explained, then you might have spotted a white elephant, that is a
- very rare occurrence where SLF4J cannot correctly compute the name
- of the class where a logger is defined. We are very interested to
- learn about such cases. If and when you spot an inexplicable
- mismatch, please do file a <a href="bug-reporting.html">bug
- report</a> with us.
- </p>
-
- <!-- ====================================================== -->
-
- <h3 class="doAnchor" name="StaticLoggerBinder">Failed to load class
- <code>org.slf4j.impl.StaticLoggerBinder</code></h3>
-
- <p>This error is reported when the
- <code>org.slf4j.impl.StaticLoggerBinder</code> class could not be
- loaded into memory. This happens when no appropriate SLF4J
- binding could be found on the class path. Placing one (and only
- one) of <em>slf4j-nop.jar</em>, <em>slf4j-simple.jar</em>,
- <em>slf4j-log4j12.jar</em>, <em>slf4j-jdk14.jar</em> or
- <em>logback-classic.jar</em> on the class path should solve the
- problem.
- </p>
-
- <p><span class="label">since 1.6.0</span> As of SLF4J version 1.6, in the absence of a binding, SLF4J
- will default to a no-operation (NOP) logger implementation.
- </p>
-
- <p>You can download SLF4J bindings from the project <a
- href="http://www.slf4j.org/download.html">download page</a>. </p>
-
- <!-- ====================================================== -->
- <!-- duplicates /faq.html#IllegalAccessError -->
-
-<!--
- <h3>
- <a name="illegalAccess" href="#illegalAccess">java.lang.IllegalAccessError: tried to access field
- org.slf4j.impl.StaticLoggerBinder.SINGLETON from class
- org.slf4j.LoggerFactory</a>
- </h3>
-
- <p>When this errors occurs, the exception looks as follows:</p>
- <p class="source">java.lang.IllegalAccessError: tried to access field org.slf4j.impl.StaticLoggerBinder.SINGLETON \
- from class org.slf4j.LoggerFactory
- at org.slf4j.LoggerFactory.&lt;clinit&gt;(LoggerFactory.java:60)
- ... </p>
-
- <p>The error is caused by the static initializer of the
- <code>LoggerFactory</code> class attempting to directly access the
- SINGLETON field of
- <code>org.slf4j.impl.StaticLoggerBinder</code>. While this was
- allowed in SLF4J 1.5.5 and earlier, in 1.5.6 and later the
- SINGLETON field has been marked as private access.
- </p>
-
- <p>From a broader perspective, this issue is a manifestation of
- problems encountered when mixing different versions of SLF4J
- artifacts. Please also refer to the relevant <a
- href="faq.html#compatibility">FAQ entry</a>.
- </p>
--->
-
- <!-- ====================================================== -->
- <h3 class="doAnchor" name="multiple_bindings">Multiple bindings
- were found on the class path
- </h3>
-
-
- <p>SLF4J API is designed to bind with one and only one underlying
- logging framework at a time. If more than one binding is present
- on the class path, SLF4J will emit a warning, listing the location
- of those bindings.</p>
-
- <p>When multiple bindings are available on the class path, select
- one and only one binding you wish to use, and remove the other
- bindings. For example, if you have both
- <em>slf4j-simple-${version}.jar</em> and
- <em>slf4j-nop-${version}.jar</em> on the class path and you wish
- to use the nop (no-operation) binding, then remove
- <em>slf4j-simple-${version}.jar</em> from the class path.
- </p>
-
- <p>The list of locations that SLF4J provides in this warning
- usually provides sufficient information to identify the dependency
- transitively pulling in an unwanted SLF4J binding into your
- project. In your project's pom.xml file, exclude this SLF4J
- binding when declaring the unscrupulous dependency. For example,
- <em>cassandra-all</em> version 0.8.1 declares both <em>log4j</em>
- and <em>slf4j-log4j12</em> as compile-time dependencies. Thus,
- when you include <em>cassandra-all</em> as a dependency in your
- project, the <em>cassandra-all</em> declaration will cause both
- <em>slf4j-log4j12.jar</em> and <em>log4j.jar</em> to be pulled in
- as dependencies. In case you do not wish to use log4j as the the
- SLF4J backend, you can instruct Maven to exclude these two
- artifacts as shown next:</p>
-
- <pre class="prettyprint">&lt;dependencies>
- &lt;dependency>
- &lt;groupId> org.apache.cassandra&lt;/groupId>
- &lt;artifactId>cassandra-all&lt;/artifactId>
- &lt;version>0.8.1&lt;/version>
-
- &lt;exclusions>
- &lt;exclusion>
- &lt;groupId>org.slf4j&lt;/groupId>
- &lt;artifactId>slf4j-log4j12&lt;/artifactId>
- &lt;/exclusion>
- &lt;exclusion>
- &lt;groupId>log4j&lt;/groupId>
- &lt;artifactId>log4j&lt;/artifactId>
- &lt;/exclusion>
- &lt;/exclusions>
-
- &lt;/dependency>
-&lt;/dependencies></pre>
-
- <p><span class="label notice">Note</span> The warning emitted by
- SLF4J is just that, a warning. Even when multiple bindings are
- present, SLF4J will pick one logging framework/implementation and
- bind with it. The way SLF4J picks a binding is determined by the
- JVM and for all practical purposes should be considered random. As
- of version 1.6.6, SLF4J will name the framework/implementation
- class it is actually bound to.</p>
-
- <p>Embedded components such as libraries or frameworks should not
- declare a dependency on any SLF4J binding but only depend on
- slf4j-api. When a library declares a compile-time dependency on a
- SLF4J binding, it imposes that binding on the end-user, thus
- negating SLF4J's purpose. When you come across an embedded
- component declaring a compile-time dependency on any SLF4J binding,
- please take the time to contact the authors of said
- component/library and kindly ask them to mend their ways.</p>
-
- <!-- ====================================================== -->
-
- <h3 class="doAnchor" name="version_mismatch">slf4j-api version
- does not match that of the binding</h3>
-
- <p>An SLF4J binding designates an artifact such as
- <em>slf4j-jdk14.jar</em> or <em>slf4j-log4j12.jar</em> used to
- <em>bind</em> slf4j to an underlying logging framework, say,
- java.util.logging and respectively log4j.
- </p>
-
- <p>Mixing mixing different versions of <em>slf4j-api.jar</em> and
- SLF4J binding can cause problems. For example, if you are using
- slf4j-api-${project.version}.jar, then you should also use
- slf4j-simple-${project.version}.jar, using slf4j-simple-1.5.5.jar
- will not work.</p>
-
- <p><span class="label notice">Note</span> From the client's
- perspective all versions of slf4j-api are compatible. Client code
- compiled with <em>slf4j-api-N.jar</em> will run perfectly fine
- with <em>slf4j-api-M.jar</em> for any N and M. You only need to
- ensure that the version of your binding matches that of the
- slf4j-api.jar. You do not have to worry about the version of
- slf4j-api.jar used by a given dependency in your project. You
- can always use any version of <em>slf4j-api.jar</em>, and as long
- as the version of <em>slf4j-api.jar</em> and its binding match,
- you should be fine.
- </p>
-
- <p>At initialization time, if SLF4J suspects that there may be a
- api vs. binding version mismatch problem, it will emit a warning
- about the suspected mismatch.
- </p>
-
- <!-- ====================================================== -->
-
- <h3 class="doAnchor" name="null_LF">Logging factory implementation
- cannot be null</h3>
-
- <p>This error is reported when the <code>LoggerFactory</code>
- class could not find an appropriate binding. Placing one (and only
- one) of <em>slf4j-nop.jar</em>, <em>slf4j-simple.jar</em>,
- <em>slf4j-log4j12.jar</em>, <em>slf4j-jdk14.jar</em> or
- <em>logback-classic.jar</em> on the class path should prove to be
- an effective remedy.
- </p>
-
- <!-- ====================================================== -->
-
- <h3 class="doAnchor" name="log4jDelegationLoop">Detected both
- log4j-over-slf4j.jar AND slf4j-log4j12.jar on the class path,
- preempting <code>StackOverflowError</code>.
- </h3>
-
- <p>The purpose of slf4j-log4j12 module is to delegate or redirect
- calls made to an SLF4J logger to log4j. The purpose of the
- log4j-over-slf4j module is to redirect calls made to a log4j
- logger to SLF4J. If both <em>slf4j-log4j12.jar</em> and
- <em>log4j-over-slf4j.jar</em> are present on the class path, a
- <code>StackOverflowError</code> will inevitably occur immediately
- after the first invocation of an SLF4J or a log4j logger.
- </p>
-
- <p>Here is how the exception might look like:</p>
-
- <pre class="prettyprint source">Exception in thread "main" java.lang.StackOverflowError
- at java.util.Hashtable.containsKey(Hashtable.java:306)
- at org.apache.log4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:36)
- at org.apache.log4j.LogManager.getLogger(LogManager.java:39)
- at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:73)
- at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:249)
- at org.apache.log4j.Category.&lt;init>(Category.java:53)
- at org.apache.log4j.Logger..&lt;init>(Logger.java:35)
- at org.apache.log4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:39)
- at org.apache.log4j.LogManager.getLogger(LogManager.java:39)
- at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:73)
- at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:249)
- at org.apache.log4j.Category..&lt;init>(Category.java:53)
- at org.apache.log4j.Logger..&lt;init>(Logger.java:35)
- at org.apache.log4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:39)
- at org.apache.log4j.LogManager.getLogger(LogManager.java:39)
- subsequent lines omitted...</pre>
-
- <p><span class="label">Since 1.5.11</span> SLF4J software preempts
- the inevitable stack overflow error by throwing an exception with
- details about the actual cause of the problem. This is deemed to
- be better than leaving the user wondering about the reasons of the
- <code>StackOverflowError</code>.
- </p>
-
- <p>For more background on this topic see <a
- href="legacy.html">Bridging legacy APIs</a>.
- </p>
-
- <!-- ====================================================== -->
-
-
- <h3 class="doAnchor" name="jclDelegationLoop">Detected both
- jcl-over-slf4j.jar AND slf4j-jcl.jar on the class path, preempting
- <code>StackOverflowError</code>.
- </h3>
-
- <p>The purpose of slf4j-jcl module is to delegate or redirect
- calls made to an SLF4J logger to jakarta commons logging
- (JCL). The purpose of the jcl-over-slf4j module is to redirect
- calls made to a JCL logger to SLF4J. If both
- <em>slf4j-jcl.jar</em> and <em>jcl-over-slf4j.jar</em> are present
- on the class path, then a <code>StackOverflowError</code> will
- inevitably occur immediately after the first invocation of an
- SLF4J or a JCL logger.
- </p>
-
- <p>Here is how the exception might look like:</p>
-
- <pre class="prettyprint source">Exception in thread "main" java.lang.StackOverflowError
- at java.lang.String.hashCode(String.java:1482)
- at java.util.HashMap.get(HashMap.java:300)
- at org.slf4j.impl.JCLLoggerFactory.getLogger(JCLLoggerFactory.java:67)
- at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:249)
- at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:155)
- at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:289)
- at org.slf4j.impl.JCLLoggerFactory.getLogger(JCLLoggerFactory.java:69)
- at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:249)
- at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:155)
- subsequent lines omitted...</pre>
-
-
- <p><span class="label">Since 1.5.11</span> SLF4J software preempts
- the inevitable stack overflow error by throwing an exception with
- details about the actual cause of the problem. This is deemed to
- be better than leaving the user wondering about the reasons of the
- <code>StackOverflowError</code>.
- </p>
-
- <p>For more background on this topic see <a
- href="legacy.html">Bridging legacy APIs</a>.
- </p>
-
- <!-- ====================================================== -->
-
- <h3 class="doAnchor" name="no_static_mdc_binder">Failed to load
- class "org.slf4j.impl.StaticMDCBinder"</h3>
-
- <p>This error indicates that appropriate SLF4J binding could not
- be found on the class path. Placing one (and only one) of
- <em>slf4j-nop.jar</em>, <em>slf4j-simple.jar</em>,
- <em>slf4j-log4j12.jar</em>, <em>slf4j-jdk14.jar</em> or
- <em>logback-classic.jar</em> on the class path should solve the
- problem.
- </p>
-
- <!-- ====================================================== -->
-
- <h3 class="doAnchor" name="null_MDCA">MDCAdapter cannot be null
- </h3>
-
- <p>This error is reported when <code>org.slf4j.MDC</code> class
- has not been initialized correctly. Same cause and remedy as the
- previously listed item.
- </p>
-
- <!-- ====================================================== -->
-
- <h3 class="doAnchor" name="log4j_version">SLF4J versions 1.4.0 and
- later requires log4j 1.2.12 or later</h3>
-
- <p>The trace level was added to log4j in version 1.2.12 released
- on August 29, 2005. The trace level was added to the SLF4J API in
- version 1.4.0 on May 16th, 2007. Thus, starting with SLF4J 1.4.0,
- the log4j binding for SLF4J requires log4j version 1.2.12 or
- above.
- </p>
-
- <p>However, as reported in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=68">bug 68</a>, in
- some environments it may be difficult to upgrade the log4j
- version. To accommodate such circumstances, SLF4J's
- <code>Log4jLoggerAdapter</code> will map the TRACE level as
- DEBUG.</p>
-
-
- <h3 class="doAnchor" name="substituteLogger" >Substitute loggers
- were created during the default configuration phase of the
- underlying logging system</h3>
-
- <p>Highly configurable logging systems such as logback and log4j
- may create components which invoke loggers during their own
- initialization. See issue <a
- href="http://jira.qos.ch/browse/LOGBACK-127">LOGBACK-127</a> for a
- typical occurrence. However, since the binding process with SLF4J
- has not yet completed (because the underlying logging system was
- not yet completely loaded into memory), it is not possible to
- honor such logger creation requests.</p>
-
- <p>To avoid this chicken-and-egg problem, SLF4J creates substitute
- loggers during this phase (initialization). Calls made to the
- substitute loggers during this phase are simply dropped. After the
- initialization completes, the substitute logger will delegate
- logging calls to the appropriate logger implementation and
- otherwise will function as any other logger returned by
- <code>LoggerFactory</code>.
- </p>
-
- <p>If any substitute logger had to be created, SLF4J will emit a a
- listing of such loggers. This list is intended to let you know
- that any logging calls made to these loggers during initialization
- have been dropped.
- </p>
-
-
- <script src="templates/footer.js" type="text/javascript"></script>
- </div>
-
-</body>
-</html>
diff --git a/slf4j-site/src/site/pages/compatibility.html b/slf4j-site/src/site/pages/compatibility.html
deleted file mode 100755
index cf4afb9c..00000000
--- a/slf4j-site/src/site/pages/compatibility.html
+++ /dev/null
@@ -1,269 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-
-<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
-<title>Compatibility report</title>
-<link rel="stylesheet" type="text/css" media="screen" href="css/site.css" />
-</head>
-<body>
- <script>
-prefix='';
-</script>
-
-<script src="templates/header.js"></script>
-<div id="left">
- <script src="templates/left.js"></script>
-</div>
-<div id="right">
- <script src="templates/right.js"></script>
-</div>
-<div id="content">
-
-
- <h1>Compatibility report</h1>
-
- <p>Given the very large user base of SLF4J, we take backward
- compatibility very seriously. As such, changes that may cause
- incompatibility problems are listed in this page. Moreover, since
- slf4j-api.jar is the main entry point into SLF4J, that is the module
- that will be covered in most detail.
- </p>
-
- <p>Please note that in many cases incompatibility problems are
- caused by mixing different versions of slf4j artifacts. For example,
- if you are using slf4j-api-1.5.4.jar you should also use
- slf4j-simple-1.5.4.jar, using slf4j-simple-1.4.2.jar will not
- work. The same goes for all other SLF4J artifacts.
- </p>
-
- <p>The list is computed using <a
- href="http://clirr.sourceforge.net/">clirr</a>. If you have reasons
- to suspect incompatible changes not mentioned here, please kindly
- contact the slf4j developers list.</p>
-
- <h2><a href="#1_5_7" name="1_5_6">Version 1.5.7 compared to 1.5.6</a></h2>
-
- <p>No breaking changes to report.</p>
-
- <h2><a href="#1_5_6" name="1_5_5">Version 1.5.6 compared to 1.5.5</a></h2>
-
-
- <table class="bodyTable">
- <tr>
- <th>Severity</th>
- <th>Description</th>
- <th>Class</th>
- <th>Method / Field</th>
- </tr>
- <tr>
- <td>Error</td>
- <td>The&nbsp;number&nbsp;of&nbsp;parameters&nbsp;of SubstituteLoggerFactory
- constructor has changed</td>
- <td>org.slf4j.helpers.SubstituteLoggerFactory</td>
- <td>public SubstituteLoggerFactory(java.util.List)</td>
- </tr>
- </table>
-
- <p>&nbsp;</p>
-
- <p>The <code>SubstituteLoggerFactory</code> class is used internally
- by the LoggerFactory class. Changes to the constructor of
- SubstituteLoggerFactory should have strictly no effect on users.
- </p>
-
- <h2><a href="#1_5_5" name="1_5_4">Version 1.5.5 compared to 1.5.4</a></h2>
-
- <p>No breaking changes to report.</p>
-
- <h2><a href="#1_5_4" name="1_5_4">Version 1.5.4 compared to 1.5.3</a></h2>
-
- <h3>slf4j-api module, list of breaking changes:</h3>
-
-
- <table class="bodyTable">
- <tr>
- <th>Severity</th>
- <th>Description</th>
- <th>Class</th>
- <th>Method / Field</th>
- </tr>
- <tr>
- <td>Error</td>
- <td>Method 'hasReferences()' has been added to an interface</td>
- <td>org.slf4j.Marker</td>
- <td>public boolean hasReferences()</td>
- </tr>
- <tr class="alt">
- <td>Info</td>
- <td>Method 'hasChildren()' was deprecated</td>
- <td>org.slf4j.Marker</td>
- <td>public boolean hasChildren()</td>
- </tr>
-
- </table>
-
- <p>&nbsp;</p>
-
- <p>The <code>hasChildren()</code> and other documentation in the
- Marker interface was misleading users to think in terms of parent
- child relationship for markers. However, as <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=100">bug 100</a>
- illustrates, associating markers as parents and children is not very
- helpful. It is much better to think of markers in terms of abstract
- graphs. As such, we now say that a marker contains (zero or more)
- <code>references</code> to other markers.
- </p>
-
- <p>This breaking change is justified because it corrects a
- conceptual error in the design. Previously, it was all too easy for
- developers to get confused and incorrectly link markers
- together.</p>
-
- <h2><a href="#1_5_3" name="1_5_3">Version 1.5.3 compared to 1.5.2</a></h2>
-
- <h3>slf4j-api module, list of breaking changes:</h3>
-
-
- <table class="bodyTable">
- <tr>
- <th>Severity</th>
- <th>Description</th>
- <th>Class</th>
- <th>Method / Field</th>
- </tr>
- <tr >
- <td>Error</td>
- <td>Added final modifier to class</td>
- <td>org.slf4j.helpers.MessageFormatter</td>
- <td></td>
- </tr>
- </table>
-
- <p>Declaring <code>MessageFormatter</code> class as final should not
- affect users, unless they extend this class. However, since this
- class is intended to be used internally, very few users should be
- affected.
- </p>
-
- <h2><a href="#1_5_2" name="1_5_2">Version 1.5.2 compared to 1.5.1</a></h2>
-
- <p>No breaking changes to report.</p>
-
- <h2><a href="#1_5_1" name="1_5_1">Version 1.5.1 compared to 1.5.0</a></h2>
-
-
- <h3>slf4j-api module, list of breaking changes:</h3>
-
-
- <table class="bodyTable">
- <tr>
- <th>Severity</th>
- <th>Description</th>
- <th>Class</th>
- <th>Method / Field</th>
- </tr>
- <tr >
- <td>Error</td>
- <td>Method 'getCopyOfContextMap()' has been added to an
- interface
- </td>
- <td>org.slf4j.spi.MDCAdapter</td>
- <td>public java.util.Map getCopyOfContextMap()</td>
- </tr>
- <tr class="alt">
- <td>Error</td>
- <td>Method 'setContextMap(Map)' has been added to an
- interface
- </td>
- <td>org.slf4j.spi.MDCAdapter</td>
- <td>public void setContextMap(java.util.Map)</td>
- </tr>
-
- <tr>
- <td>Error</td>
- <td>Method 'getDetachedMarker(String)' has been added to an
- interface
- </td>
- <td>org.slf4j.IMarkerFactory</td>
- <td>public org.slf4j.Marker getDetachedMarker(java.lang.String)</td>
- </tr>
-
- <tr class="alt">
- <td>Info</td>
- <td>Method 'equals(Object)' has been added to an
- interface
- </td>
- <td>org.slf4j.Marker</td>
- <td>public boolean equals(java.lang.Object)</td>
- </tr>
-
- <tr>
- <td>info</td>
- <td>Method 'hashCode()' has been added to an
- interface
- </td>
- <td>org.slf4j.Marker</td>
- <td>public int hashCode()</td>
- </tr>
-
- </table>
-
- <p>The addition of the <code>getCopyOfContextMap()</code> method in
- the <code>MDCAdapter</code> class should only impact users who have
- their own implementation of the said interface. Except for bindings
- that ship with SLF4J and for logback-classic, which will be
- naturally upgraded, there are no known other implementations of
- <code>MDCAdapter</code>. In a rare but still possible scenario, if
- the user mixes different versions for slf4j-api.jar, say version
- 1.5.1. and an SLF4J binding, say slf4j-log4j12.jar version 1.5.0,
- then a <code>java.lang.AbstractMethodError</code> will be thrown,
- but only if the client code calls the newly added method. <span
- style="color:green"> In short, although generally speaking the
- addition of a method to an interface is a breaking change, we are
- confident that no users will be impacted in this particular
- case.</span>
- </p>
-
- <p>Similar reasoning applies to the <code>setContextMap(Map)</code>
- method.</p>
-
- <p>The addition of <code>getDetachedMarker(String)</code> method in
- the <code>org.slf4j.IMarkerFactory</code> should not impact users as
- the only (known) implementation of this interface ships with SLF4J
- itself.
- </p>
-
- <p>The <code>equals()</code> and <code>hashCode()</code> methods
- were added to the <code>org.slf4j.Marker</code> interface for
- documentation purposes. Given that all objects implicitly implement
- these methods, their addition should theoretically not break
- existing code. </p>
-
-
- <h3>Other modules</h3>
-
- <p>No breaking changes to report.</p>
-
-
- <!-- ========================================= -->
- <h2><a href="#1_5_0" name="1_5_0">Version 1.5.0 compared to
- 1.4.3</a></h2>
-
- <p>No breaking changes to report.</p>
-
- <!-- ========================================= -->
- <h2><a href="#1_4_3" name="1_4_3">Version 1.4.3 compared to
- 1.4.2</a></h2>
- <p>No breaking changes to report.</p>
-
- <!-- ========================================= -->
- <h2><a href="#1_4_2" name="1_4_2">Version 1.4.2 compared to 1.4.1</a></h2>
- <p>No breaking changes to report.</p>
-
- <!-- ========================================= -->
- <h2><a href="#1_4_1" name="1_4_1">Version 1.4.1 compared to
- 1.4.0</a></h2>
- <p>No breaking changes to report.</p>
-
-</div> </body> </html> \ No newline at end of file
diff --git a/slf4j-site/src/site/pages/css/popup.css b/slf4j-site/src/site/pages/css/popup.css
deleted file mode 100644
index 2b20468e..00000000
--- a/slf4j-site/src/site/pages/css/popup.css
+++ /dev/null
@@ -1,67 +0,0 @@
-
-/* =========== popup ================== */
-#backgroundPopup {
- display:none;
- position:fixed;
- _position:absolute; /* hack for internet explorer 6*/
- height:100%;
- width:100%;
- top:0;
- left:0;
- background:#000000;
- border:1px solid #cecece;
- z-index:1;
-}
-
-#popupContents {
- display:none;
- position:fixed;
- _position:absolute; /* hack for internet explorer 6*/
- height: 150px;
- width: 408px;
- background:#FFFFFF;
- border: 2px solid #cecece;
- z-index:2;
- padding-left: 1ex;
- font-size:13px;
-}
-
-#popupContents p {
- margin: 0px;
-}
-#popupContents h3 {
- margin: 0px;
-}
-
-#popupContactClose {
- font-size:14px;
- line-height:14px;
- right:6px;
- top:4px;
- position:absolute;
- color:#6fa5fd;
- font-weight:700;
- display:block;
-}
-
-a.popupLink {
- background: #FFF;
- color: #0079C5;
- font-family: "Comic Sans MS", sans-serif;
- white-space: nowrap;
- font-size: 14px;
- font-weight: bold;
-
- border-top: 2px solid #DDD;
- border-left: 2px solid #DDD;
- border-right: 2px solid #888;
- border-bottom: 2px solid #888;
- padding: 0px 1em 0px 1em;
- margin: 0px 0px 3px 0px;
-}
-
-a.popupLink:hover {
- background: #E0E0EF;
- cursor: pointer;
-}
-
diff --git a/slf4j-site/src/site/pages/css/prettify.css b/slf4j-site/src/site/pages/css/prettify.css
deleted file mode 100644
index 290a86a4..00000000
--- a/slf4j-site/src/site/pages/css/prettify.css
+++ /dev/null
@@ -1,29 +0,0 @@
-.str{color:#080}
-.kwd{color:#008}
-.com{color:#800}
-.typ{color:#606}
-.lit{color:#066}
-.pun{color:#660}
-.pln{color:#000}
-.tag{color:#008}
-.atn{color:#606}
-.atv{color:#080}
-.dec{color:#606}
-
-pre.prettyprint{
- padding:2px;
- border-top: 1px solid #888; border-bottom: 1px solid #888;
-}
-@media print{.str{color:#060}
-
-.kwd{
- color:#006;font-weight:bold}
- .com{color:#600;font-style:italic
-}
-.typ{color:#404;font-weight:bold}
-.lit{color:#044}
-.pun{color:#440}
-.pln{color:#000}
-.tag{color:#006;font-weight:bold}
-.atn{color:#404}
-.atv{color:#060}} \ No newline at end of file
diff --git a/slf4j-site/src/site/pages/css/site.css b/slf4j-site/src/site/pages/css/site.css
deleted file mode 100755
index 5fd72a66..00000000
--- a/slf4j-site/src/site/pages/css/site.css
+++ /dev/null
@@ -1,449 +0,0 @@
-html {
- padding:0px;
- margin:0px;
-}
-
-body {
- background-color: #fff;
- font-family: Verdana, Arial, SunSans-Regular, Sans-Serif;
- color: #000;
- padding:0px;
- margin:0px;
- font-size: small;
-}
-
-#job img { border:1px solid #DDDDDD; }
-#job:hover img { border:1px solid #8888EE; }
-
-p, h2, pre {
- margin: 0px;
- padding-top: 5px;
- padding-bottom: 5px;
- /*padding-left: 1ex;*/
- /*padding: 5px 20px 5px 20px; */
-}
-
-p.rm {
- padding-top: 0px;
- padding-bottom: 0px;
-}
-
-a {
- color: #4183c4;
- /*font-size: smaller;*/
- background-color:transparent;
- text-decoration: none;
-}
-
-#content a:hover {
- text-decoration: underline;
-}
-
-.source {
- border-top: 1px solid #DDDDDD;
- border-bottom: 1px solid #DDDDDD;
- background:#f5f5f5;
- font-family: Courier, "MS Courier New", Prestige, Everson Monocourrier, monospace;
- padding-bottom: 0.5ex;
- padding-top: 0.5ex;
- padding-left: 1ex;
-
- margin-left: 0ex;
- margin-top: 0.5ex;
- margin-bottom: 0.5ex;
- white-space: pre;
-
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
- border-radius: 3px;
-}
-
-pre {
- background-color:transparent;
- font-family: Monaco, Andale Mono, Courier New, monospace;
-}
-
-.alignright {
- margin-top: 0;
- text-align: right;
- font-size: 10px;
-}
-
-h1, h2, h3, h4 {
- color: #333;
-}
-
-h2 {
- padding-top:10px;
- background-color: transparent;
- font-weight: 900;
- font-size: x-large;
-}
-
-h3 {
- padding-top: 5px;
- background-color: transparent;
- font-weight: normal;
- font-size: large;
-}
-
-h4 {
- padding-top:5px;
- background-color: transparent;
- font-weight: normal;
- font-size: large;
-}
-
-table.footer {
- width: 100%;
-}
-
-.footer {
- text-align: right;
- color: #564b47;
- background-color: #fff;
- padding:0px;
- border-top: 1px solid #CCCCCC;
- margin-top: 3ex;
- font-size: smaller;
-}
-
-
-strong {
- /*font-size: 13px;*/
- font-weight: bold;
-}
-
-/* positioning-layers static and absolute */
-
-#breadcrumbs {
- padding: 3px 10px 3px 10px;
- margin: 0px 4px 0px 4px;
- font-size: small;
- border: 1px solid #CCCCCC;
- /*border-bottom: 1px solid #aaa;
- /* background-color: #ccc; lime;
- border-color: #663300;*/
- background-color: #ffd0a0;
- /*max-width: 77em;*/
-}
-
-#left {
- position: absolute;
- left: 0px;
- width: 15em;
- margin: 4px 0px 0px 4px;
- padding: 0px;
- font-size: 80%;
- background-color: #ffffff;
-}
-
-.menuGroup {
- border: 1px solid #cccccc;
- background-color: #fff8e8;
- color: #564b47;
- border: 1px solid #cccccc;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
- border-radius: 3px;
-}
-
-.menuGroup a {
- display: block;
- width: 95.5%;
- margin: 0px;
- padding: 2px;
- border: solid 1px #fff8e8;
- color: #0066cc;
- text-decoration: none;
-}
-
-.menuGroup a:hover {
- border: solid 1px #FFFFFF;
- background-color: #3333CC;
- color: #ffffff;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
- border-radius: 3px;
-}
-
-.pub {
- text-align: center;
-}
-
-#left .pub a:hover {
- background-color: transparent;
- border: solid 0px #FFFFFF;
-}
-
-#left a:hover, #right a:hover {
- border: solid 1px #FFFFFF;
- background-color: #3333CC;
- color: #ffffff;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
- border-radius: 3px;
-}
-
-#left div.jobadd {
- font-size: 160%;
- color: #fff;
- margin: 0px;
- padding: 1ex;
-
- text-align: center;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
- border-radius: 3px;
-
- background-image: -ms-linear-gradient(bottom right, #FFBB55 0%, #FF8822 100%);
- background-image: -moz-linear-gradient(bottom right, #FFBB55 0%, #FF8822 100%);
- background-image: -o-linear-gradient(bottom right, #FFBB55 0%, #FF8822 100%);
- background-image: -webkit-gradient(linear, right bottom, left top, color-stop(0, #FFBB55), color-stop(1, #FF8822));
- background-image: -webkit-linear-gradient(bottom right, #FFBB55 0%, #FF8822 100%);
- background-image: linear-gradient(to top left, #FFBB55 0%, #FF8822 100%);
-}
-
-#left div.jobadd a, div.jobadd a:hover {
- background-color: transparent;
- color: #fff;
- border-width: 0px;
-}
-
-p.menu_header {
- margin: 0px;
- padding: 2px;
- font-weight: normal;
- background-color: #ffd0a0;
- border-top: solid 1px #CCCCCC;
- border-bottom: solid 1px #CCCCCC;
-}
-
-#content {
- margin: 0px 12em 0px 16em;
- padding: 0px;
- background-color: #ffffff;
-}
-
-
-#content img {
- border:none;
- margin-left: auto;
- margin-right: auto;
- display: block;
-}
-
-.author {
- text-align: left;
- font-weight: bold;
-}
-
-.definition {
- padding-left: 5px;
- padding-right: 5px;
- margin: 5px 50px 5px 50px;
- text-align: justify;
- background-color: #E6E64C;
-}
-
-.deftitle {
- font-weight: bold;
-}
-
-.big {
- font-size: 130%;
-}
-
-.green {
- color: green;
-}
-.blue {
- color: blue;
-}
-
-.red {
- color: red;
-}
-
-.bold {
- font-weight: bold;
-}
-
-.redBold {
- color: red;
- font-weight: bold;
-}
-.greenBold {
- color: green;
- font-weight: bold;
-}
-
-code {
- font-family: Courier, monospace;
-}
-
-
-.option {
- border: 1px solid black;
- font-family: Arial, sans-serif;
-}
-.highlight {
- width: 18em;
- float: right;
- display: inline;
- font-size: 110%;
-
- border: 2px solid #711;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- border-radius: 4px;
- background:#FFE0B0;
- padding-top: 1ex;
- padding-left: 1ex;
- padding-right: 1ex;
- padding-bottom: 1ex;
- margin-left: 1em;
- margin-right: 0em;
- margin-bottom: 1ex;
-}
-
-
-.survey {
- font-weight: bolder;
- font-size: larger;
-
- border:1px solid #cccccc;
- background:#FFCC99;
- padding-left: 1ex;
- padding-right: 1ex;
-}
-/* ========== body table ============ */
-table.bodyTable {
- padding: 0px;
- margin-left: -2px;
- margin-right: -2px;
-}
-
-table.bodyTable th {
- color: white;
- background-color: #bbb;
- font-weight: bold;
-}
-
-
-table.bodyTable td {
- padding-left: 0.5ex;
- padding-bottom: 0.5ex;
-}
-
-
-/* apply to tr elements of tables which are both bodytable and dark */
-table[class="bodyTable dark"] tr {
- background-color: #ddd;
-}
-
-/* apply to tr elements of tables which are both bodytable and dark */
-table[class="bodyTable properties"] tr {
- vertical-align: top;
-}
-
-table.bodyTable tr.a {
- background-color: #ddd;
-}
-
-table.bodyTable tr.b {
- background-color: #eee;
-}
-
-table.bodyTable tr.alt {
- background-color: #eee;
-}
-
-.striped tr:nth-child(odd) td {
- background-color: #f9f9f9;
-}
-.striped td {
- background-color: #f0f0f0;
-}
-
-/* EOF =============== bodyTable =============== */
-
-.label {
- padding: 1px 3px 2px;
- font-size: 9.75px;
- font-weight: bold;
- color: #ffffff;
- text-transform: uppercase;
- white-space: nowrap;
- background-color: #bfbfbf;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
- border-radius: 3px;
-}
-.label.notice {
- background-color: #62cffc;
-}
-
-
-/* ------------------------------------ */
-
-dt {
- border-top: 2px solid #888888;
- color: #333;
- padding-bottom: 1ex;
- padding-top: 1ex;
- font-weight: bold;
-}
-dd {
- margin-top: 1ex;
- margin-bottom: 1ex;
-}
-
-/* ------------------------------------ */
-.anchor { display:none; }
-
-h1 .anchor:before {content:url(anchor24.png);}
-h2 .anchor:before {content:url(anchor20.png);}
-h3 .anchor:before {content:url(anchor16.png);}
-h4 .anchor:before {content:url(anchor12.png);}
-td .anchor:before {content:url(anchor12.png);}
-dt .anchor:before {content:url(anchor12.png);}
-
-h1:hover .anchor { margin-left: -24px; }
-h2:hover .anchor { margin-left: -20px; }
-h3:hover .anchor { margin-left: -16px; }
-h4:hover .anchor { margin-left: -12px; }
-td:hover .anchor { margin-left: -12px; }
-dt:hover .anchor { margin-left: -12px; }
-
-h1:hover .anchor,
-h2:hover .anchor,
-h3:hover .anchor,
-h4:hover .anchor,
-td:hover .anchor,
-dt:hover .anchor {
- display: inline-block;
- text-decoration: none;
-}
-
-
-/* ------------ twitter button ------- */
-.twitter_button {
- vertical-align: text-bottom;
- padding-top: 3px;
- padding-right: 16px;
- float: left;
- height: 18px;div
- text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
- white-space: nowrap;
- background-color: white;
- background-image: -moz-linear-gradient(top, #ffffff, #dedede);
- background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#dedede));
- background-image: -ms-linear-gradient(top, #ffffff, #dedede);
- background-image: linear-gradient(top, #ffffff, #dedede);
- background-image: -o-linear-gradient(top, #ffffff, #dedede);
- border: #CCC solid 1px;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
- border-radius: 3px;
-}
diff --git a/slf4j-site/src/site/pages/docs.html b/slf4j-site/src/site/pages/docs.html
deleted file mode 100644
index 9788d788..00000000
--- a/slf4j-site/src/site/pages/docs.html
+++ /dev/null
@@ -1,153 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <title>SLF4J Documentation</title>
- <link rel="stylesheet" type="text/css" media="screen" href="css/site.css" />
- </head>
- <body>
- <script type="text/javascript">prefix='';</script>
-
- <script src="templates/header.js" type="text/javascript"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="templates/left.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>Documentation</h1>
-
- <p>Given the small size of SLF4J, its documentation is not very
- lengthy.</p>
-
- <ul>
- <li><a href="manual.html">User manual</a></li>
- <li><a href="faq.html">FAQ</a></li>
- <li><a href="codes.html">SLF4J error messages</a></li>
- <li><a href="legacy.html">Bridging legacy APIs</a></li>
- <li><a href="migrator.html">SLF4J Migrator</a></li>
- <li><a href="extensions.html">SLF4J extensions</a></li>
-
- <li><a href="localization.html">Localization/Internalization support</a></li>
-
- <li><a href="apidocs/index.html">javadocs</a></li>
- <li>
- <a href="xref/index.html">sources</a>,
- <a href="xref-test/index.html">test sources</a>
- </li>
- </ul>
-
-
- <h2>Videos</h2>
-
- <table>
- <tr>
- <td>
- <a href="http://www.youtube.com/watch?v=tMLEbGJ2z7I&hd=1;"><img style="align:left;" src="images/beginnerSLF4J.png"/></a>
- </td>
- </tr>
- </table>
-
- <h2>Articles, blogs &amp; presentations</h2>
-
- <ul>
-
- <li>
- <a
- href="http://jayunit100.blogspot.ch/2013/10/simplifying-distinction-between-sl4j.html">Simplifying
- the distinction between SL4J and commons logging</a>, by Jay
- Vyas
- </li>
-
- <li>
- <a
- href="http://runjva.appspot.com/logging101/index.html">Logging
- in Java with slf4j</a>, by Thorbj&oslash;rn Ravn Andersen
- </li>
-
- <li>
- <a href="http://eclipsezone.com/articles/franey-logging/?source=archives">Universal
- Logger Plug-ins for RCP Applications</a>, by John J. Franey
- </li>
-
-
- <li><a href="http://blog.frankel.ch/tech/dev/java/thoughts-on-java-logging-and-slf4j">Thoughts on Java logging and SLF4J</a> by Nicolas Frankel
- </li>
-
- <li><a href="http://glauche.de/2009/08/24/">Logging with SLF4J and
- Guice</a>, by Michael Glauche </li>
-
- <li>
- <a href="slf4j-in-10-slides.ppt">SLF4J in 10 slides</a>, by Ceki G&uuml;lc&uuml;
- </li>
-
- <li><a
- href="http://parleys.com/play/514892260364bc17fc56be83/chapter0/about">Devoxx-2009
- video presentation</a>, by Ceki G&#252;lc&#252; </li>
-
- <li>
- <a
- href="http://day-to-day-stuff.blogspot.com/2007/10/announcement-version-99-does-not-exist.html">
- Version 99 Does Not Exist</a>, by Erik van Oosten
- </li>
-
- <li>
- <a href="http://www.catosplace.net/blogs/personal/?p=442">JUnit
- 4 Test Logging Tips using SLF4J</a>, by Pete Sellars
- </li>
-
- <li>
- <a
- href="http://tapestryjava.blogspot.com/2007/08/so-long-commons-logging-hello-slf4j.html">So
- long, commons-logging, hello SLF4J</a>, by Howard Lewis Ship
- </li>
-
- <li>
- <a
- href="http://bsnyderblog.blogspot.com/2007/08/my-soapbox-for-slf4j.html">My
- Soapbox for SLF4J</a>, by Bruce Snyder
- </li>
-
- <li>
- <a
- href="http://blog.springsource.com/2009/12/04/logging-dependencies-in-spring/">Logging
- Dependencies in Spring </a> by Dave Syer
- </li>
-
- <li>
- <a href="http://baptiste-wicht.developpez.com/tutorials/java/slf4j/">Logging with SLF4J</a>
- by Baptiste Wicht
- </li>
-
- <li>
- <a href="http://javajing.com/2012/06/08/slf4j.html">Steps to use
- SLF4J</a> short (8 minute) video
- </li>
-
- </ul>
-
- <h4>In French</h4>
-
- <ul>
- <li><a
- href="http://www.insideit.fr/post/2009/11/23/SLF4J-LOGBack">SLF4J
- &amp; Logback : simplifiez-vous les logs</a> by Ludovic Meurillon
- </li>
-
- <li>
- <a
- href="http://baptiste-wicht.developpez.com/tutoriels/java/slf4j/">Journalisation avec SLF4J
- </a> by Baptiste Wicht
- </li>
-
- </ul>
-
-
- <script src="templates/footer.js" type="text/javascript"></script>
-
-
-</div>
-</body>
-</html>
diff --git a/slf4j-site/src/site/pages/download.html b/slf4j-site/src/site/pages/download.html
deleted file mode 100644
index f7b19307..00000000
--- a/slf4j-site/src/site/pages/download.html
+++ /dev/null
@@ -1,123 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <title>SLF4J Binary files</title>
- <link rel="stylesheet" type="text/css" media="screen" href="css/site.css" />
- <link rel="stylesheet" type="text/css" href="css/popup.css" media="screen" />
- </head>
- <body onload="">
- <script type="text/javascript">prefix='';</script>
-
- <script type="text/javascript" src="templates/header.js" ></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="templates/left.js" type="text/javascript"></script>
- </div>
-
- <div id="popupContents">
- <h3>Would you like to subscribe to the QOS.CH announcements mailing
- list?</h3>
-
-
- <p>The list is reserved for announcements related to QOS.CH
- projects such as cal10n, logback, mistletoe and SLF4J.</p>
- <br/>
- <table width="100%">
- <tr>
- <td><a class="popupLink" id="announce">Yes, I'd like to subscribe.</a></td>
- <td><a class="popupLink" id="popupContentsClose">No, thanks.</a></td>
- </tr>
- </table>
- </div>
- <div id="backgroundPopup"></div>
-
-
- <div id="content">
-
- <h2>Latest official SLF4J distribution</h2>
-
-
- <p>Download version ${project.version} including <i>full source code</i>,
- class files and documentation in ZIP or TAR.GZ format: </p>
-
- <ul>
- <li><a href="dist/slf4j-${project.version}.tar.gz"><b>slf4j-${project.version}.tar.gz</b></a> </li>
- <li><a href="dist/slf4j-${project.version}.zip"><b>slf4j-${project.version}.zip</b></a> </li>
- </ul>
-
-
- <h3>Previous versions</h3>
-
- <p>Previous versions of SLF4J can be downloaded from the <a
- href="dist/">main repository</a>.
- </p>
-
- <h3>javadoc downloads</h3>
-
- <p>For each slf4j module, the corresponding javadoc artifacts can be
- downloaded from the <a
- href="http://repo2.maven.org/maven2/org/slf4j/">Maven central
- repository</a> as <em>javadoc.jar</em> files.
- </p>
-
- <h2>Closely related projects</h2>
-
-
- <ul>
- <li><a
- href="http://projects.lidalia.org.uk/sysout-over-slf4j/">sysout-over-slf4j</a>
- module redirects all calls to System.out and System.err to an
- SLF4J defined logger with the name of the fully qualified class in
- which the System.out.println (or similar) call was made, at
- configurable levels. </li>
-
- <li><a href="http://projects.lidalia.org.uk/slf4j-test">SLF4J
- Test</a> is an SLF4J implementation focused on facilitating easier
- unit testing of logging code.
- </li>
-
- <li><a
- href="http://projects.lidalia.org.uk/lidalia-slf4j-ext/">Lidalia
- SLF4J Extensions</a> allows logging at a level determined at runtime
- rather than compile-time.
- </li>
- </ul>
-
- <h2>Additional SLF4J-related software</h2>
-
- <ul>
-
- <li><a href="http://code.google.com/p/jdbcdslog/">jdbcdslog</a> a
- tracing tool for JDBC, by Andriy Kolyadenko</li>
-
- <li><a href="http://www.jwaresoftware.org/wiki/log4ant/home">Log4Ant</a>, by JWare Software
- </li>
-
- <li><a href="http://code.google.com/p/log4jdbc/">log4jdbc</a>, a
- JDBC driver which logs SQL information before delegating to an
- underlying JDBC driver, by Arthur Blake
- </li>
-
- <li><a href="http://code.google.com/p/slf4fx/">SLF4Fx</a>, an open
- source logging suite for Flex, by Dmitry Motylev
- </li>
-
- <li><a
- href="http://svn.codehaus.org/sonar/trunk/sonar-web/src/main/webapp/WEB-INF/lib/slf4j_logger.rb">SLF4J
- logger for JRuby on Rails</a> and <a
- href="http://svn.codehaus.org/sonar/trunk/sonar-web/src/main/webapp/WEB-INF/config/environments/production.rb">settings
- file</a>, by SonarSource </li>
-
- </ul>
-
-
- </p>
-
-
- <script src="templates/footer.js" type="text/javascript"></script>
-</div>
-</body>
-</html>
diff --git a/slf4j-site/src/site/pages/extensions.html b/slf4j-site/src/site/pages/extensions.html
deleted file mode 100755
index d4695810..00000000
--- a/slf4j-site/src/site/pages/extensions.html
+++ /dev/null
@@ -1,886 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <title>SLF4J extensions</title>
-
- <link rel="stylesheet" type="text/css" media="screen" href="css/site.css" />
- <link rel="stylesheet" type="text/css" href="css/prettify.css" />
- </head>
- <body onload="prettyPrint()">
- <script type="text/javascript">prefix='';</script>
- <script type="text/javascript" src="js/prettify.js"></script>
- <script src="templates/header.js" type="text/javascript"></script>
- <div id="left">
- <script src="templates/left.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>SLF4J extensions</h1>
-
- <p>SLF4J extensions are packaged within <em>slf4j-ext.jar</em>
- which ships with SLF4J. </p>
-
-
- <ul>
- <li><a href="#profiler">Profiler</a></li>
- <li><a href="#extended_logger">Extended logger</a></li>
- <li><a href="#event_logger">Event Logging</a></li>
- <li><a href="#javaagent">Logging added with Java agent (requires Java 5)</a></li>
- </ul>
-
- <h2><a name="profiler"></a>Profilers</h2>
-
- <h3>What is a profiler?</h3>
-
- <p>According to wikipedia, <a
- href="http://en.wikipedia.org/wiki/Profiler_%28computer_science%29">profiling</a>
- is the investigation of a program's behavior using information
- gathered as the program runs, i.e. it is a form of dynamic program
- analysis, as opposed to static code analysis. The usual goal of
- performance analysis is to determine which parts of a program to
- optimize for speed or memory usage.
- </p>
-
- <p>SLF4J profilers, a.k.a. poor man's profilers, will help the
- developer gather performance data. Essentially, a profiler
- consists of one or more stopwatches. Stopwatches are driven
- (started/stopped) by statements in the <em>source code</em>. An
- example should make the point clearer.
- </p>
-
- <h3>Basic example</h3>
-
-
- <em>Example: Using the profiler: <a
- href="xref-test/org/slf4j/profiler/BasicProfilerDemo.html">BasicProfilerDemo</a></em>
-
- <pre class="prettyprint source">[omitted]
-32 public class BasicProfilerDemo {
-33
-34 public static void main(String[] args) {
-35 // create a profiler called "BASIC"
-36 <b>Profiler profiler = new Profiler("BASIC");</b>
-37 <b>profiler.start("A");</b>
-38 doA();
-39
-40 <b>profiler.start("B");</b>
-41 doB();
-42
-43 <b>profiler.start("OTHER");</b>
-44 doOther();
-45 <b>profiler.stop().print();</b>
-46 }
-[omitted]</pre>
-
-
- <p>Running the above example will output the following output.</p>
-
- <p class="source">+ Profiler [BASIC]
-|-- elapsed time [A] 220.487 milliseconds.
-|-- elapsed time [B] 2499.866 milliseconds.
-|-- elapsed time [OTHER] 3300.745 milliseconds.
-|-- Total [BASIC] 6022.568 milliseconds.</p>
-
- <p>Instantiating a profiler starts a global stopwatch. Each call to
- the start() method starts a new and named stopwatch. In addition to
- starting a named stopwatch, the start() method also causes the
- previous stopwatch to stop. Thus, the call to
- <code>profiler.start("A")</code> starts a stopwatch named "A". The
- subsequent call to <code>profiler.start("B")</code> starts
- stopwatch "B" and simultaneously stops the stopwatch named
- "A". Invoking the <code>stop()</code> on a profiler stops the last
- stopwatch as well as the global stopwatch which was started when
- the profiler was instantiated.
- </p>
-
-
- <h3>Profiler nesting</h3>
-
- <p>Profilers can also be nested. By nesting profilers, it is
- possible to measure a task which itself has subtasks that need to
- be timed and measured.
- </p>
-
- <p>Starting a nested profiler will stop any previously started
- stopwatch or nested profiler associated with the parent profiler.
- </p>
-
- <p>Often times, the subtask is implemented by a different class as
- the class hosting the parent profiler. Using the
- <code>ProfilerRegistry</code> is a convenient way of passing a
- nested profiler to an object outside the current object. Each
- thread has its own profiler registry which can be retrieved by
- invoking the <code>getThreadContextInstance()</code> method.
- </p>
-
- <em>Example: <a
- href="xref-test/org/slf4j/profiler/NestedProfilerDemo.html">NestedProfilerDemo</a>
- </em>
-
- <pre class="prettyprint source">33 public class NestedProfilerDemo {
-34
-35 public static void main(String[] args) {
-36 // create a profiler called "DEMO"
-37 Profiler profiler = new Profiler("DEMO");
-38
-39 // register this profiler in the thread context's profiler registry
-40 <b>ProfilerRegistry profilerRegistry = ProfilerRegistry.getThreadContextInstance();</b>
-41 <b>profiler.registerWith(profilerRegistry);</b>
-42
-43 // start a stopwatch called "RANDOM"
-44 profiler.start("RANDOM");
-45 RandomIntegerArrayGenerator riaGenerator = new RandomIntegerArrayGenerator();
-46 int n = 1000*1000;
-47 int[] randomArray = riaGenerator.generate(n);
-48
-49 // create and start a nested profiler called "SORT_AND_PRUNE"
-50 // By virtue of its parent-child relationship with the "DEMO"
-51 // profiler, and the previous registration of the parent profiler,
-52 // this nested profiler will be automatically registered
-53 // with the thread context's profiler registry
-54 <b>profiler.startNested(SortAndPruneComposites.NESTED_PROFILER_NAME);</b>
-55
-56 SortAndPruneComposites pruner = new SortAndPruneComposites(randomArray);
-57 pruner.sortAndPruneComposites();
-58
-59 // stop and print the "DEMO" printer
-60 profiler.stop().print();
-61 }
-62 }</pre>
-
- <p>Here is the relevant excerpt from the <a
- href="xref-test/org/slf4j/profiler/SortAndPruneComposites.html">SortAndPruneComposites</a>
- class.
- </p>
-
- <pre class="prettyprint source">[omitted]
-6 public class SortAndPruneComposites {
-7
-8 static String NESTED_PROFILER_NAME = "SORT_AND_PRUNE";
-9
-10 final int[] originalArray;
-11 final int originalArrayLength;
-12
-13 public SortAndPruneComposites(int[] randomArray) {
-14 this.originalArray = randomArray;
-15 this.originalArrayLength = randomArray.length;
-16
-17 }
-18
-19 public int[] sortAndPruneComposites() {
-20 // retrieve previously registered profiler named "SORT_AND_PRUNE"
-21 ProfilerRegistry profilerRegistry = ProfilerRegistry.getThreadContextInstance();
-22 <b>Profiler sortProfiler = profilerRegistry.get(NESTED_PROFILER_NAME);</b>
-23
-24 // start a new stopwatch called SORT
-25 sortProfiler.start("SORT");
-26 int[] sortedArray = sort();
-27 // start a new stopwatch called PRUNE_COMPOSITES
-28 sortProfiler.start("PRUNE_COMPOSITES");
-29 int result[] = pruneComposites(sortedArray);
-30
-31 return result;
-32 }
-[omitted] </pre>
-
-
- <p>On a Dual-Core Intel CPU clocked at 3.2 GHz, running the
- <code>ProfilerDemo</code> application yields the following output:</p>
-
- <p class="source">+ Profiler [DEMO]
-|-- elapsed time [RANDOM] 70.524 milliseconds.
-|---+ Profiler [SORT_AND_PRUNE]
- |-- elapsed time [SORT] 665.281 milliseconds.
- |-- elapsed time [PRUNE_COMPOSITES] 5695.515 milliseconds.
- |-- Subtotal [SORT_AND_PRUNE] 6360.866 milliseconds.
-|-- elapsed time [SORT_AND_PRUNE] 6360.866 milliseconds.
-|-- Total [DEMO] 6433.922 milliseconds.</p>
-
- <p>From the above, we learn that generating 1'000'000 random
- integers takes 70 ms, sorting them 665 ms, and pruning the composite
- (non-prime) integers 5695 ms, for a grand total of 6433 ms. Given
- that pruning composites takes most of the CPU effort, any future
- optimizations efforts would be directed at the pruning part.
- </p>
-
- <p>With just a few well-placed profiler calls we were able to
- identify hot-spots in our application. Also note that passing a
- profiler to a target class could be achieved by registering it in a
- profiler registry and then retrieving it in the target class.
- </p>
-
- <h3>Printing using a logger</h3>
-
- <p> Invoking <code>profiler.print</code> will always print the
- output on the console. If you wish to leave the profiler code in
- production, then you probably need more control over the output
- destination. This can be accomplished by associating a logger of
- your choice with a profiler.
- </p>
-
- <p>After you have associated a logger with a profiler, you would
- invoke the <code>log()</code> method instead of <code>print()</code>
- previously, as the next example illustrates.
- </p>
-
- <em>Profiler with a logger: <a
- href="xref-test/org/slf4j/profiler/NestedProfilerDemo2.html">NestedProfilerDemo2</a>
- </em>
-
- <pre class="prettyprint source">[omitted]
-17 public class NestedProfilerDemo2 {
-18
-19 static Logger logger = LoggerFactory.getLogger(NestedProfilerDemo2.class);
-20
-21 public static void main(String[] args) {
-22 Profiler profiler = new Profiler("DEMO");
-23 // associate a logger with the profiler
-24 <b>profiler.setLogger(logger);</b>
-25
-26 ProfilerRegistry profilerRegistry = ProfilerRegistry.getThreadContextInstance();
-27 profiler.registerWith(profilerRegistry);
-28
-29 profiler.start("RANDOM");
-30 RandomIntegerArrayGenerator riaGenerator = new RandomIntegerArrayGenerator();
-31 int n = 10*1000;
-32 int[] randomArray = riaGenerator.generate(n);
-33
-34 profiler.startNested(SortAndPruneComposites.NESTED_PROFILER_NAME);
-35
-36 SortAndPruneComposites pruner = new SortAndPruneComposites(randomArray);
-37 pruner.sortAndPruneComposites();
-38
-39 // stop and log
-40 profiler.stop().<b>log()</b>;
-41 }
-42 } </pre>
-
- <p>The output generated by this example will depend on the logging
- environment, but should be very similar to the output generated by
- the previous <code>NestedProfilerDemo</code> example.
- </p>
-
- <p>The log() method logs at level DEBUG using a marker named
- "PROFILER".</p>
-
- <p>If your logging system supports markers, e.g. logback, you could
- specifically enable or disable output generated by SLF4J
- profilers. Here is logback configuration file disabling output for
- any logging event bearing the "PROFILER" marker, even if the logger
- used by the profiler is enabled for the debug level.
- </p>
-
-
- <em>logback configuration disabling logging from profilers, and only
- profilers</em>
-
- <pre class="prettyprint source">&lt;configuration>
-
- <b>&lt;turboFilter class="ch.qos.logback.classic.turbo.MarkerFilter">
- &lt;Marker>PROFILER&lt;/Marker>
- &lt;OnMatch>DENY&lt;/OnMatch>
- &lt;/turboFilter></b>
-
- &lt;appender name="STDOUT"
- class="ch.qos.logback.core.ConsoleAppender">
- &lt;layout class="ch.qos.logback.classic.PatternLayout">
- &lt;Pattern>%-5level %logger{36} - %msg%n&lt;/Pattern>
- &lt;/layout>
- &lt;/appender>
-
- &lt;root>
- &lt;level value="DEBUG" />
- &lt;appender-ref ref="STDOUT" />
- &lt;/root>
-&lt;/configuration> </pre>
-
-
-<!-- .............................................................. -->
-
- <h2><a name="mdcStrLookup"></a>MDCStrLookup</h2>
-
- <p>StrLookup is a class defined in Apache Commons Lang. It is used
- in conjunction with the StrSubstitutor class to allow Strings to
- have tokens in the Strings dynamically replaced at run time. There
- are many cases where it is desirable to merge the values for keys
- in the SLF4J MDC into Strings. MDCStrLookup makes this possible.
- </p>
- <p>
- Apache Commons Configuration provides a ConfigurationInterpolator
- class. This class allows new StrLookups to be registered and the
- values can then be used to merge with both the configuration of
- Commons Configuration as well as the configuration files it manages.
- </p>
- <p>
- StrLookup obviously has a dependency on Commons Lang. The Maven
- pom.xml for slf4j-ext lists this dependency as optional so
- that those wishing to use other extensions are not required to
- unnecessarily package the commons lang jar. Therefore, when using
- MDCStrLookup the dependency for commons-lang must be explicitly
- declared along with slf4j-ext.
- </p>
-
-<!-- .............................................................. -->
-
- <h2><a name="extended_logger"></a>Extended Logger</h2>
-
- <p>The <a
- href="apidocs/org/slf4j/ext/XLogger.html"><code>XLogger</code></a>
- class provides a few extra logging methods that are quite useful
- for following the execution path of applications. These methods
- generate logging events that can be filtered separately from other
- debug logging. Liberal use of these methods is encouraged as the
- output has been found to
- </p>
-
- <ul>
- <li>aid in problem diagnosis in development without requiring a
- debug session</li>
-
- <li>aid in problem diagnosis in production where no debugging is
- possible</li>
-
- <li>help educate new developers in learning the application.</li>
- </ul>
-
-
- <p>The two most used methods are the <code>entry()</code> and
- <code>exit()</code> methods. <code>entry()</code> should be placed
- at the beginning of methods, except perhaps for simple getters and
- setters. <code>entry()</code> can be called passing from 0 to 4
- parameters. Typically these will be parameters passed to the
- method. The <code>entry()</code> method logs with a level of TRACE
- and uses a <code>Marker</code> with a name of "ENTER" which is also
- a "FLOW" Marker.
- </p>
-
- <p>The <code>exit()</code> method should be placed before any
- return statement or as the last statement of methods without a
- return. <code>exit()</code> can be called with or without a
- parameter. Typically, methods that return void will use
- <code>exit()</code> while methods that return an Object will use
- exit(Object obj). The <code>entry()</code> method logs with a
- level of TRACE and uses a Marker with a name of "EXIT" which is
- also a "FLOW" Marker.
- </p>
-
- <p>The throwing() method can be used by an application when it is
- throwing an exception that is unlikely to be handled, such as a
- RuntimeException. This will insure that proper diagnostics are
- available if needed. The logging event generated will have a level
- of ERROR and will have an associated Marker with a name of
- "THROWING" which is also an "EXCEPTION" Marker.
- </p>
-
- <p>The catching() method can be used by an application when it
- catches an Exception that it is not going to rethrow, either
- explicitly or attached to another Exception. The logging event
- generated will have a level of ERROR and will have an associated
- Marker with a name of "CATCHING" which is also an "EXCEPTION"
- Marker.
- </p>
-
- <p>By using these extended methods applications that standardize on
- SLF4J can be assured that they will be able to perform diagnostic
- logging in a standardized manner.
- </p>
-
- <p>Note that XLogger instances are obtained to through the
- <a
- href="apidocs/org/slf4j/ext/XLoggerFactory.html"><code>XLoggerFactory</code></a>
- utility class.</p>
-
- <p>The following example shows a simple application using these
- methods in a fairly typical manner. The <code>throwing()</code>
- method is not present since no Exceptions are explicitly thrown and
- not handled.
- </p>
-
- <pre class="prettyprint source">package com.test;
-
-import org.slf4j.ext.XLogger;
-import org.slf4j.ext.XLoggerFactory;
-
-import java.util.Random;
-
-public class TestService {
- private XLogger logger = XLoggerFactory.getXLogger(TestService.class
- .getName());
-
- private String[] messages = new String[] { "Hello, World",
- "Goodbye Cruel World", "You had me at hello" };
-
- private Random rand = new Random(1);
-
- public String retrieveMessage() {
- logger.entry();
-
- String testMsg = getMessage(getKey());
-
- logger.exit(testMsg);
- return testMsg;
- }
-
- public void exampleException() {
- logger.entry();
- try {
- String msg = messages[messages.length];
- logger.error("An exception should have been thrown");
- } catch (Exception ex) {
- logger.catching(ex);
- }
- logger.exit();
- }
-
- public String getMessage(int key) {
- logger.entry(key);
-
- String value = messages[key];
-
- logger.exit(value);
- return value;
- }
-
- private int getKey() {
- logger.entry();
- int key = rand.nextInt(messages.length);
- logger.exit(key);
- return key;
- }
-}</pre>
-
- <p>This test application uses the preceding service to generate
- logging events.
- </p>
-
- <pre class="prettyprint source">package com.test;
-
-public class App {
- public static void main( String[] args ) {
- TestService service = new TestService();
- service.retrieveMessage();
- service.retrieveMessage();
- service.exampleException();
- }
-} </pre>
-
- <p>The configuration below will cause all output to be routed to
- target/test.log. The pattern for the FileAppender includes the
- class name, line number and method name. Including these in the
- pattern are critical for the log to be of value.
- </p>
-
- <pre class="prettyprint source">&lt;?xml version='1.0' encoding='UTF-8'?>
-&lt;configuration&gt;
- &lt;appender name="console" class="ch.qos.logback.core.ConsoleAppender"&gt;
- &lt;filter class="ch.qos.logback.classic.filter.LevelFilter"&gt;
- &lt;level&gt;ERROR&lt;/level&gt;
- &lt;onMatch&gt;ACCEPT&lt;/onMatch&gt;
- &lt;onMismatch&gt;DENY&lt;/onMismatch&gt;
- &lt;/filter&gt;
- &lt;layout class="ch.qos.logback.classic.PatternLayout"&gt;
- &lt;Pattern&gt;%d{HH:mm:ss.SSS} %-5level %class{36}:%L %M - %msg%n&lt;/Pattern&gt;
- &lt;/layout&gt;
- &lt;/appender&gt;
- &lt;appender name="log" class="ch.qos.logback.core.FileAppender"&gt;
- &lt;File&gt;target/test.log&lt;/File&gt;
- &lt;Append&gt;false&lt;/Append&gt;
- &lt;layout class="ch.qos.logback.classic.PatternLayout"&gt;
- &lt;Pattern&gt;%d{HH:mm:ss.SSS} %-5level %class{36}:%L %M - %msg%n&lt;/Pattern&gt;
- &lt;/layout&gt;
- &lt;/appender&gt;
-
- &lt;root&gt;
- &lt;level value="trace" /&gt;
- &lt;appender-ref ref="log" /&gt;
- &lt;/root&gt;
-&lt;/configuration&gt;
-</pre>
- <p>
- Here is the output that results from the Java classes and configuration above.
- </p>
-<p class="source">00:07:57.725 TRACE com.test.TestService:22 retrieveMessage - entry
-00:07:57.738 TRACE com.test.TestService:57 getKey - entry
-00:07:57.739 TRACE com.test.TestService:59 getKey - exit with (0)
-00:07:57.741 TRACE com.test.TestService:47 getMessage - entry with (0)
-00:07:57.741 TRACE com.test.TestService:51 getMessage - exit with (Hello, World)
-00:07:57.742 TRACE com.test.TestService:26 retrieveMessage - exit with (Hello, World)
-00:07:57.742 TRACE com.test.TestService:22 retrieveMessage - entry
-00:07:57.742 TRACE com.test.TestService:57 getKey - entry
-00:07:57.743 TRACE com.test.TestService:59 getKey - exit with (1)
-00:07:57.745 TRACE com.test.TestService:47 getMessage - entry with (1)
-00:07:57.745 TRACE com.test.TestService:51 getMessage - exit with (Goodbye Cruel World)
-00:07:57.746 TRACE com.test.TestService:26 retrieveMessage - exit with (Goodbye Cruel World)
-00:07:57.746 TRACE com.test.TestService:32 exampleException - entry
-00:07:57.750 ERROR com.test.TestService:40 exampleException - catching
-java.lang.ArrayIndexOutOfBoundsException: 3
- at com.test.TestService.exampleException(TestService.java:35)
- at com.test.AppTest.testApp(AppTest.java:39)
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
- at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
- at java.lang.reflect.Method.invoke(Method.java:585)
- at junit.framework.TestCase.runTest(TestCase.java:154)
- at junit.framework.TestCase.runBare(TestCase.java:127)
- at junit.framework.TestResult$1.protect(TestResult.java:106)
- at junit.framework.TestResult.runProtected(TestResult.java:124)
- at junit.framework.TestResult.run(TestResult.java:109)
- at junit.framework.TestCase.run(TestCase.java:118)
- at junit.framework.TestSuite.runTest(TestSuite.java:208)
- at junit.framework.TestSuite.run(TestSuite.java:203)
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
- at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
- at java.lang.reflect.Method.invoke(Method.java:585)
- at org.apache.maven.surefire.junit.JUnitTestSet.execute(JUnitTestSet.java:213)
- at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
- at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)
- at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
- at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
- at java.lang.reflect.Method.invoke(Method.java:585)
- at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:338)
- at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:997)
-00:07:57.750 TRACE com.test.TestService:42 exampleException - exit</p>
-
- <p>Simply changing the root logger level to DEBUG in the example
- above will reduce the output considerably.
- </p>
- <p class="source">00:28:06.004 ERROR com.test.TestService:40 exampleException - catching
-java.lang.ArrayIndexOutOfBoundsException: 3
- at com.test.TestService.exampleException(TestService.java:35)
- at com.test.AppTest.testApp(AppTest.java:39)
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
- at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
- at java.lang.reflect.Method.invoke(Method.java:585)
- at junit.framework.TestCase.runTest(TestCase.java:154)
- at junit.framework.TestCase.runBare(TestCase.java:127)
- at junit.framework.TestResult$1.protect(TestResult.java:106)
- at junit.framework.TestResult.runProtected(TestResult.java:124)
- at junit.framework.TestResult.run(TestResult.java:109)
- at junit.framework.TestCase.run(TestCase.java:118)
- at junit.framework.TestSuite.runTest(TestSuite.java:208)
- at junit.framework.TestSuite.run(TestSuite.java:203)
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
- at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
- at java.lang.reflect.Method.invoke(Method.java:585)
- at org.apache.maven.surefire.junit.JUnitTestSet.execute(JUnitTestSet.java:213)
- at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
- at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)
- at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
- at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
- at java.lang.reflect.Method.invoke(Method.java:585)
- at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:338)
- at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:997) </p>
-
- <!-- .............................................................. -->
-
- <h2><a name="event_logger"></a>Event Logging</h2>
-
- <p>The EventLogger class provides a simple mechanism for logging events that occur in an application.
- While the EventLogger is useful as a way of initiating events that should be processed by an audit
- Logging system, it does not implement any of the features an audit logging system would require
- such as guaranteed delivery.</p>
-
- <p>The recommended way of using the EventLogger in a typical web application is to populate
- the SLF4J MDC with data that is related to the entire lifespan of the request such as the user's id,
- the user's ip address, the product name, etc. This can easily be done in a servlet filter where
- the MDC can also be cleared at the end of the request. When an event that needs to be recorded
- occurs an EventData object should be created and populated. Then call EventLogger.logEvent(data)
- where data is a reference to the EventData object.</p>
-
- <pre class="prettyprint source">import org.slf4j.MDC;
-import org.apache.commons.lang.time.DateUtils;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.FilterChain;
-import javax.servlet.http.HttpSession;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.TimeZone;
-
-public class RequestFilter implements Filter
-{
- private FilterConfig filterConfig;
- private static String TZ_NAME = "timezoneOffset";
-
- public void init(FilterConfig filterConfig) throws ServletException {
- this.filterConfig = filterConfig;
- }
-
- /**
- * Sample filter that populates the MDC on every request.
- */
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
- FilterChain filterChain) throws IOException, ServletException {
- HttpServletRequest request = (HttpServletRequest)servletRequest;
- HttpServletResponse response = (HttpServletResponse)servletResponse;
- MDC.put("ipAddress", request.getRemoteAddr());
- HttpSession session = request.getSession(false);
- TimeZone timeZone = null;
- if (session != null) {
- // Something should set this after authentication completes
- String loginId = (String)session.getAttribute("LoginId");
- if (loginId != null) {
- MDC.put("loginId", loginId);
- }
- // This assumes there is some javascript on the user's page to create the cookie.
- if (session.getAttribute(TZ_NAME) == null) {
- if (request.getCookies() != null) {
- for (Cookie cookie : request.getCookies()) {
- if (TZ_NAME.equals(cookie.getName())) {
- int tzOffsetMinutes = Integer.parseInt(cookie.getValue());
- timeZone = TimeZone.getTimeZone("GMT");
- timeZone.setRawOffset((int)(tzOffsetMinutes * DateUtils.MILLIS_PER_MINUTE));
- request.getSession().setAttribute(TZ_NAME, tzOffsetMinutes);
- cookie.setMaxAge(0);
- response.addCookie(cookie);
- }
- }
- }
- }
- }
- MDC.put("hostname", servletRequest.getServerName());
- MDC.put("productName", filterConfig.getInitParameter("ProductName"));
- MDC.put("locale", servletRequest.getLocale().getDisplayName());
- if (timeZone == null) {
- timeZone = TimeZone.getDefault();
- }
- MDC.put("timezone", timeZone.getDisplayName());
- filterChain.doFilter(servletRequest, servletResponse);
- MDC.clear();
- }
-
- public void destroy() {
- }
-} </pre>
-
- <p>Sample class that uses EventLogger.</p>
- <pre class="prettyprint source">import org.slf4j.ext.EventData;
-import org.slf4j.ext.EventLogger;
-
-import java.util.Date;
-import java.util.UUID;
-
-public class MyApp {
-
- public String doFundsTransfer(Account toAccount, Account fromAccount, long amount) {
- toAccount.deposit(amount);
- fromAccount.withdraw(amount);
- EventData data = new EventData();
- data.setEventDateTime(new Date());
- data.setEventType("transfer");
- String confirm = UUID.randomUUID().toString();
- data.setEventId(confirm);
- data.put("toAccount", toAccount);
- data.put("fromAccount", fromAccount);
- data.put("amount", amount);
- EventLogger.logEvent(data);
- return confirm;
- }
-} </pre>
-
- <p>The EventLogger class uses a Logger named "EventLogger". EventLogger uses a logging level
- of INFO. The following shows a configuration using Logback.</p>
- <pre class="prettyprint source">&lt;configuration&gt;
- &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"&gt;
- &lt;layout class="ch.qos.logback.classic.PatternLayout"&gt;
- &lt;Pattern&gt;%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n&lt;/Pattern&gt;
- &lt;/layout&gt;
- &lt;/appender&gt;
-
- &lt;appender name="events" class="ch.qos.logback.core.ConsoleAppender"&gt;
- &lt;layout class="ch.qos.logback.classic.PatternLayout"&gt;
- &lt;Pattern&gt;%d{HH:mm:ss.SSS} %X - %msg%n&lt;/Pattern&gt;
- &lt;/layout&gt;
- &lt;/appender&gt;
-
- &lt;logger name="EventLogger" additivity="false"&gt;
- &lt;level value="INFO"/&gt;
- &lt;appender appender-ref="events"/&gt;
- &lt;/logger&gt;
-
- &lt;root level="DEBUG"&gt;
- &lt;appender-ref ref="STDOUT" /&gt;
- &lt;/root&gt;
-
-&lt;/configuration&gt; </pre>
-
- <!-- .............................................................. -->
-
- <h2><a name="javaagent"></a>Adding logging with Java agent</h2>
-
- <p><b>NOTE: BETA RELEASE, NOT PRODUCTION QUALITY</b> </p>
-
- <p>Quickstart for the impatient:</p>
-
- <ol>
- <li>Use Java 5 or later.</li>
- <li>Download slf4j-ext-${project.version}.jar and javassist.jar, and put them
- both in the same directory.</li>
- <li>Ensure your application is properly configured with
- slf4j-api-${project.version}.jar and a suitable backend.</li>
-
- <li>Instead of "java ..." use "java --javaagent:PATH/slf4j-ext-${project.version}.jar=time,verbose,level=info ..."
- <br/>
- (replace PATH with the path to the jar)
- </li>
- <li>That's it!</li>
- </ol>
-
- <p>In some applications logging is used to trace the actual
- execution of the application as opposed to log an occasional event.
- One approach is using the <a href="#extended_logger">extended
- logger</a> to add statements as appropriately, but another is to use
- a tool which modifies compiled bytecode to add these statements!
- Many exist, and the one included in slf4j-ext is not intended to
- compete with these, but merely provide a quick way to get very basic
- trace information from a given application.
- </p>
-
- <p>Java 5 added the Java Instrumentation mechanism, which allows you
- to provide "Java agents" that can inspect and modify the byte code
- of the classes as they are loaded. This allows the original class
- files to remain unchanged, and the transformations done on the byte
- codes depend on the needs at launch time.
- </p>
-
- <p>Given the well-known "Hello World" example:</p>
-
- <pre class="prettyprint source">public class HelloWorld {
- public static void main(String args[]) {
- System.out.println("Hello World");
- }
-}</pre>
-
- <p>a typical transformation would be similar to: (imports omitted)</p>
-
- <pre class="prettyprint source">public class LoggingHelloWorld {
- final static Logger _log = LoggerFactory.getLogger(LoggingHelloWorld.class.getName());
-
- public static void main(String args[]) {
- if (_log.isInfoEnabled()) {
- _log.info("> main(args=" + Arrays.asList(args) + ")");
- }
- System.out.println("Hello World");
- if (_log.isInfoEnabled()) {
- _log.info("&lt; main()");
- }
- }
-}</pre>
-
- <p>which in turn produces the following result when run similar to
- "java LoggingHelloWorld 1 2 3 4":
- </p>
-
- <p class="source">1 [main] INFO LoggingHelloWorld - > main(args=[1, 2, 3, 4])
-Hello World
-1 [main] INFO LoggingHelloWorld - &lt; main()</p>
-
- <p>The same effect could have been had by using this command (with
- the relative path to javassist.jar and
- slf4j-ext-${project.version}.jar being ../jars):</p>
-
- <p class="source">java -javaagent:../jars/slf4j-ext-${project.version}.jar HelloWorld 1 2 3 4</p>
-
- <p></p>
-
-
- <h3>How to use</h3>
- <p>The javaagent may take one or more options separated by comma. The following options
- are currently supported:</p>
-
- <dl>
- <dt><b>level</b>=X</dt>
- <dd>The log level to use for the generated log statements. X is
- one of "info", "debug" or "trace". Default is "info".</dd>
-
- <dt><b>time</b></dt>
- <dd>Print out the current date at program start, and again when
- the program ends plus the execution time in milliseconds.</dd>
-
- <dt><b>verbose</b></dt>
- <dd>Print out when a class is processed as part of being loaded</dd>
-
- <dt><b>ignore</b>=X:Y:...</dt>
- <dd>(Advanced) Provide full list of colon separated prefixes of
- class names NOT to add logging to. The default list is
- "org/slf4j/:ch/qos/logback/:org/apache/log4j/". This does not override the fact that a class must be able to access the
- slf4j-api classes in order to do logging, so if these classes are not visible to a given class it is not instrumented.
- </dd>
- </dl>
-
-
- <p>Some classes may misbehave when being rendered with "object.toString()" so they may be explicitly disabled
- in the logback configuration file permanently. For instance the ToStringBuilder in the Apache Jakarta commons lang
- package is a prime candidate for this. For logback add this snippet to logback.xml:
- <pre>&lt;logger name="org.apache.commons.lang.builder" level="OFF" /&gt;</pre>
- </p>
-
-
-
- <p>Note: These are not finalized yet, and may change.</p>
-
- <h3>Locations of jar files</h3>
-
- <p>The javassist library is used for the actual byte code
- manipulation and must be available to be able to add any logging
- statements. slf4j-ext-${project.version} has been configured to
- look for the following:
- </p>
-
- <ul>
- <li>"javassist-3.4.GA.jar" relatively to
- slf4j-ext-${project.version}.jar as would be if Maven had downloaded
- both from the repository and slf4j-ext-${project.version}.jar was
- referenced directly in the Maven repository in the
- "-javaagent"-argument.</li>
- <li>"javassist-3.4.GA.jar" in the same directory as slf4j-ext</li>
- <li>"javassist.jar" in the same directory as slf4j-ext</li>
- </ul>
-
- <p>A warning message is printed if the javassist library was not
- found by the agent, and options requiring byte code transformations will not work.
- </p>
-
-
- <h3>Misc notes</h3>
-
- <ul>
- <li>A java agent is not invoked on any classes already loaded by the
- class loader.</li>
- <li>Exceptions in the java agent that would normally have been
- printed, may be silently swallowed by the JVM.</li>
- <li>The javaagent only logs to System.err.</li>
- <li>The name of the logger variable is fixed (to a value unlikely to be used) so if that
- name is already used, a failure occurs. This should be changed to determine
- an unused name and use that instead.</li>
- <li>Empty methods are not instrumented (an incorrect check for an interface). They should be</li>
-
- </ul>
-
- <p>(The agent is an adaption of the java.util.logging version
- described in <a
- href="http://today.java.net/pub/a/today/2008/04/24/add-logging-at-class-load-time-with-instrumentation.html"
- >http://today.java.net/pub/a/today/2008/04/24/add-logging-at-class-load-time-with-instrumentation.html</a>)
- </p>
-
- <script src="templates/footer.js" type="text/javascript"></script>
-</div>
-</body>
-</html>
-
diff --git a/slf4j-site/src/site/pages/faq.html b/slf4j-site/src/site/pages/faq.html
deleted file mode 100755
index 1767e2b2..00000000
--- a/slf4j-site/src/site/pages/faq.html
+++ /dev/null
@@ -1,1615 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-
- <head>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <title>SLF4J FAQ</title>
- <link rel="stylesheet" type="text/css" media="screen" href="css/site.css" />
- <link rel="stylesheet" type="text/css" href="css/prettify.css" />
- </head>
- <body onload="prettyPrint(); decorate();">
-
- <script type="text/javascript" src="js/prettify.js"></script>
- <script type="text/javascript">prefix='';</script>
-
- <script type="text/javascript" src="templates/header.js"></script>
- <script type="text/javascript" src="js/jquery-min.js"></script>
- <script type="text/javascript" src="js/decorator.js"></script>
-
- <div id="left">
- <script src="templates/left.js" type="text/javascript"></script>
- </div>
-
- <div id="content">
-
- <h2><a name="top">Frequently Asked Questions about SLF4J</a></h2>
-
- <p><b>Generalities</b></p>
-
- <ol type="1">
- <li><a href="#what_is">What is SLF4J?</a></li>
-
- <li><a href="#when">When should SLF4J be used?</a></li>
-
- <li><a href="#yet_another_facade"> Is SLF4J yet another loggingfacade?</a></li>
-
- <li><a href="#why_new_project"> If SLF4J fixes JCL, then why
- wasn't the fix made in JCL instead of creating a new project?
- </a>
- </li>
-
- <li><a href="#need_to_recompile"> When using SLF4J, do I have to
- recompile my application to switch to a different logging
- system?
- </a>
- </li>
-
- <li><a href="#requirements">What are SLF4J's requirements?</a></li>
-
- <li><a href="#compatibility">Are SLF4J versions backward
- compatible?</a></li>
-
- <li><a href="#IllegalAccessError">I am getting
- <code>IllegalAccessError</code> exceptions when using SLF4J. Why
- is that?</a></li>
-
-
- <li>
- <a href="#license">Why is SLF4J licensed under X11 type
- license instead of the Apache Software License?
- </a>
- </li>
-
- <li>
- <a href="#where_is_binding">Where can I get a particular
- SLF4J binding?
- </a>
- </li>
-
- <li>
- <a href="#configure_logging">Should my library attempt to
- configure logging?
- </a>
- </li>
-
- <li>
- <a href="#optional_dependency">In order to reduce the number of
- dependencies of our software we would like to make SLF4J an
- optional dependency. Is that a good idea?
- </a>
- </li>
-
- <li>
- <a href="#maven2">What about Maven transitive
- dependencies?
- </a>
- </li>
-
- <li>
- <a href="#excludingJCL">How do I exclude commons-logging as a
- Maven dependency?
- </a>
- </li>
- </ol>
-
-
- <b>About the SLF4J API</b>
-
- <ol type="1">
-
- <li>
- <a href="#string_or_object"> Why don't the printing methods
- in the Logger interface accept message of type Object, but only
- messages of type String?
- </a>
- </li>
-
- <li>
- <a href="#exception_message">
- Can I log an exception without an accompanying message?
- </a>
- </li>
-
-
- <li>
- <a href="#logging_performance"> What is the fastest way of
- (not) logging?
- </a>
- </li>
-
- <li>
- <a href="#string_contents"> How can I log the string contents
- of a single (possibly complex) object?
- </a>
- </li>
-
-
- <li><a href="#fatal"> Why doesn't the
- <code>org.slf4j.Logger</code> interface have methods for the
- FATAL level? </a></li>
-
- <li><a href="#trace">Why was the TRACE level introduced only in
- SLF4J version 1.4.0? </a></li>
-
- <li><a href="#i18n">Does the SLF4J logging API support I18N
- (internationalization)? </a></li>
-
-
- <li><a href="#noLoggerFactory">Is it possible to retrieve loggers
- without going through the static methods in
- <code>LoggerFactory</code>? </a></li>
-
- <li><a href="#paramException">In the presence of an
- exception/throwable, is it possible to parameterize a logging
- statement?</a></li>
-
- </ol>
-
-
-
- <b>Implementing the SLF4J API</b>
-
- <ol type="1">
-
- <li><a href="#slf4j_compatible">How do I make my logging
- framework SLF4J compatible? </a></li>
-
- <li><a href="#marker_interface">How can my logging system add
- support for the <code>Marker</code> interface? </a></li>
-
- <li><a href="#version_checks">How does SLF4J's version check
- mechanism work? </a></li>
-
-
- </ol>
-
-
- <b>General questions about logging</b>
-
-
- <ol type="1">
-
- <li><a href="#declared_static"> Should Logger members of a class
- be declared as static? </a></li>
-
-
- <li><a href="#declaration_pattern">Is there a recommended idiom
- for declaring a loggers in a class?</a></li>
-
- </ol>
-
- <h2>Generalities</h2>
-
- <dl>
- <dt class="doAnchor" name="what_is">What is SLF4J?</dt>
- <dd>
- <p>SLF4J is a simple facade for logging systems allowing the
- end-user to plug-in the desired logging system at deployment
- time.
- </p>
- </dd>
-
- <dt class="doAnchor" name="when">When should SLF4J be used?</dt>
-
- <dd>
- <p>In short, libraries and other embedded components should
- consider SLF4J for their logging needs because libraries cannot
- afford to impose their choice of logging framework on the
- end-user. On the other hand, it does not necessarily make sense
- for stand-alone applications to use SLF4J. Stand-alone
- applications can invoke the logging framework of their choice
- directly. In the case of logback, the question is moot because
- logback exposes its logger API via SLF4J.
- </p>
-
- <p>SLF4J is only a facade, meaning that it does not provide a
- complete logging solution. Operations such as configuring
- appenders or setting logging levels cannot be performed with
- SLF4J. Thus, at some point in time, any non-trivial
- application will need to directly invoke the underlying
- logging system. In other words, complete independence from the
- API underlying logging system is not possible for a
- stand-alone application. Nevertheless, SLF4J reduces the
- impact of this dependence to near-painless levels.
- </p>
-
- <p>Suppose that your CRM application uses log4j for its
- logging. However, one of your important clients request that
- logging be performed through JDK 1.4 logging. If your
- application is riddled with thousands of direct log4j calls,
- migration to JDK 1.4 would be a relatively lengthy and
- error-prone process. Even worse, you would potentially need to
- maintain two versions of your CRM software. Had you been
- invoking SLF4J API instead of log4j, the migration could be
- completed in a matter of minutes by replacing one jar file with
- another.
- </p>
-
- <p>SLF4J lets component developers to defer the choice of the
- logging system to the end-user but eventually a choice needs
- to be made.
- </p>
-
-
-
- </dd>
-
- <dt class="doAnchor" name="yet_another_facade">Is SLF4J yet
- another logging facade?</dt>
-
- <dd>
- <p>SLF4J is conceptually very similar to JCL. As such, it can
- be thought of as yet another logging facade. However, SLF4J is
- much simpler in design and arguably more robust. In a
- nutshell, SLF4J avoid the class loader issues that plague JCL.
- </p>
-
-
-
- </dd>
- <dt class="doAnchor" name="why_new_project">If SLF4J fixes JCL,
- then why wasn't the fix made in JCL instead of creating a new
- project?
- </dt>
-
- <dd>
- <p>This is a very good question. First, SLF4J static binding
- approach is very simple, perhaps even laughably so. It was
- not easy to convince developers of the validity of that
- approach. It is only after SLF4J was released and started to
- become accepted did it gain respectability in the relevant
- community.
- </p>
-
- <p>Second, SLF4J offers two enhancements which tend to be
- underestimated. Parameterized log messages solve an important
- problem associated with logging performance, in a pragmatic
- way. Marker objects, which are supported by the
- <code>org.slf4j.Logger</code> interface, pave the way for
- adoption of advanced logging systems and still leave the door
- open to switching back to more traditional logging systems if
- need be.
- </p>
-
-
- </dd>
-
- <dt class="doAnchor" name="need_to_recompile">When using SLF4J, do
- I have to recompile my application to switch to a different
- logging system?
- </dt>
-
- <dd>
- <p>No, you do not need to recompile your application. You can
- switch to a different logging system by removing the previous
- SLF4J binding and replacing it with the binding of your choice.
- </p>
-
- <p>For example, if you were using the NOP implementation and
- would like to switch to log4j version 1.2, simply replace
- <em>slf4j-nop.jar</em> with <em>slf4j-log4j12.jar</em> on
- your class path but do not forget to add log4j-1.2.x.jar as
- well. Want to switch to JDK 1.4 logging? Just replace
- <em>slf4j-log4j12.jar</em> with <em>slf4j-jdk14.jar</em>.
- </p>
-
-
- </dd>
-
- <dt class="doAnchor" name="requirements">What are SLF4J's
- requirements?
- </dt>
-
- <dd>
-
- <p>As of version 1.7.0, SLF4J requires JDK 1.5 or later. Earlier
- SLF4J versions, namely SLF4J 1.4, 1.5. and 1.6, required JDK
- 1.4.
- </p>
-
- <p>&nbsp;</p>
-
- <table class="bodyTable striped">
- <tr align="left">
- <th>Binding</th>
- <th>Requirements</th>
- </tr>
-
- <tr>
- <td>slf4j-nop</td>
- <td>JDK 1.5</td>
- </tr>
- <tr>
- <td>slf4j-simple</td>
- <td>JDK 1.5</td>
- </tr>
-
- <tr>
- <td>slf4j-log4j12</td>
- <td align="left">JDK 1.5, plus any other library
- dependencies required by the log4j appenders in use</td>
- </tr>
- <tr>
- <td>slf4j-jdk14</td>
- <td>JDK 1.5 or later</td>
- </tr>
- <tr>
- <td>logback-classic</td>
- <td>JDK 1.5 or later, plus any other library dependencies
- required by the logback appenders in use</td>
- </tr>
-
- </table>
-
-
- </dd>
-
- <!-- ==================================================== -->
- <!-- entry has order dependees -->
-
- <dt class="doAnchor" name="compatibility">Are SLF4J versions
- backward compatible?
- </dt>
-
- <dd>
- <p>From the clients perspective, the SLF4J API is backward
- compatible for all versions. This means than you can upgrade
- from SLF4J version 1.0 to any later version without
- problems. Code compiled with <em>slf4j-api-versionN.jar</em>
- will work with <em>slf4j-api-versionM.jar</em> for any versionN
- and any versionM. <b>To date, binary compatibility in slf4j-api
- has never been broken.</b></p>
-
- <p>However, while the SLF4J API is very stable from the client's
- perspective, SLF4J bindings, e.g. slf4j-simple.jar or
- slf4j-log4j12.jar, may require a specific version of slf4j-api.
- Mixing different versions of slf4j artifacts can be problematic
- and is strongly discouraged. For instance, if you are using
- slf4j-api-1.5.6.jar, then you should also use
- slf4j-simple-1.5.6.jar, using slf4j-simple-1.4.2.jar will not
- work.
- </p>
-
- <p>At initialization time, if SLF4J suspects that there may be a
- version mismatch problem, it emits a warning about the said
- mismatch.
- </p>
-
-
- </dd>
-
- <!-- ==================================================== -->
-
- <dt class="doAnchor" name="IllegalAccessError">I am getting
- <code>IllegalAccessError</code> exceptions when using SLF4J. Why
- is that?
- </dt>
-
- <dd>
-
- <p>Here are the exception details.</p>
-
- <pre class="source">Exception in thread "main" java.lang.IllegalAccessError: tried to access field
-org.slf4j.impl.StaticLoggerBinder.SINGLETON from class org.slf4j.LoggerFactory
- at org.slf4j.LoggerFactory.&lt;clinit>(LoggerFactory.java:60)</pre>
-
- <p>This error is caused by the static initializer of the
- <code>LoggerFactory</code> class attempting to directly access
- the SINGLETON field of
- <code>org.slf4j.impl.StaticLoggerBinder</code>. While this was
- allowed in SLF4J 1.5.5 and earlier, in 1.5.6 and later the
- SINGLETON field has been marked as private access.
- </p>
-
-
- <p>If you get the exception shown above, then you are using an
- older version of slf4j-api, e.g. 1.4.3, with a new version of a
- slf4j binding, e.g. 1.5.6. Typically, this occurs when your
- Maven <em>pom.ml</em> file incorporates hibernate 3.3.0 which
- declares a dependency on slf4j-api version 1.4.2. If your
- <em>pom.xml</em> declares a dependency on an slf4j binding, say
- slf4j-log4j12 version 1.5.6, then you will get illegal access
- errors.
- </p>
-
- <p>To see which version of slf4j-api is pulled in by Maven, use
- the maven dependency plugin as follows.</p>
-
- <p class="source">mvn dependency:tree</p>
-
- <p>If you are using Eclipse, please do not rely on the dependency
- tree shown by <a
- href="http://m2eclipse.codehaus.org/">m2eclipse</a>.</p>
-
- <p>In your <em>pom.xml</em> file, explicitly declaring a
- dependency on slf4j-api matching the version of the declared
- binding will make the problem go away.
- </p>
-
- <p>Please also read the FAQ entry on <a
- href="#compatibility">backward compatibility</a> for a more
- general explanation.</p>
-
-
- </dd>
-
-
- <!-- ==================================================== -->
-
- <dt class="doAnchor" name="license">Why is SLF4J licensed under
- X11 type license instead of the Apache Software License?
- </dt>
-
- <dd>
- <p>SLF4J is licensed under a permissive X11 type license
- instead of the <a
- href="http://www.apache.org/licenses/">ASL</a> or the <a
- href="http://www.gnu.org/copyleft/lesser.html">LGPL</a>
- because the X11 license is deemed by both the Apache Software
- Foundation as well as the Free Software Foundation as
- compatible with their respective licenses.
- </p>
-
-
- </dd>
-
- <!-- ==================================================== -->
- <dt class="doAnchor" name="where_is_binding">Where can I get a
- particular SLF4J binding?
- </dt>
-
- <dd>
-
- <p>SLF4J bindings for <a
- href="api/org/slf4j/impl/SimpleLogger.html">SimpleLogger</a>,
- <a href="api/org/slf4j/impl/NOPLogger.html">NOPLogger</a>, <a
- href="api/org/slf4j/impl/Log4jLoggerAdapter.html">Log4jLoggerAdapter</a>
- and <a
- href="api/org/slf4j/impl/JDK14LoggerAdapter.html">JDK14LoggerAdapter</a>
- are contained within the files <em>slf4j-nop.jar</em>,
- <em>slf4j-simple.jar</em>, <em>slf4j-log4j12.jar</em>, and
- <em>slf4j-jdk14.jar</em>. These files ship with the <a
- href="download.html">official SLF4J distribution</a>. Please
- note that all bindings depend on <em>slf4j-api.jar</em>.
- </p>
-
- <p>The binding for logback-classic ships with the <a
- href="http://logback.qos.ch/download.html">logback
- distribution</a>. However, as with all other bindings, the
- logback-classic binding requires <em>slf4j-api.jar</em>.
- </p>
-
-
- </dd>
-
- <dt class="doAnchor" name="configure_logging">Should my library
- attempt to configure logging?
- </dt>
-
- <dd>
- <p><b>Embedded components such as libraries not only do not need
- to configure the underlying logging framework, they really
- should not do so</b>. They should invoke SLF4J to log but should
- let the end-user configure the logging environment. When
- embedded components try to configure logging on their own, they
- often override the end-user's wishes. At the end of the day, it
- is the end-user who has to read the logs and process them. She
- should be the person to decide how she wants her logging
- configured.
- </p>
-
-
- </dd>
-
- <!-- ======================================================= -->
-
- <dt class="doAnchor" name="optional_dependency">In order to reduce
- the number of dependencies of our software we would like to make
- SLF4J an optional dependency. Is that a good idea?
- </dt>
-
- <dd>
- <p><a
- href="http://stackoverflow.com/questions/978670/is-it-worth-wrapping-a-logging-framework-in-an-additional-layer">This
- question pops up</a> whenever a software project reaches a point
- where it needs to devise a logging strategy.
- </p>
-
- <p>Let Wombat be a software library with very few
- dependencies. If SLF4J is chosen as Wombat's logging API, then a
- new dependency on <em>slf4j-api.jar</em> will be added to
- Wombat's list of dependencies. Given that writing a logging
- wrapper does not seem that hard, some developers will be tempted
- to wrap SLF4J and link with it only if it is already present on
- the classpath, making SLF4J an optional dependency of Wombat. In
- addition to solving the dependency problem, the wrapper will
- isolate Wombat from SLF4J's API ensuring that logging in Wombat
- is future-proof.
- </p>
-
- <p>On the other hand, any SLF4J-wrapper by definition depends on
- SLF4J. It is bound to have the same general API. If in the
- future a new and significantly different logging API comes
- along, code that uses the wrapper will be equally difficult to
- migrate to the new API as code that used SLF4J directly. Thus,
- the wrapper is not likely to future-proof your code, but to make
- it more complex by adding an additional indirection on top of
- SLF4J, which is an indirection in itself.
- </p>
-
- <p><span class="label">increased vulnerability</span> It is
- actually worse than that. Wrappers will need to depend on
- certain internal SLF4J interfaces which change from time to
- time, contrary to the client-facing API which never
- changes. Thus, wrappers are usually dependent on the major
- version they were compiled with. A wrapper compiled against
- SLF4J version 1.5.x will not work with SLF4J 1.6 whereas client
- code using <code>org.slf4j.Logger</code>,
- <code>LoggerFactory</code>, <code>MarkerFactory</code>,
- <code>org.slf4j.Marker</code>, and <code>MDC</code> will work
- fine with any SLF4J version from version 1.0 and onwards.
- </p>
-
- <p>It is reasonable to assume that in most projects Wombat will
- be one dependency among many. If each library had its own
- logging wrapper, then each wrapper would presumably need to be
- configured separately. Thus, instead of having to deal with one
- logging framework, namely SLF4J, the user of Wombat would have
- to detail with Wombat's logging wrapper as well. The problem
- will be compounded by each framework that comes up with its own
- wrapper in order to make SLF4J optional. (Configuring or
- dealing with the intricacies of five different logging wrappers
- is not exactly exciting nor endearing.)
- </p>
-
- <p>The <a
- href="http://velocity.apache.org/engine/devel/developer-guide.html#Configuring_Logging">logging
- strategy adopted by the Velocity project</a> is a good example
- of the "custom logging abstraction" anti-pattern. By adopting an
- independent logging abstraction strategy, Velocity developers
- have made life harder for themselves, but more importantly, they
- made life harder for their users.
- </p>
-
- <p>Some projects try to detect the presence of SLF4J on the
- class path and switch to it if present. While this approach
- seems transparent enough, it will result in erroneous location
- information. Underlying logging frameworks will print the
- location (class name and line number) of the wrapper instead of
- the real caller. Then there is the question of API coverage as
- SLF4J support MDC and markers in addition to parameterized
- logging. While one can come up with a seemingly working
- SLF4J-wrapper within hours, many technical issues will emerge
- over time which Wombat developers will have to deal with. Note
- that SLF4J has evolved over several years and has 260 bug
- reports filed against it.</p>
-
- <p>For the above reasons, developers of frameworks should resist
- the temptation to write their own logging wrapper. Not only is
- it a waste of time of the developer, it will actually make life
- more difficult for the users of said frameworks and make logging
- code paradoxically more vulnerable to change.
- </p>
- </dd>
-
-
- <!-- ======================================================= -->
-
- <dt class="doAnchor" name="maven2">What about Maven transitive
- dependencies?
- </dt>
-
- <dd>
- <p>As an author of a library built with Maven, you might want to
- test your application using a binding, say slf4j-log4j12 or
- logback-classic, without forcing log4j or logback-classic as a
- dependency upon your users. This is rather easy to accomplish.
- </p>
-
- <p>Given that your library's code depends on the SLF4J API, you
- will need to declare slf4j-api as a compile-time (default scope)
- dependency.
- </p>
- <pre class="prettyprint source">&lt;dependency&gt;
- &lt;groupId&gt;org.slf4j&lt;/groupId&gt;
- &lt;artifactId&gt;slf4j-api&lt;/artifactId&gt;
- &lt;version&gt;${project.version}&lt;/version&gt;
-&lt;/dependency&gt;</pre>
-
- <p>Limiting the transitivity of the SLF4J binding used in your
- tests can be accomplished by declaring the scope of the
- SLF4J-binding dependency as "test". Here is an example:</p>
-
- <pre class="prettyprint source">&lt;dependency&gt;
- &lt;groupId&gt;org.slf4j&lt;/groupId&gt;
- &lt;artifactId&gt;slf4j-log4j12&lt;/artifactId&gt;
- &lt;version&gt;${project.version}&lt;/version&gt;
- <b>&lt;scope&gt;test&lt;/scope&gt;</b>
-&lt;/dependency&gt;</pre>
-
- <p>Thus, as far as your users are concerned you are exporting
- slf4j-api as a transitive dependency of your library, but not
- any SLF4J-binding or any underlying logging system.
- </p>
-
- <p>Note that as of SLF4J version 1.6, in the absence of an SLF4J
- binding, slf4j-api will default to a no-operation
- implementation.
- </p>
-
-
-
- </dd>
-
- <!-- ====================================================== -->
- <dt class="doAnchor" name="excludingJCL">How do I exclude
- commons-logging as a Maven dependency?
- </dt>
-
- <dd>
- <p><b>alternative 1) explicit exclusion</b></p>
-
- <p>Many software projects using Maven declare commons-logging as
- a dependency. Therefore, if you wish to migrate to SLF4J or use
- jcl-over-slf4j, you would need to exclude commons-logging in all
- of your project's dependencies which transitively depend on
- commons-logging. <a
- href="http://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html">Dependency
- exclusion</a> is described in the Maven documentation. Excluding
- commons-logging explicitly for multiple dependencies distributed
- on several <em>pom.xml</em> files can be a cumbersome and a
- relatively error prone process.
- </p>
-
- <p><b>alternative 2) provided scope</b></p>
-
- <p>Commons-logging can be rather simply and conveniently
- excluded as a dependency by declaring it in the
- <em>provided</em> scope within the pom.xml file of your
- project. The actual commons-logging classes would be provided by
- jcl-over-slf4j. This translates into the following pom file
- snippet:</p>
-
- <pre class="prettyprint source">&lt;dependency>
- &lt;groupId>commons-logging&lt;/groupId>
- &lt;artifactId>commons-logging&lt;/artifactId>
- &lt;version>1.1.1&lt;/version>
- &lt;scope>provided&lt;/scope>
-&lt;/dependency>
-
-&lt;dependency>
- &lt;groupId>org.slf4j&lt;/groupId>
- &lt;artifactId>jcl-over-slf4j&lt;/artifactId>
- &lt;version>${project.version}&lt;/version>
-&lt;/dependency></pre>
-
- <p>The first dependency declaration essentially states that
- commons-logging will be "somehow" provided by your
- environment. The second declaration includes jcl-over-slf4j into
- your project. As jcl-over-slf4j is a perfect binary-compatible
- replacement for commons-logging, the first assertion becomes
- true.
- </p>
-
- <p>Unfortunately, while declaring commons-logging in the
- provided scope gets the job done, your IDE, e.g. Eclipse, will
- still place <em>commons-logging.jar</em> on your project's class
- path as seen by your IDE. You would need to make sure that
- <em>jcl-over-slf4j.jar</em> is visible before
- <em>commons-logging.jar</em> by your IDE.
- </p>
-
- <p><b>alternative 3) empty artifacts</b></p>
-
- <p>An alternative approach is to depend on an <b>empty</b>
- <em>commons-logging.jar</em> artifact. This clever <a
- href="http://day-to-day-stuff.blogspot.com/2007/10/announcement-version-99-does-not-exist.html">approach
- first was imagined</a> and initially supported by Erik van
- Oosten.
- </p>
-
- <p>The empty artifact is available from a <a
- href="http://version99.qos.ch">http://version99.qos.ch</a> a
- high-availability Maven repository, replicated on several hosts
- located in different geographical regions.</p>
-
- <p>The following declaration adds the version99 repository to
- the set of remote repositories searched by Maven. This
- repository contains empty artifacts for commons-logging and
- log4j. By the way, if you use the version99 repository, please
- drop us a line at &lt;version99 AT qos.ch&gt;.
- </p>
-
- <pre class="prettyprint source">&lt;repositories>
- &lt;repository>
- &lt;id>version99&lt;/id>
- &lt;!-- highly available repository serving empty artifacts --&gt;
- &lt;url>http://version99.qos.ch/&lt;/url>
- &lt;/repository>
-&lt;/repositories></pre>
-
- <p>Declaring version 99-empty of commons-logging in the
- <code>&lt;dependencyManagement></code> section of your project
- will direct all transitive dependencies for commons-logging to
- import version 99-empty, thus nicely addressing the
- commons-logging exclusion problem. The classes for commons-logging
- will be provided by jcl-over-slf4j. The following lines declare
- commons-logging version 99-empty (in the dependency management
- section) and declare jcl-over-slf4j as a dependency.
- </p>
-
-<pre class="prettyprint source">&lt;dependencyManagement>
- &lt;dependencies>
- &lt;dependency>
- &lt;groupId>commons-logging&lt;/groupId>
- &lt;artifactId>commons-logging&lt;/artifactId>
- &lt;version><b>99-empty</b>&lt;/version>
- &lt;/dependency>
- ... other declarations...
- &lt;/dependencies>
-&lt;/dependencyManagement>
-
-&lt;!-- Do not forget to declare a dependency on jcl-over-slf4j in the --&gt;
-&lt;!-- dependencies section. Note that the dependency on commons-logging --&gt;
-&lt;!-- will be imported transitively. You don't have to declare it yourself. --&gt;
-&lt;dependencies>
- &lt;dependency>
- &lt;groupId>org.slf4j&lt;/groupId>
- &lt;artifactId>jcl-over-slf4j&lt;/artifactId>
- &lt;version>${project.version}&lt;/version>
- &lt;/dependency>
- ... other dependency declarations
-&lt;/dependencies>
-</pre>
-
-
- </dd>
-
-
-
- </dl>
-
-
- <h2>About the SLF4J API</h2>
-
- <dl>
-
- <dt class="doAnchor" name="string_or_object">Why don't the
- printing methods in the Logger interface accept message of type
- Object, but only messages of type String?
- </dt>
-
- <dd>
-
- <p>In SLF4J 1.0beta4, the printing methods such as debug(),
- info(), warn(), error() in the <a
- href="api/org/slf4j/Logger.html">Logger interface</a> were
- modified so as to accept only messages of type String
- instead of Object.
- </p>
-
- <p>Thus, the set of printing methods for the DEBUG level
- became:</p>
-
- <pre class="prettyprint source">debug(String msg);
-debug(String format, Object arg);
-debug(String format, Object arg1, Object arg2);
-debug(String msg, Throwable t);</pre>
-
- <p>Previously, the first argument in the above methods was of
- type <code>Object</code>.</p>
-
- <p>This change enforces the notion that logging systems are
- about decorating and handling messages of type String, and not
- any arbitrary type (Object).
- </p>
-
- <p>Just as importantly, the new set of method signatures offer
- a clearer differentiation between the overloaded methods
- whereas previously the choice of the invoked method due to
- Java overloading rules were not always easy to follow.</p>
-
- <p>It was also easy to make mistakes. For example, previously
- it was legal to write:</p>
-
- <pre class="prettyprint source">logger.debug(new Exception("some error"));</pre>
-
- <p>Unfortunately, the above call did not print the stack trace
- of the exception. Thus, a potentially crucial piece of
- information could be lost. When the first parameter is
- restricted to be of type String, then only the method
- </p>
-
- <pre class="prettyprint source">debug(String msg, Throwable t);</pre>
-
- <p>can be used to log exceptions. Note that this method
- ensures that every logged exception is accompanied with a
- descriptive message.</p>
-
-
- </dd>
-
- <!-- ====================================================== -->
-
- <dt class="doAnchor" name="exception_message">Can I log an
- exception without an accompanying message?
- </dt>
-
- <dd>
- <p>In short, no.</p>
-
- <p>If <code>e</code> is an <code>Exception</code>, and you
- would like to log an exception at the ERROR level, you must
- add an accompanying message. For example,</p>
-
- <pre class="prettyprint source">logger.error("some accompanying message", e);</pre>
-
- <p>You might legitimately argue that not all exceptions have a
- meaningful message to accompany them. Moreover, a good exception
- should already contain a self explanatory description. The
- accompanying message may therefore be considered redundant.
- </p>
-
-
- <p>While these are valid arguments, there are three opposing
- arguments also worth considering. First, on many, albeit not
- all occasions, the accompanying message can convey useful
- information nicely complementing the description contained
- in the exception. Frequently, at the point where the
- exception is logged, the developer has access to more
- contextual information than at the point where the exception
- is thrown. Second, it is not difficult to imagine more or
- less generic messages, e.g. "Exception caught", "Exception
- follows", that can be used as the first argument for
- <code>error(String msg, Throwable t)</code> invocations.
- Third, most log output formats display the message on a
- line, followed by the exception on a separate line. Thus,
- the message line would look inconsistent without a message.
- </p>
-
- <p>In short, if the user were allowed to log an exception
- without an accompanying message, it would be the job of the
- logging system to invent a message. This is actually what
- the <a href="http://tinyurl.com/cr9kg">throwing(String
- sourceClass, String sourceMethod, Throwable thrown)</a>
- method in java.util.logging package does. (It decides on its
- own that accompanying message is the string "THROW".)
- </p>
-
- <p>It may initially appear strange to require an accompanying
- message to log an exception. Nevertheless, this is common
- practice in <em>all</em> log4j derived systems such as
- java.util.logging, logkit, etc. and of course log4j itself. It
- seems that the current consensus considers requiring an
- accompanying message as a good a thing (TM).
- </p>
-
- </dd>
-
- <!-- ====================================================== -->
-
-
- <dt class="doAnchor" name="logging_performance">What is the
- fastest way of (not) logging?
- </dt>
-
- <dd>
- <p>SLF4J supports an advanced feature called parameterized
- logging which can significantly boost logging performance for
- <em>disabled</em> logging statement.</p>
-
- <p> For some Logger <code>logger</code>, writing,</p>
- <pre class="prettyprint source">logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));</pre>
-
- <p>incurs the cost of constructing the message parameter, that
- is converting both integer <code>i</code> and
- <code>entry[i]</code> to a String, and concatenating
- intermediate strings. This, regardless of whether the message
- will be logged or not.
- </p>
-
- <p>One possible way to avoid the cost of parameter
- construction is by surrounding the log statement with a
- test. Here is an example.</p>
-
- <pre class="prettyprint source">if(logger.isDebugEnabled()) {
- logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
-}</pre>
-
-
- <p>This way you will not incur the cost of parameter
- construction if debugging is disabled for
- <code>logger</code>. On the other hand, if the logger is
- enabled for the DEBUG level, you will incur the cost of
- evaluating whether the logger is enabled or not, twice: once in
- <code>debugEnabled</code> and once in <code>debug</code>. This
- is an insignificant overhead because evaluating a logger takes
- less than 1% of the time it takes to actually log a statement.
- </p>
-
- <p><b>Better yet, use parameterized messages</b></p>
-
- <p>There exists a very convenient alternative based on message
- formats. Assuming <code>entry</code> is an object, you can write:
- </p>
-
-
- <pre class="prettyprint source">Object entry = new SomeObject();
-logger.debug("The entry is {}.", entry);</pre>
-
- <p>After evaluating whether to log or not, and only if the
- decision is affirmative, will the logger implementation format
- the message and replace the '{}' pair with the string value of
- <code>entry</code>. In other words, this form does not incur
- the cost of parameter construction in case the log statement is
- disabled.
- </p>
-
- <p>The following two lines will yield the exact same
- output. However, the second form will outperform the first
- form by a factor of at least 30, in case of a
- <em>disabled</em> logging statement.
- </p>
-
- <pre class="prettyprint source">logger.debug("The new entry is "+entry+".");
-logger.debug("The new entry is {}.", entry);</pre>
-
-
- <p>A <a
- href="apidocs/org/slf4j/Logger.html#debug(java.lang.String,%20java.lang.Object%2C%20java.lang.Object)">two
- argument</a> variant is also available. For example, you can
- write:</p>
-
-
- <pre class="prettyprint source">logger.debug("The new entry is {}. It replaces {}.", entry, oldEntry);</pre>
-
- <p>If three or more arguments need to be passed, you can make
- use of the <a
- href="apidocs/org/slf4j/Logger.html#debug(java.lang.String%2C%20java.lang.Object...)"><code>Object...</code>
- variant</a> of the printing methods. For example, you can
- write:</p>
-
- <pre class="prettyprint source">logger.debug("Value {} was inserted between {} and {}.", newVal, below, above);</pre>
-
- <p>This form incurs the hidden cost of construction of an
- Object[] (object array) which is usually very small. The one and
- two argument variants do not incur this hidden cost and exist
- solely for this reason (efficiency). The slf4j-api would be
- smaller/cleaner with only the Object... variant.</p>
-
-
- <p>Array type arguments, including multi-dimensional arrays,
- are also supported.</p>
-
- <p>SLF4J uses its own message formatting implementation which
- differs from that of the Java platform. This is justified by
- the fact that SLF4J's implementation performs about 10 times
- faster but at the cost of being non-standard and less
- flexible.
- </p>
-
- <p><b>Escaping the "{}" pair</b></p>
-
- <p>The "{}" pair is called the <em>formatting anchor</em>. It
- serves to designate the location where arguments need to be
- substituted within the message pattern.
- </p>
-
- <p>SLF4J only cares about the <em>formatting anchor</em>, that
- is the '{' character immediately followed by '}'. Thus, in
- case your message contains the '{' or the '}' character, you
- do not have to do anything special unless the '}' character
- immediately follows '}'. For example,
- </p>
-
- <pre class="prettyprint source">logger.debug("Set {1,2} differs from {}", "3");</pre>
-
- <p>which will print as "Set {1,2} differs from 3". </p>
-
- <p>You could have even written,</p>
- <pre class="prettyprint source">logger.debug("Set {1,2} differs from {{}}", "3");</pre>
- <p>which would have printed as "Set {1,2} differs from {3}". </p>
-
- <p>In the extremely rare case where the the "{}" pair occurs
- naturally within your text and you wish to disable the special
- meaning of the formatting anchor, then you need to escape the
- '{' character with '\', that is the backslash character. Only
- the '{' character should be escaped. There is no need to
- escape the '}' character. For example,
- </p>
-
- <pre class="prettyprint source">logger.debug("Set \\{} differs from {}", "3");</pre>
-
- <p>will print as "Set {} differs from 3". Note that within
- Java code, the backslash character needs to be written as
- '\\'.</p>
-
- <p>In the rare case where the "\{}" occurs naturally in the
- message, you can double escape the formatting anchor so that
- it retains its original meaning. For example,</p>
-
-
- <pre class="prettyprint source">logger.debug("File name is C:\\\\{}.", "file.zip");</pre>
- <p>will print as "File name is C:\file.zip".</p>
-
- </dd>
-
- <!-- ================================================= -->
-
- <dt class="doAnchor" name="string_contents">How can I log the
- string contents of a single (possibly complex) object?</dt>
-
- <dd>
- <p> In relatively rare cases where the message to be logged
- is the string form of an object, then the parameterized
- printing method of the appropriate level can be
- used. Assuming <code>complexObject</code> is an object of
- certain complexity, for a log statement of level DEBUG, you
- can write:
- </p>
-
- <pre class="prettyprint source">logger.debug("{}", complexObject);</pre>
-
-
- <p>The logging system will invoke
- <code>complexObject.toString()</code> method only after it
- has ascertained that the log statement was
- enabled. Otherwise, the cost of
- <code>complexObject.toString()</code> conversion will be
- advantageously avoided.
- </p>
-
-
-
- </dd>
-
- <!-- ================================================= -->
-
-
- <dt class="doAnchor" name="fatal">Why doesn't the
- <code>org.slf4j.Logger</code> interface have methods for the FATAL
- level?
- </dt>
-
- <dd>
- <p>The <a href="apidocs/org/slf4j/Marker.html">Marker</a>
- interface, part of the <code>org.slf4j</code> package, renders
- the FATAL level largely redundant. If a given error requires
- attention beyond that allocated for ordinary errors, simply mark
- the logging statement with a specially designated marker which
- can be named "FATAL" or any other name to your liking.
- </p>
-
- <p>Here is an example,</p>
-
-<pre class="prettyprint">import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.slf4j.Marker;
-import org.slf4j.MarkerFactory;
-
-class Bar {
- void foo() {
- <b>Marker fatal = MarkerFactory.getMarker("FATAL");</b>
- Logger logger = LoggerFactory.getLogger("aLogger");
-
- try {
- ... obtain a JDBC connection
- } catch (JDBException e) {
- logger.error(<b>fatal</b>, "Failed to obtain JDBC connection", e);
- }
- }
-}</pre>
-
-
- <p>While markers are part of the SLF4J API, only logback
- supports markers off the shelf. For example, if you add the
- <code>%marker</code> conversion word to its pattern, logback's
- <code>PatternLayout</code> will add marker data to its
- output. Marker data can be used to <a
- href="http://logback.qos.ch/manual/filters.html">filter
- messages</a> or even <a
- href="http://logback.qos.ch/manual/appenders.html#OnMarkerEvaluator">trigger</a>
- an outgoing email <a
- href="http://logback.qos.ch/recipes/emailPerTransaction.html">at
- the end of an individual transaction</a>.
- </p>
-
- <p>In combination with logging frameworks such as log4j and
- java.util.logging which do not support markers, marker data will
- be silently ignored.</p>
-
- <p>Markers add a new dimension with infinite possible values for
- processing log statements compared to five values, namely ERROR,
- WARN, INFO, DEBUG and TRACE, allowed by levels. At present time,
- only logback supports marker data. However, nothing prevents
- other logging frameworks from making use of marker data.
- </p>
-
- </dd>
-
- <!-- ======================================================= -->
- <dt class="doAnchor" name="trace">Why was the TRACE level
- introduced only in SLF4J version 1.4.0?</dt>
-
- <dd>
-
- <p>The addition of the TRACE level has been frequently and
- hotly debated request. By studying various projects, we
- observed that the TRACE level was used to disable logging
- output from certain classes <em>without</em> needing to
- configure logging for those classes. Indeed, the TRACE level
- is by default disabled in log4j and logback as well most other
- logging systems. The same result can be achieved by adding the
- appropriate directives in configuration files.
- </p>
-
- <p>Thus, in many of cases the TRACE level carried the same
- semantic meaning as DEBUG. In such cases, the TRACE level
- merely saves a few configuration directives. In other, more
- interesting occasions, where TRACE carries a different meaning
- than DEBUG, <a href="api/org/slf4j/Marker.html">Marker</a>
- objects can be put to use to convey the desired
- meaning. However, if you can't be bothered with markers and
- wish to use a logging level lower than DEBUG, the TRACE level
- can get the job done.
- </p>
-
- <p>Note that while the cost of evaluating a disabled log
- request is in the order of a few <code>nanoseconds</code>, the
- use of the TRACE level (or any other level for that matter) is
- discouraged in tight loops where the log request might be
- evaluated millions of times. If the log request is enabled,
- then it will overwhelm the target destination with massive
- output. If the request is disabled, it will waste resources.
- </p>
-
- <p>In short, although we still discourage the use of the TRACE
- level because alternatives exist or because in many cases log
- requests of level TRACE are wasteful, given that people kept
- asking for it, we decided to bow to popular demand.
- </p>
-
-
- </dd>
-
- <!-- ================================================= -->
- <dt class="doAnchor" name="i18n">Does the SLF4J logging API
- support I18N (internationalization)?
- </dt>
-
- <dd>
- <p>Yes, as of version 1.5.9, SLF4J ships with a package called
- <code>org.slf4j.cal10n</code> which adds <a
- href="localization.html">localized/internationalized logging</a>
- support as a thin layer built upon the <a
- href="http://cal10n.qos.ch">CAL10N API</a>.</p>
-
-
- </dd>
-
- <!-- ================================================= -->
-
- <dt class="doAnchor" name="noLoggerFactory">Is it possible to
- retrieve loggers without going through the static methods in
- <code>LoggerFactory</code>?
- </dt>
-
- <dd>
-
- <p>Yes. <code>LoggerFactory</code> is essentially a wrapper
- around an <a
- href="xref/org/slf4j/ILoggerFactory.html"><code>ILoggerFactory</code></a>
- instance. The <code>ILoggerFactory</code> instance in use is
- determined according to the static binding conventions of the
- SLF4J framework. See the <a
- href="xref/org/slf4j/LoggerFactory.html#217">getSingleton()</a>
- method in <code>LoggerFactory</code> for details.
- </p>
-
- <p>However, nothing prevents you from using your own
- <code>ILoggerFactory</code> instance. Note that you can also
- obtain a reference to the <code>ILoggerFactory</code> that the
- <code>LoggerFactory</code> class is using by invoking the <a
- href="apidocs/org/slf4j/LoggerFactory.html#getILoggerFactory()">
- <code>LoggerFactory.getILoggerFactory()</code></a> method.
- </p>
-
- <p>Thus, if SLF4J binding conventions do not fit your needs, or
- if you need additional flexibility, then do consider using the
- <code>ILoggerFactory</code> interface as an alternative to
- inventing your own logging API.</p>
- </dd>
-
- <!-- ================================================= -->
-
- <dt class="doAnchor" name="paramException">In the presence of an
- exception/throwable, is it possible to parameterize a logging
- statement?</dt>
-
-
- <dd>
- <p>Yes, as of SLF4J 1.6.0, but not in previous versions. The
- SLF4J API supports parametrization in the presence of an
- exception, assuming the exception is the last parameter. Thus,
- </p>
- <pre class="prettyprint">String s = "Hello world";
-try {
- Integer i = Integer.valueOf(s);
-} catch (NumberFormatException e) {
- logger.error("Failed to format {}", s, e);
-}</pre>
-
- <p>will print the <code>NumberFormatException</code> with its
- stack trace as expected. The java compiler will invoke the <a
- href="http://www.slf4j.org/apidocs/org/slf4j/Logger.html#error%28java.lang.String,%20java.lang.Object,%20java.lang.Object%29">error
- method taking a String and two Object arguments</a>. SLF4J, in
- accordance with the programmer's most probable intention, will
- interpret <code>NumberFormatException</code> instance as a
- throwable instead of an unused <code>Object</code> parameter. In
- SLF4J versions prior to 1.6.0, the
- <code>NumberFormatException</code> instance was simply ignored.
- </p>
-
- <p>If the exception is not the last argument, it will be treated
- as a plain object and its stack trace will NOT be printed.
- However, such situations should not occur in practice.
- </p>
-
- </dd>
- </dl>
-
-
-
- <h2>Implementing the SLF4J API</h2>
-
- <dl>
-
- <!-- ============================================================= -->
-
- <dt class="doAnchor" name="slf4j_compatible">How do I make my
- logging framework SLF4J compatible?
- </dt>
-
-
- <dd>
-
- <p>Adding supporting for the SLF4J is surprisingly
- easy. Essentially, you coping an existing binding and tailoring
- it a little (as explained below) does the trick.
- </p>
-
- <p>Assuming your logging system has notion of a
- logger, called say <code>MyLogger</code>, you need to provide
- an adapter for <code>MyLogger</code> to
- <code>org.slf4j.Logger</code> interface. Refer to slf4j-jcl,
- slf4j-jdk14, and slf4j-log4j12 modules for examples of
- adapters.
- </p>
-
- <p>Once you have written an appropriate adapter, say
- <code>MyLoggerAdapter</code>, you need to provide a factory
- class implementing the <code>org.slf4j.ILoggerFactory</code>
- interface. This factory should return instances
- <code>MyLoggerAdapter</code>. Let <code>MyLoggerFactory</code>
- be the name of your factory class.
- </p>
-
- <p>Once you have the adapter, namely
- <code>MyLoggerAdapter</code>, and a factory, namely
- <code>MyLoggerFactory</code>, the last remaining step is to
- modify the <code>StaticLoggerBinder</code> class so that it
- returns an new instance of <code>MyLoggerFactory</code>. You
- will also need to modify the
- <code>loggerFactoryClassStr</code> variable.
- </p>
-
- <p>For Marker or MDC support, you could use the one of the
- existing NOP implementations.
- </p>
-
- <p>In summary, to create an SLF4J binding for your logging
- system, follow these steps:</p>
-
- <ol>
- <li>start with a copy of an existing module,</li>
- <li>create an adapter between your logging system and
- <code>org.slf4j.Logger</code> interface
- </li>
- <li>create a factory for the adapter created in the previous step,</li>
- <li>modify <code>StaticLoggerBinder</code> class to use the
- factory you created in the previous step</li>
- </ol>
-
-
- </dd>
-
- <!-- ============================================================= -->
-
- <dt class="doAnchor" name="marker_interface">How can my logging
- system add support for the <code>Marker</code> interface?
- </dt>
- <dd>
-
- <p>Markers constitute a revolutionary concept which is
- supported by logback but not other existing logging
- systems. Consequently, SLF4J conforming logging systems are
- allowed to ignore marker data passed by the user.
- </p>
-
- <p>However, even though marker data may be ignored, the user
- must still be allowed to specify marker data. Otherwise, users
- would not be able to switch between logging systems that
- support markers and those that do not.
- </p>
-
- <p>The <code>MarkerIgnoringBase</code> class can serve as a
- base for adapters or native implementations of logging
- systems lacking marker support. In
- <code>MarkerIgnoringBase</code>, methods taking marker data
- simply invoke the corresponding method without the Marker
- argument, discarding any Marker data passed as
- argument. Your SLF4J adapters can extend
- <code>MarkerIgnoringBase</code> to quickly implement the
- methods in <code>org.slf4j.Logger</code> which take a
- <code>Marker</code> as the first argument.
- </p>
-
-
- </dd>
-
- <!-- ============================================================= -->
-
- <dt class="doAnchor" name="version_checks">How does SLF4J's
- version check mechanism work?
- </dt>
-
- <dd>
- <p>The version check performed by SLF4J API during its
- initialization is an <em>elective</em> process. Conforming SLF4J
- implementations may choose <em>not</em> to participate, in which
- case, no version check will be performed.
- </p>
-
- <p>However, if an SLF4J implementation decides to participate,
- than it needs to declare a variable called
- REQUESTED_API_VERSION within its copy of the
- <code>StaticLoggerBinder</code> class. The value of this
- variable should be equal to the version of the slf4j-api.jar
- it is compiled with. If the implementation is upgraded to a
- newer version of slf4j-api, than you also need to update the
- value of REQUESTED_API_VERSION.
- </p>
-
- <p>For each version, SLF4J API maintains a list of compatible
- versions. SLF4J will emit a version mismatch warning only if
- the requested version is not found in the compatibility
- list. So even if your SLF4J binding has a different release
- schedule than SLF4J, assuming you update the SLF4J version you
- use every 6 to 12 months, you can still participate in the
- version check without incurring a mismatch warning. For
- example, logback has a different release schedule but still
- participates in version checks.</p>
-
- <p><b>As of SLF4J 1.5.5</b>, all bindings shipped within the
- SLF4J distribution, e.g. slf4j-log4j12, slf4j-simple and
- slf4j-jdk14, declare the REQUESTED_API_VERSION field with a
- value equal to their SLF4J version. It follows that, for example
- if slf4j-simple-1.5.8.jar is mixed with slf4j-api-1.6.0.jar,
- given that 1.5.8 is not on the compatibility list of SLF4J
- version 1.6.x, a version mismatch warning will be issued.
- </p>
-
- <p>Note that SLF4J versions prior to 1.5.5 did not have a
- version check mechanism. Only slf4j-api-1.5.5.jar and later can
- emit version mismatch warnings.
- </p>
-
-
- </dd>
-
- </dl>
-
- <h2>General questions about logging</h2>
-
-
-
- <dl>
-
- <!-- ============================================================= -->
- <dt class="doAnchor" name="declared_static">Should Logger members
- of a class be declared as static?
- </dt>
- <dd>
-
- <p>We <code>used</code> to recommend that loggers members be
- declared as instance variables instead of static. After further
- analysis, <b>we no longer recommend one approach over the
- other.</b>
- </p>
-
- <p>Here is a summary of the pros and cons of each approach.
- </p>
-
- <table class="bodyTable">
- <tr valign="top">
- <th width="50%">Advantages for declaring loggers as static</th>
- <th width="50%">Disadvantages for declaring loggers as static</th>
- </tr>
- <tr valign="top" class="alt">
- <td>
- <ol>
- <li>common and well-established idiom</li>
- <li>less CPU overhead: loggers are retrieved and
- assigned only once, at hosting class
- initialization</li>
- <li>less memory overhead: logger declaration will
- consume one reference per class</li>
- </ol>
- </td>
-
- <td> <!-- static con -->
- <ol>
- <li>For libraries shared between applications, not
- possible to take advantage of repository selectors. It
- should be noted that if the SLF4J binding and the
- underlying API ships with each application (not shared
- between applications), then each application will still
- have its own logging environment.
- </li>
- <li>not IOC-friendly</li>
- </ol>
- </td>
- </tr>
-
- <tr>
- <th width="50%">Advantages for declaring loggers as instance variables</th>
- <th width="50%">Disadvantages for declaring loggers as
- instance variables</th>
- </tr>
-
- <tr class="alt" valign="top">
- <td> <!-- instance pros -->
- <ol>
- <li>Possible to take advantage of repository selectors
- even for libraries shared between applications. However,
- repository selectors only work if the underlying logging
- system is logback-classic. Repository selectors do not
- work for the SLF4J+log4j combination.
- </li>
- <li>IOC-friendly</li>
- </ol>
- </td>
-
- <td> <!-- instance cons -->
- <ol>
- <li>Less common idiom than declaring loggers as static
- variables</li>
-
- <li>higher CPU overhead: loggers are retrieved and
- assigned for each instance of the hosting class</li>
-
- <li>higher memory overhead: logger declaration will
- consume one reference per instance of the hosting class</li>
- </ol>
- </td>
- </tr>
- </table>
-
-
- <h3>Explanation</h3>
-
- <p>Static logger members cost a single variable reference for
- all instances of the class whereas an instance logger member
- will cost a variable reference for every instance of the
- class. For simple classes instantiated thousands of times
- there might be a noticeable difference.
- </p>
-
- <p>However, more recent logging systems, e.g log4j or logback,
- support a distinct logger context for each application running
- in the application server. Thus, even if a single copy of
- <em>log4j.jar</em> or <em>logback-classic.jar</em> is deployed
- in the server, the logging system will be able to differentiate
- between applications and offer a distinct logging environment
- for each application.
- </p>
-
- <p>More specifically, each time a logger is retrieved by
- invoking <code>LoggerFactory.getLogger()</code> method, the
- underlying logging system will return an instance appropriate
- for the current application. Please note that within the
- <em>same</em> application retrieving a logger by a given name
- will always return the same logger. For a given name, a
- different logger will be returned only for different
- applications.
- </p>
-
- <p>If the logger is static, then it will only be retrieved once
- when the hosting class is loaded into memory. If the hosting
- class is used in only in one application, there is not much to
- be concerned about. However, if the hosting class is shared
- between several applications, then all instances of the shared
- class will log into the context of the application which
- happened to first load the shared class into memory - hardly the
- behavior expected by the user.
- </p>
-
- <p>Unfortunately, for non-native implementations of the SLF4J
- API, namely with slf4j-log4j12, log4j's repository selector will
- not be able to do its job properly because slf4j-log4j12, a
- non-native SLF4J binding, will store logger instances in a map,
- short-circuiting context-dependent logger retrieval. For native
- SLF4J implementations, such as logback-classic, repository
- selectors will work as expected.
- </p>
-
- <p>The Apache Commons wiki contains an <a
- href="http://wiki.apache.org/jakarta-commons/Logging/StaticLog">informative
- article</a> covering the same question.</p>
-
- <p><b>Logger serialization</b></p>
-
- <p>Contrary to static variables, instance variables are
- serialized by default. As of SLF4J version 1.5.3, logger
- instances survive serialization. Thus, serialization of the host
- class no longer requires any special action, even when loggers
- are declared as instance variables. In previous versions, logger
- instances needed to be declared as <code>transient</code> in the
- host class. </p>
-
- <p><b>Summary</b></p>
-
- <p>In summary, declaring logger members as static variables
- requires less CPU time and have a slightly smaller memory
- footprint. On the other hand, declaring logger members as
- instance variables requires more CPU time and have a slightly
- higher memory overhead. However, instance variables make it
- possible to create a distinct logger environment for each
- application, even for loggers declared in shared
- libraries. Perhaps more important than previously mentioned
- considerations, instance variables are IOC-friendly whereas
- static variables are not.
- </p>
-
- <p>See also <a
- href="http://wiki.apache.org/jakarta-commons/Logging/StaticLog">related
- discussion</a> in the commons-logging wiki.
- </p>
-
- </dd>
- </dl>
-
- <!-- ============================================================= -->
- <dl>
- <dt class="doAnchor" name="declaration_pattern">Is there a
- recommended idiom for declaring a logger in a class?
- </dt>
-
- <dd>
- <p>The following is the recommended logger declaration
- idiom. For reasons <a href="#declared_static">explained
- above</a>, it is left to the user to determine whether loggers
- are declared as static variables or not.</p>
-
- <pre class="prettyprint source">package some.package;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class MyClass {
- <b>final (static) Logger logger = LoggerFactory.getLogger(MyClass.class);</b>
- ... etc
-}</pre>
-
- <p>Unfortunately, give that the name of the hosting class is
- part of the logger declaration, the above logger declaration
- idiom is not is <em>not</em> resistant to cut-and-pasting
- between classes.
- </p>
- </dd>
- </dl>
-
- <script src="templates/footer.js" type="text/javascript"></script>
-</div>
-</body>
-</html>
diff --git a/slf4j-site/src/site/pages/inde_base.html b/slf4j-site/src/site/pages/inde_base.html
deleted file mode 100644
index 2addd7b4..00000000
--- a/slf4j-site/src/site/pages/inde_base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
-<title>SLF4J</title>
-<link rel="stylesheet" type="text/css" media="screen" href="css/site.css" />
-</head>
-<body>
- <script>
-prefix='';
-</script>
-
-<script src="templates/header.js"></script>
-<div id="left">
- <script src="templates/left.js"></script>
-</div>
-<div id="right">
- <script src="templates/right.js"></script>
-</div>
-<div id="content">
-
-
-
-
-
-</div>
-</body>
-</html>
diff --git a/slf4j-site/src/site/pages/index.html b/slf4j-site/src/site/pages/index.html
deleted file mode 100755
index b684a9fd..00000000
--- a/slf4j-site/src/site/pages/index.html
+++ /dev/null
@@ -1,170 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <title>SLF4J</title>
- <link rel="stylesheet" type="text/css" media="screen" href="css/site.css" />
- </head>
- <body>
-
- <script type="text/javascript">prefix='';</script>
-
- <script src="templates/header.js" type="text/javascript"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="templates/left.js" type="text/javascript"></script>
- </div>
- <!--
- <div id="right">
- <script src="templates/right.js" type="text/javascript"></script>
- </div>
- -->
- <div id="content">
-
-
- <h1>Simple Logging Facade for Java (SLF4J)</h1>
-
- <p>The Simple Logging Facade for Java (SLF4J) serves as a simple
- facade or abstraction for various logging frameworks
- (e.g. java.util.logging, logback, log4j) allowing the end user to
- plug in the desired logging framework at <em>deployment</em>
- time. </p>
-
- <p>Before you start using SLF4J, we highly recommend that you read
- the two-page <a href="manual.html">SLF4J user manual</a>.
- </p>
-
- <p>Note that SLF4J-enabling your library implies the addition of
- only a single mandatory dependency, namely <em>slf4j-api.jar</em>.
- If no binding is found on the class path, then SLF4J will default to
- a no-operation implementation.
- </p>
-
- <p>In case you wish to migrate your Java source files to SLF4J,
- consider our <a href="migrator.html">migrator tool</a> which can
- migrate your project to use the SLF4J API in just a few minutes.</p>
-
- <p>In case an externally-maintained component you depend on uses a
- logging API other than SLF4J, such as commons logging, log4j or
- java.util.logging, have a look at SLF4J's binary-support for <a
- href="legacy.html">legacy APIs</a>.
- </p>
-
- <h3>Projects depending on SLF4J</h3>
-
- <p>Here is a non-exhaustive list of projects known to depend on
- SLF4J, in alphabetical order:
- </p>
-
- <table border="0">
- <tr>
- <td valign="top">
- <ul>
- <li><a href="http://activemq.apache.org/">Apache ActiveMQ</a></li>
- <li><a href="http://arhiva.apache.org/">Apache Archiva</a></li>
- <li><a href="http://camel.apache.org/">Apache Camel</a></li>
- <li><a href="http://directory.apache.org/">Apache Directory</a></li>
- <li><a href="http://mina.apache.org/ftpserver/">Apache FTPServer</a></li>
- <li><a href="http://geronimo.apache.org/">Apache Geronimo</a></li>
- <li><a href="http://incubator.apache.org/graffito/">Apache Graffito</a></li>
- <li><a href="http://jackrabbit.apache.org/">Apache Jackrabbit</a></li>
- <li><a href="http://mina.apache.org/">Apache Mina</a></li>
- <li><a href="http://cwiki.apache.org/qpid/">Apache Qpid</a></li>
- <li><a href="http://servicemix.apache.org/">Apache ServiceMix</a></li>
- </ul>
- </td>
-
- <td valign="top">
- <ul>
- <li><a href="http://incubator.apache.org/sling/site/index.html">Apache Sling</a></li>
- <li><a href="http://lucene.apache.org/solr/">Apache Solr</a></li>
- <li><a href="http://tapestry.apache.org/">Apache Tapestry</a></li>
- <li><a href="http://incubator.apache.org/wicket/">Apache Wicket</a></li>
- <li><a href="http://aperture.sourceforge.net/">Aperture</a></li>
- <li><a href="http://apogee.nuxeo.org/">Apogee</a></li>
- <li><a href="http://www.jfrog.org/sites/artifactory/latest/">Artifactory</a></li>
- <li><a href="http://docs.safehaus.org/display/ASYNCWEB/Home">AsyncWeb</a></li>
- <li><a href="http://www.bitronix.be/">Bitronix</a></li>
- <li><a href="http://www.dbunit.org/">DbUnit</a></li>
- <li><a href="http://displaytag.sourceforge.net/11/">Display tag</a></li>
-
- </ul>
-
- </td>
-
- <td valign="top">
- <ul>
- <li><a href="http://ehcache.org/">Ehcache</a></li>
- <li><a href="http://groovy.codehaus.org/GMaven">GMaven</a></li>
- <li><a href="http://www.gradle.org/">Gradle</a></li>
- <li><a href="http://www.icegreen.com/greenmail/">GreenMail</a></li>
- <li><a href="http://gumtree.codehaus.org/">GumTree</a></li>
- <li><a href="http://www.h2database.com/">H2 Database</a></li>
- <li><a href="http://ha-jdbc.sourceforge.net/">HA-JDBC</a></li>
- <li><a href="http://www.hibernate.org/">Hibernate</a></li>
- <li><a href="http://code.google.com/p/igenko/">Igenko</a></li>
- <li><a href="http://jabsorb.org/">Jabsorb</a></li>
- <li><a href="http://jetty.mortbay.org/">Jetty v6</a></li>
- </ul>
- </td>
- </tr>
-
- <tr>
-
- <td valign="top">
- <ul>
- <li><a href="http://www.topmind.biz/html/index.php">jLynx</a></li>
- <li><a href="http://code.google.com/p/jmesa/">JMesa</a></li>
- <li><a href="http://www.artofsolving.com/opensource/jodconverter">JODConverter</a></li>
- <li><a href="http://jtrac.info/dependencies.html">JTrac</a></li>
- <li><a href="http://jwebunit.sourceforge.net/2.x/">JWebUnit 2.x</a></li>
- <li><a href="http://www.jquantlib.org/index.php/Main_Page">JQuantLib</a></li>
- <li><a href="http://www.liferay.com/web/guest/home">LIFERAY</a></li>
- <li><a href="http://liftweb.net/">Lift</a></li>
- <li><a href="http://log4jdbc.sourceforge.net">log4jdbc</a></li>
- <li><a href="http://www.magnolia.info/en/magnolia.html">Magnolia</a></li>
- <li><a href="http://mrcp4j.sourceforge.net/">MRCP4J</a></li>
- </ul>
- </td>
-
-
- <td valign="top">
- <ul>
- <li><a href="http://www.mindquarry.com/">Mindquarry</a></li>
- <li><a href="http://mugshot.org/">Mugshot</a></li>
- <li><a href="http://mule.codehaus.org/display/MULE/Home">Mule</a></li>
- <li><a href="http://nexus.sonatype.org/repository.html">Nexus</a></li>
- <li><a href="http://www.novocode.com/naf/">Novocode</a></li>
- <li><a href="http://www.unidata.ucar.edu/software/netcdf-java/">NetCDF</a></li>
- <li><a href="http://code.google.com/p/openmeetings/">OpenMeetings</a></li>
- <li><a href="http://www.openrdf.org/">OpenRDF</a></li>
- <li><a href="http://docs.safehaus.org/display/PENROSE/Home">Penrose</a></li>
- <li><a href="http://pzfilereader.sourceforge.net/">PZFileReader</a></li>
- <li><a href="http://www.quartz-scheduler.org/">Quartz Scheduler</a></li>
- </ul>
- </td>
-
- <td valign="top">
- <ul>
- <li><a href="http://www.quickfixj.org/">QuickFIX/J</a></li>
- <li><a href="http://sonar.codehaus.org/">Sonar</a></li>
- <li><a href="http://smsj.sourceforge.net/dependencies.html">SMSJ</a></li>
- <li><a href="http://www.springframework.org/osgi">Spring-OSGi</a></li>
- <li><a href="http://static.springsource.org/s2-dmserver/2.0.x/user-guide/htmlsingle/user-guide.html">SpringSource dm Server&#8482;</a></li>
- <li><a href="http://streambase.com/">StreamBase</a></li>
- <li><a href="http://www.timefinder.de/">TimeFinder</a></li>
- <li><a href="http://www.wtfigo.org/index.html">WTFIGO</a></li>
- <li><a href="http://yaslibrary.sourceforge.net/index.shtml">YASL</a></li>
- <li><a href="http://xooctory.xoocode.org/">Xooctory</a></li>
- <li><a href="http://xwiki.org">XWiki</a></li>
- </ul>
- </td>
- </tr>
- </table>
-
- <script src="templates/footer.js" type="text/javascript"></script>
-</div>
-</body>
-</html>
diff --git a/slf4j-site/src/site/pages/js/decorator.js b/slf4j-site/src/site/pages/js/decorator.js
deleted file mode 100644
index 362712eb..00000000
--- a/slf4j-site/src/site/pages/js/decorator.js
+++ /dev/null
@@ -1,101 +0,0 @@
-
-
-// <h3><a name="LoggerContext" href="#LoggerContext"><span
-// class="anchor"/></a>Logger context</h3>
-
-function decorate() {
- var anchor = findAnchorInURL(document.URL);
- decoratePropertiesInTables(anchor);
- decorateDoAnchor(anchor);
- decorateConversionWordInTables(anchor);
-}
-
-// ----------------------------------------------
-function findAnchorInURL(url) {
-
- if(url == null) return null
- var index = url.lastIndexOf("#");
- if(index != -1 && (index+1) < url.length)
- return url.substr(index+1);
- else
- return null;
-}
-
-// ----------------------------------------------
-function decoratePropertiesInTables(anchor) {
-
- //if(1==1) return;
- var elems = $('tr td:first-child span.prop');
-
- for(var i = 0; i < elems.length; i++) {
- var e = elems[i];
- var p = e.parentNode;
- if(p == null) continue;
-
- var tmpHTML = p.innerHTML;
- var propName = e.innerHTML;
- var nameAttr = $(e).attr('name')
-
- if(nameAttr == null) {
- var containerAttr = $(e).attr('container')
- if(containerAttr != null)
- nameAttr = containerAttr+capitaliseFirstLetter(propName);
- else
- nameAttr = propName;
- }
-
- p.innerHTML = "<a name='" + nameAttr + "' href='#" + nameAttr +
- "'><span class='anchor'/></a><b>" +tmpHTML +"</b>";
- scrollIfMatch(p, nameAttr, anchor);
- } // for
-}
-
-function decorateConversionWordInTables(anchor) {
- var elems = $('tr td.word');
- for(var i = 0; i < elems.length; i++) {
- var e = elems[i];
- var tmpHTML = e.innerHTML;
- var nameAttr = $(e).attr('name')
- if(nameAttr == null)
- continue;
- e.innerHTML = "<a name='" + nameAttr + "' href='#" + nameAttr +
- "'><span class='anchor'/></a>" +tmpHTML;
- scrollIfMatch(e, nameAttr, anchor);
- }
-}
-
-
-function decorateDoAnchor(anchor) {
- var elems = $('.doAnchor');
- for(var i = 0; i < elems.length; i++) {
- var e = elems[i];
- var tmpHTML = e.innerHTML;
- var nameAttr = $(e).attr('name')
- if(nameAttr == null) {
- nameAttr = camelCase($.trim(tmpHTML))
- }
- e.innerHTML = "<a name='" + nameAttr + "' href='#" + nameAttr +
- "'><span class='anchor'/></a>" +tmpHTML;
- scrollIfMatch(e, nameAttr, anchor);
- }
-}
-
-function scrollIfMatch(element, nameAttr, anchor) {
- if(anchor != null && nameAttr.toString() == anchor)
- element.scrollIntoView(true);
-
-
-}
-
-function capitaliseFirstLetter(str) {
- return str.charAt(0).toUpperCase() + str.slice(1);
-}
-
-
-function camelCase(str) {
- var res = str.trim().replace(/\s\w/g, function(match) {
- return match.trim().toUpperCase();
- });
- return res;
-}
-
diff --git a/slf4j-site/src/site/pages/js/jquery-min.js b/slf4j-site/src/site/pages/js/jquery-min.js
deleted file mode 100644
index 16ad06c5..00000000
--- a/slf4j-site/src/site/pages/js/jquery-min.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/*! jQuery v1.7.2 jquery.com | jquery.org/license */
-(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"<!doctype html>":"")+"<html><body>"),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function ca(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function b_(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bD.test(a)?d(a,e):b_(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&f.type(b)==="object")for(var e in b)b_(a+"["+e+"]",b[e],c,d);else d(a,b)}function b$(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function bZ(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bS,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bZ(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bZ(a,c,d,e,"*",g));return l}function bY(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bO),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bB(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?1:0,g=4;if(d>0){if(c!=="border")for(;e<g;e+=2)c||(d-=parseFloat(f.css(a,"padding"+bx[e]))||0),c==="margin"?d+=parseFloat(f.css(a,c+bx[e]))||0:d-=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0;return d+"px"}d=by(a,b);if(d<0||d==null)d=a.style[b];if(bt.test(d))return d;d=parseFloat(d)||0;if(c)for(;e<g;e+=2)d+=parseFloat(f.css(a,"padding"+bx[e]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+bx[e]))||0);return d+"px"}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;b.nodeType===1&&(b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?b.outerHTML=a.outerHTML:c!=="input"||a.type!=="checkbox"&&a.type!=="radio"?c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text):(a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value)),b.removeAttribute(f.expando),b.removeAttribute("_submit_attached"),b.removeAttribute("_change_attached"))}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c,i[c][d])}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){if(typeof c!="string"||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h,i){var j,k=d==null,l=0,m=a.length;if(d&&typeof d=="object"){for(l in d)e.access(a,c,l,d[l],1,h,f);g=1}else if(f!==b){j=i===b&&e.isFunction(f),k&&(j?(j=c,c=function(a,b,c){return j.call(e(a),c)}):(c.call(a,f),c=null));if(c)for(;l<m;l++)c(a[l],d,j?f.call(a[l],l,c(a[l],d)):f,i);g=1}return g?a:k?c.call(a):m?c(a[0],d):h},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m,n=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?n(g):h==="function"&&(!a.unique||!p.has(g))&&c.push(g)},o=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,j=!0,m=k||0,k=0,l=c.length;for(;c&&m<l;m++)if(c[m].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}j=!1,c&&(a.once?e===!0?p.disable():c=[]:d&&d.length&&(e=d.shift(),p.fireWith(e[0],e[1])))},p={add:function(){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){j&&f<=l&&(l--,f<=m&&m--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&p.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(j?a.once||d.push([b,c]):(!a.once||!e)&&o(b,c));return this},fire:function(){p.fireWith(this,arguments);return this},fired:function(){return!!i}};return p};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p=c.createElement("div"),q=c.documentElement;p.setAttribute("className","t"),p.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name","t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="<div "+n+"display:block;'><div style='"+t+"0;display:block;overflow:hidden;'></div></div>"+"<table "+n+"' cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="<table><tr><td style='"+t+"0;display:none'></td><td>t</td></tr></table>",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="none",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="<div style='width:5px;'></div>",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g.style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position="relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h,i,j=this[0],k=0,m=null;if(a===b){if(this.length){m=f.data(j);if(j.nodeType===1&&!f._data(j,"parsedAttrs")){g=j.attributes;for(i=g.length;k<i;k++)h=g[k].name,h.indexOf("data-")===0&&(h=f.camelCase(h.substring(5)),l(j,h,m[h]));f._data(j,"parsedAttrs",!0)}}return m}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!";return f.access(this,function(c){if(c===b){m=this.triggerHandler("getData"+e,[d[0]]),m===b&&j&&(m=f.data(j,a),m=l(j,a,m));return m===b&&d[1]?this.data(d[0]):m}d[1]=c,this.each(function(){var b=f(this);b.triggerHandler("setData"+e,d),f.data(this,a,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length<d)return f.queue(this[0],a);return c===b?this:this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise(c)}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,f.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i<g;i++)e=d[i],e&&(c=f.propFix[e]||e,h=u.test(e),h||f.attr(a,e,""),a.removeAttribute(v?e:c),h&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0,coords:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/(?:^|\s)hover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(
-a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:g&&G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=f.event.special[c.type]||{},j=[],k,l,m,n,o,p,q,r,s,t,u;g[0]=c,c.delegateTarget=this;if(!i.preDispatch||i.preDispatch.call(this,c)!==!1){if(e&&(!c.button||c.type!=="click")){n=f(this),n.context=this.ownerDocument||this;for(m=c.target;m!=this;m=m.parentNode||this)if(m.disabled!==!0){p={},r=[],n[0]=m;for(k=0;k<e;k++)s=d[k],t=s.selector,p[t]===b&&(p[t]=s.quick?H(m,s.quick):n.is(t)),p[t]&&r.push(s);r.length&&j.push({elem:m,matches:r})}}d.length>e&&j.push({elem:this,matches:d.slice(e)});for(k=0;k<j.length&&!c.isPropagationStopped();k++){q=j[k],c.currentTarget=q.elem;for(l=0;l<q.matches.length&&!c.isImmediatePropagationStopped();l++){s=q.matches[l];if(h||!c.namespace&&!s.namespace||c.namespace_re&&c.namespace_re.test(s.namespace))c.data=s.data,c.handleObj=s,o=((f.event.special[s.origType]||{}).handle||s.handler).apply(q.elem,g),o!==b&&(c.result=o,o===!1&&(c.preventDefault(),c.stopPropagation()))}}i.postDispatch&&i.postDispatch.call(this,c);return c.result}},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),d._submit_attached=!0)})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=d||c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9||d===11){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));o.match.globalPOS=p;var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.globalPOS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")[\\s/>]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f
-.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(f.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(g){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,function(a,b){b.src?f.ajax({type:"GET",global:!1,url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g,h,i,j=[];b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1></$2>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]==="<table>"&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0]&&typeof (u=l.length)=="number")for(i=0;i<u;i++)bn(l[i]);else bn(l);l.nodeType?j.push(l):j=f.merge(j,l)}if(d){g=function(a){return!a.type||be.test(a.type)};for(k=0;j[k];k++){h=j[k];if(e&&f.nodeName(h,"script")&&(!h.type||be.test(h.type)))e.push(h.parentNode?h.parentNode.removeChild(h):h);else{if(h.nodeType===1){var v=f.grep(h.getElementsByTagName("script"),g);j.splice.apply(j,[k+1,0].concat(v))}d.appendChild(h)}}}return j},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bp=/alpha\([^)]*\)/i,bq=/opacity=([^)]*)/,br=/([A-Z]|^ms)/g,bs=/^[\-+]?(?:\d*\.)?\d+$/i,bt=/^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,bu=/^([\-+])=([\-+.\de]+)/,bv=/^margin/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Top","Right","Bottom","Left"],by,bz,bA;f.fn.css=function(a,c){return f.access(this,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)},a,c,arguments.length>1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bu.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bW},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bY(bS),ajaxTransport:bY(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?ca(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cb(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bW+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bZ(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application\/x\-www\-form\-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n);try{m.text=h.responseText}catch(a){}try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),(e===""&&f.css(d,"display")==="none"||!f.contains(d.ownerDocument.documentElement,d))&&f._data(d,"olddisplay",cu(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(ct("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(ct("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o,p,q;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]);if((k=f.cssHooks[g])&&"expand"in k){l=k.expand(a[g]),delete a[g];for(i in l)i in a||(a[i]=l[i])}}for(g in a){h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cu(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cm.test(h)?(q=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),q?(f._data(this,"toggle"+i,q==="show"?"hide":"show"),j[q]()):j[h]()):(m=cn.exec(h),n=j.cur(),m?(o=parseFloat(m[2]),p=m[3]||(f.cssNumber[i]?"":"px"),p!=="px"&&(f.style(this,i,(o||1)+p),n=(o||1)/j.cur()*n,f.style(this,i,n+p)),m[1]&&(o=(m[1]==="-="?-1:1)*o+n),j.custom(n,o,p)):j.custom(n,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:ct("show",1),slideUp:ct("hide",1),slideToggle:ct("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a){return a},swing:function(a){return-Math.cos(a*Math.PI)/2+.5}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cq||cr(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){f._data(e.elem,"fxshow"+e.prop)===b&&(e.options.hide?f._data(e.elem,"fxshow"+e.prop,e.start):e.options.show&&f._data(e.elem,"fxshow"+e.prop,e.end))},h()&&f.timers.push(h)&&!co&&(co=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cq||cr(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(co),co=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(cp.concat.apply([],cp),function(a,b){b.indexOf("margin")&&(f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)})}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cv,cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?cv=function(a,b,c,d){try{d=a.getBoundingClientRect()}catch(e){}if(!d||!f.contains(c,a))return d?{top:d.top,left:d.left}:{top:0,left:0};var g=b.body,h=cy(b),i=c.clientTop||g.clientTop||0,j=c.clientLeft||g.clientLeft||0,k=h.pageYOffset||f.support.boxModel&&c.scrollTop||g.scrollTop,l=h.pageXOffset||f.support.boxModel&&c.scrollLeft||g.scrollLeft,m=d.top+k-i,n=d.left+l-j;return{top:m,left:n}}:cv=function(a,b,c){var d,e=a.offsetParent,g=a,h=b.body,i=b.defaultView,j=i?i.getComputedStyle(a,null):a.currentStyle,k=a.offsetTop,l=a.offsetLeft;while((a=a.parentNode)&&a!==h&&a!==c){if(f.support.fixedPosition&&j.position==="fixed")break;d=i?i.getComputedStyle(a,null):a.currentStyle,k-=a.scrollTop,l-=a.scrollLeft,a===e&&(k+=a.offsetTop,l+=a.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(a.nodeName))&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),g=e,e=a.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&d.overflow!=="visible"&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),j=d}if(j.position==="relative"||j.position==="static")k+=h.offsetTop,l+=h.offsetLeft;f.support.fixedPosition&&j.position==="fixed"&&(k+=Math.max(c.scrollTop,h.scrollTop),l+=Math.max(c.scrollLeft,h.scrollLeft));return{top:k,left:l}},f.fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){f.offset.setOffset(this,a,b)});var c=this[0],d=c&&c.ownerDocument;if(!d)return null;if(c===d.body)return f.offset.bodyOffset(c);return cv(c,d,d.documentElement)},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo(d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file
diff --git a/slf4j-site/src/site/pages/js/prettify.js b/slf4j-site/src/site/pages/js/prettify.js
deleted file mode 100644
index 8fc4c933..00000000
--- a/slf4j-site/src/site/pages/js/prettify.js
+++ /dev/null
@@ -1,23 +0,0 @@
-function H(){var x=navigator&&navigator.userAgent&&/\bMSIE 6\./.test(navigator.userAgent);H=function(){return x};return x}(function(){function x(b){b=b.split(/ /g);var a={};for(var c=b.length;--c>=0;){var d=b[c];if(d)a[d]=null}return a}var y="break continue do else for if return while ",U=y+"auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile ",D=U+"catch class delete false import new operator private protected public this throw true try ",
-I=D+"alignof align_union asm axiom bool concept concept_map const_cast constexpr decltype dynamic_cast explicit export friend inline late_check mutable namespace nullptr reinterpret_cast static_assert static_cast template typeid typename typeof using virtual wchar_t where ",J=D+"boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient ",V=J+"as base by checked decimal delegate descending event fixed foreach from group implicit in interface internal into is lock object out override orderby params readonly ref sbyte sealed stackalloc string select uint ulong unchecked unsafe ushort var ",
-K=D+"debugger eval export function get null set undefined var with Infinity NaN ",L="caller delete die do dump elsif eval exit foreach for goto if import last local my next no our print package redo require sub undef unless until use wantarray while BEGIN END ",M=y+"and as assert class def del elif except exec finally from global import in is lambda nonlocal not or pass print raise try with yield False True None ",N=y+"alias and begin case class def defined elsif end ensure false in module next nil not or redo rescue retry self super then true undef unless until when yield BEGIN END ",
-O=y+"case done elif esac eval fi function in local set then until ",W=I+V+K+L+M+N+O;function X(b){return b>="a"&&b<="z"||b>="A"&&b<="Z"}function u(b,a,c,d){b.unshift(c,d||0);try{a.splice.apply(a,b)}finally{b.splice(0,2)}}var Y=(function(){var b=["!","!=","!==","#","%","%=","&","&&","&&=","&=","(","*","*=","+=",",","-=","->","/","/=",":","::",";","<","<<","<<=","<=","=","==","===",">",">=",">>",">>=",">>>",">>>=","?","@","[","^","^=","^^","^^=","{","|","|=","||","||=","~","break","case","continue",
-"delete","do","else","finally","instanceof","return","throw","try","typeof"],a="(?:(?:(?:^|[^0-9.])\\.{1,3})|(?:(?:^|[^\\+])\\+)|(?:(?:^|[^\\-])-)";for(var c=0;c<b.length;++c){var d=b[c];a+=X(d.charAt(0))?"|\\b"+d:"|"+d.replace(/([^=<>:&])/g,"\\$1")}a+="|^)\\s*$";return new RegExp(a)})(),P=/&/g,Q=/</g,R=/>/g,Z=/\"/g;function $(b){return b.replace(P,"&amp;").replace(Q,"&lt;").replace(R,"&gt;").replace(Z,"&quot;")}function E(b){return b.replace(P,"&amp;").replace(Q,"&lt;").replace(R,"&gt;")}var aa=
-/&lt;/g,ba=/&gt;/g,ca=/&apos;/g,da=/&quot;/g,ea=/&amp;/g,fa=/&nbsp;/g;function ga(b){var a=b.indexOf("&");if(a<0)return b;for(--a;(a=b.indexOf("&#",a+1))>=0;){var c=b.indexOf(";",a);if(c>=0){var d=b.substring(a+3,c),g=10;if(d&&d.charAt(0)==="x"){d=d.substring(1);g=16}var e=parseInt(d,g);if(!isNaN(e))b=b.substring(0,a)+String.fromCharCode(e)+b.substring(c+1)}}return b.replace(aa,"<").replace(ba,">").replace(ca,"'").replace(da,'"').replace(ea,"&").replace(fa," ")}function S(b){return"XMP"===b.tagName}
-function z(b,a){switch(b.nodeType){case 1:var c=b.tagName.toLowerCase();a.push("<",c);for(var d=0;d<b.attributes.length;++d){var g=b.attributes[d];if(!g.specified)continue;a.push(" ");z(g,a)}a.push(">");for(var e=b.firstChild;e;e=e.nextSibling)z(e,a);if(b.firstChild||!/^(?:br|link|img)$/.test(c))a.push("</",c,">");break;case 2:a.push(b.name.toLowerCase(),'="',$(b.value),'"');break;case 3:case 4:a.push(E(b.nodeValue));break}}var F=null;function ha(b){if(null===F){var a=document.createElement("PRE");
-a.appendChild(document.createTextNode('<!DOCTYPE foo PUBLIC "foo bar">\n<foo />'));F=!/</.test(a.innerHTML)}if(F){var c=b.innerHTML;if(S(b))c=E(c);return c}var d=[];for(var g=b.firstChild;g;g=g.nextSibling)z(g,d);return d.join("")}function ia(b){var a=0;return function(c){var d=null,g=0;for(var e=0,h=c.length;e<h;++e){var f=c.charAt(e);switch(f){case "\t":if(!d)d=[];d.push(c.substring(g,e));var i=b-a%b;a+=i;for(;i>=0;i-=" ".length)d.push(" ".substring(0,i));g=e+1;break;
-case "\n":a=0;break;default:++a}}if(!d)return c;d.push(c.substring(g));return d.join("")}}var ja=/(?:[^<]+|<!--[\s\S]*?--\>|<!\[CDATA\[([\s\S]*?)\]\]>|<\/?[a-zA-Z][^>]*>|<)/g,ka=/^<!--/,la=/^<\[CDATA\[/,ma=/^<br\b/i;function na(b){var a=b.match(ja),c=[],d=0,g=[];if(a)for(var e=0,h=a.length;e<h;++e){var f=a[e];if(f.length>1&&f.charAt(0)==="<"){if(ka.test(f))continue;if(la.test(f)){c.push(f.substring(9,f.length-3));d+=f.length-12}else if(ma.test(f)){c.push("\n");++d}else g.push(d,f)}else{var i=ga(f);
-c.push(i);d+=i.length}}return{source:c.join(""),tags:g}}function v(b,a){var c={};(function(){var g=b.concat(a);for(var e=g.length;--e>=0;){var h=g[e],f=h[3];if(f)for(var i=f.length;--i>=0;)c[f.charAt(i)]=h}})();var d=a.length;return function(g,e){e=e||0;var h=[e,"pln"],f="",i=0,j=g;while(j.length){var o,m=null,k,l=c[j.charAt(0)];if(l){k=j.match(l[1]);m=k[0];o=l[0]}else{for(var n=0;n<d;++n){l=a[n];var p=l[2];if(p&&!p.test(f))continue;k=j.match(l[1]);if(k){m=k[0];o=l[0];break}}if(!m){o="pln";m=j.substring(0,
-1)}}h.push(e+i,o);i+=m.length;j=j.substring(m.length);if(o!=="com"&&/\S/.test(m))f=m}return h}}var oa=v([],[["pln",/^[^<]+/,null],["dec",/^<!\w[^>]*(?:>|$)/,null],["com",/^<!--[\s\S]*?(?:--\>|$)/,null],["src",/^<\?[\s\S]*?(?:\?>|$)/,null],["src",/^<%[\s\S]*?(?:%>|$)/,null],["src",/^<(script|style|xmp)\b[^>]*>[\s\S]*?<\/\1\b[^>]*>/i,null],["tag",/^<\/?\w[^<>]*>/,null]]);function pa(b){var a=oa(b);for(var c=0;c<a.length;c+=2)if(a[c+1]==="src"){var d,g;d=a[c];g=c+2<a.length?a[c+2]:b.length;var e=b.substring(d,
-g),h=e.match(/^(<[^>]*>)([\s\S]*)(<\/[^>]*>)$/);if(h)a.splice(c,2,d,"tag",d+h[1].length,"src",d+h[1].length+(h[2]||"").length,"tag")}return a}var qa=v([["atv",/^\'[^\']*(?:\'|$)/,null,"'"],["atv",/^\"[^\"]*(?:\"|$)/,null,'"'],["pun",/^[<>\/=]+/,null,"<>/="]],[["tag",/^[\w:\-]+/,/^</],["atv",/^[\w\-]+/,/^=/],["atn",/^[\w:\-]+/,null],["pln",/^\s+/,null," \t\r\n"]]);function ra(b,a){for(var c=0;c<a.length;c+=2){var d=a[c+1];if(d==="tag"){var g,e;g=a[c];e=c+2<a.length?a[c+2]:b.length;var h=b.substring(g,
-e),f=qa(h,g);u(f,a,c,2);c+=f.length-2}}return a}function r(b){var a=[],c=[];if(b.tripleQuotedStrings)a.push(["str",/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""]);else if(b.multiLineStrings)a.push(["str",/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"]);else a.push(["str",/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
-null,"\"'"]);c.push(["pln",/^(?:[^\'\"\`\/\#]+)/,null," \r\n"]);if(b.hashComments)a.push(["com",/^#[^\r\n]*/,null,"#"]);if(b.cStyleComments)c.push(["com",/^\/\/[^\r\n]*/,null]);if(b.regexLiterals)c.push(["str",/^\/(?:[^\\\*\/\[]|\\[\s\S]|\[(?:[^\]\\]|\\.)*(?:\]|$))+(?:\/|$)/,Y]);if(b.cStyleComments)c.push(["com",/^\/\*[\s\S]*?(?:\*\/|$)/,null]);var d=x(b.keywords);b=null;var g=v(a,c),e=v([],[["pln",/^\s+/,null," \r\n"],["pln",/^[a-z_$@][a-z_$@0-9]*/i,null],["lit",/^0x[a-f0-9]+[a-z]/i,null],["lit",
-/^(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d+)(?:e[+\-]?\d+)?[a-z]*/i,null,"123456789"],["pun",/^[^\s\w\.$@]+/,null]]);function h(f,i){for(var j=0;j<i.length;j+=2){var o=i[j+1];if(o==="pln"){var m,k,l,n;m=i[j];k=j+2<i.length?i[j+2]:f.length;l=f.substring(m,k);n=e(l,m);for(var p=0,t=n.length;p<t;p+=2){var w=n[p+1];if(w==="pln"){var A=n[p],B=p+2<t?n[p+2]:l.length,s=f.substring(A,B);if(s===".")n[p+1]="pun";else if(s in d)n[p+1]="kwd";else if(/^@?[A-Z][A-Z$]*[a-z][A-Za-z$]*$/.test(s))n[p+1]=s.charAt(0)==="@"?"lit":
-"typ"}}u(n,i,j,2);j+=n.length-2}}return i}return function(f){var i=g(f);i=h(f,i);return i}}var G=r({keywords:W,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function sa(b,a){for(var c=0;c<a.length;c+=2){var d=a[c+1];if(d==="src"){var g,e;g=a[c];e=c+2<a.length?a[c+2]:b.length;var h=G(b.substring(g,e));for(var f=0,i=h.length;f<i;f+=2)h[f]+=g;u(h,a,c,2);c+=h.length-2}}return a}function ta(b,a){var c=false;for(var d=0;d<a.length;d+=2){var g=a[d+1],e,h;if(g==="atn"){e=
-a[d];h=d+2<a.length?a[d+2]:b.length;c=/^on|^style$/i.test(b.substring(e,h))}else if(g==="atv"){if(c){e=a[d];h=d+2<a.length?a[d+2]:b.length;var f=b.substring(e,h),i=f.length,j=i>=2&&/^[\"\']/.test(f)&&f.charAt(0)===f.charAt(i-1),o,m,k;if(j){m=e+1;k=h-1;o=f}else{m=e+1;k=h-1;o=f.substring(1,f.length-1)}var l=G(o);for(var n=0,p=l.length;n<p;n+=2)l[n]+=m;if(j){l.push(k,"atv");u(l,a,d+2,0)}else u(l,a,d,2)}c=false}}return a}function ua(b){var a=pa(b);a=ra(b,a);a=sa(b,a);a=ta(b,a);return a}function va(b,
-a,c){var d=[],g=0,e=null,h=null,f=0,i=0,j=ia(8);function o(k){if(k>g){if(e&&e!==h){d.push("</span>");e=null}if(!e&&h){e=h;d.push('<span class="',e,'">')}var l=E(j(b.substring(g,k))).replace(/(\r\n?|\n| ) /g,"$1&nbsp;").replace(/\r\n?|\n/g,"<br />");d.push(l);g=k}}while(true){var m;m=f<a.length?(i<c.length?a[f]<=c[i]:true):false;if(m){o(a[f]);if(e){d.push("</span>");e=null}d.push(a[f+1]);f+=2}else if(i<c.length){o(c[i]);h=c[i+1];i+=2}else break}o(b.length);if(e)d.push("</span>");return d.join("")}
-var C={};function q(b,a){for(var c=a.length;--c>=0;){var d=a[c];if(!C.hasOwnProperty(d))C[d]=b;else if("console"in window)console.log("cannot override language handler %s",d)}}q(G,["default-code"]);q(ua,["default-markup","html","htm","xhtml","xml","xsl"]);q(r({keywords:I,hashComments:true,cStyleComments:true}),["c","cc","cpp","cs","cxx","cyc"]);q(r({keywords:J,cStyleComments:true}),["java"]);q(r({keywords:O,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);q(r({keywords:M,hashComments:true,
-multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);q(r({keywords:L,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);q(r({keywords:N,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);q(r({keywords:K,cStyleComments:true,regexLiterals:true}),["js"]);function T(b,a){try{var c=na(b),d=c.source,g=c.tags;if(!C.hasOwnProperty(a))a=/^\s*</.test(d)?"default-markup":"default-code";var e=C[a].call({},d);return va(d,g,e)}catch(h){if("console"in window){console.log(h);
-console.trace()}return b}}function wa(b){var a=H(),c=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],d=[];for(var g=0;g<c.length;++g)for(var e=0;e<c[g].length;++e)d.push(c[g][e]);c=null;var h=0;function f(){var i=(new Date).getTime()+250;for(;h<d.length&&(new Date).getTime()<i;h++){var j=d[h];if(j.className&&j.className.indexOf("prettyprint")>=0){var o=j.className.match(/\blang-(\w+)\b/);if(o)o=o[1];var m=false;for(var k=j.parentNode;k;k=
-k.parentNode)if((k.tagName==="pre"||k.tagName==="code"||k.tagName==="xmp")&&k.className&&k.className.indexOf("prettyprint")>=0){m=true;break}if(!m){var l=ha(j);l=l.replace(/(?:\r\n?|\n)$/,"");var n=T(l,o);if(!S(j))j.innerHTML=n;else{var p=document.createElement("PRE");for(var t=0;t<j.attributes.length;++t){var w=j.attributes[t];if(w.specified)p.setAttribute(w.name,w.value)}p.innerHTML=n;j.parentNode.replaceChild(p,j);p=j}if(a&&j.tagName==="PRE"){var A=j.getElementsByTagName("br");for(var B=A.length;--B>=
-0;){var s=A[B];s.parentNode.replaceChild(document.createTextNode("\r\n"),s)}}}}}if(h<d.length)setTimeout(f,250);else if(b)b()}f()}window.PR_normalizedHtml=z;window.prettyPrintOne=T;window.prettyPrint=wa;window.PR={createSimpleLexer:v,registerLangHandler:q,sourceDecorator:r,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})();
diff --git a/slf4j-site/src/site/pages/legacy.html b/slf4j-site/src/site/pages/legacy.html
deleted file mode 100755
index 1dfe6c55..00000000
--- a/slf4j-site/src/site/pages/legacy.html
+++ /dev/null
@@ -1,267 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <title>Log4j Bridge</title>
- <link rel="stylesheet" type="text/css" media="screen" href="css/site.css" />
- <link rel="stylesheet" type="text/css" media="print" href="css/print.css" />
-
-</head>
-
-<body onload="decorate();">
- <script type="text/javascript">prefix='';</script>
-
- <script type="text/javascript" src="templates/header.js"></script>
- <script type="text/javascript" src="js/jquery-min.js"></script>
- <script type="text/javascript" src="js/decorator.js"></script>
-
- <div id="left">
- <script src="templates/left.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
-
- <h2>Bridging legacy APIs</h2>
-
- <p>Often, some of the components you depend on rely on a logging
- API other than SLF4J. You may also assume that these components
- will not switch to SLF4J in the immediate future. To deal with
- such circumstances, SLF4J ships with several bridging modules
- which redirect calls made to log4j, JCL and java.util.logging APIs
- to behave as if they were made to the SLF4J API instead. The
- figure below illustrates the idea.
- </p>
-
- <p>Please note that for source code under your control, you really
- should use the <a href="migrator.html">slf4j-migrator</a>. The
- binary-based solutions described in this page are appropriate for
- software beyond your control.
- </p>
-
- <p></p>
- <p></p>
-
-
- <p><a href="images/legacy.png">
- <img src="images/legacy.png" alt="click to enlarge" width="800"/>
- </a></p>
-
- <p>
- </p>
-
- <h2 class="doAnchor" name="jcl-over-slf4j">Gradual migration to
- SLF4J from Jakarta Commons Logging (JCL)</h2>
-
- <h4 class="doAnchor" name="jclOverSLF4J"><em>jcl-over-slf4j.jar</em></h4>
-
- <p>To ease migration to SLF4J from JCL, SLF4J distributions
- include the jar file <em>jcl-over-slf4j.jar</em>. This jar file is
- intended as a drop-in replacement for JCL version 1.1.1. It
- implements the public API of JCL but using SLF4J underneath, hence
- the name "JCL over SLF4J."
- </p>
-
- <p>Our JCL over SLF4J implementation will allow you to migrate to
- SLF4J gradually, especially if some of the libraries your software
- depends on continue to use JCL for the foreseeable future. You can
- immediately enjoy the benefits of SLF4J's reliability and preserve
- backward compatibility at the same time. Just replace
- <em>commons-logging.jar</em> with
- <em>jcl-over-slf4j.jar</em>. Subsequently, the selection of the
- underlying logging framework will be done by SLF4J instead of JCL
- <a href="http://articles.qos.ch/classloader.html">but without the
- class loader headaches plaguing JCL</a>. The underlying logging
- framework can be any of the frameworks supported by SLF4J. Often
- times, replacing <em>commons-logging.jar</em> with
- <em>jcl-over-slf4j.jar</em> will immediately and permanently solve
- class loader issues related to commons logging.
- </p>
-
- <h3 class="doAnchor" name="slf4jJCL"><em>slf4j-jcl.jar</em></h3>
-
- <p>Some of our users after having switched to SLF4J API realize that
- in some contexts the use of JCL is mandatory and their use of SLF4J
- can be a problem. For this uncommon but important case, SLF4J offers
- a JCL binding, found in the file <em>slf4j-jcl.jar</em>. The JCL
- binding will delegate all logging calls made through SLF4J API to
- JCL. Thus, if for some reason an existing application <em>must</em>
- use JCL, your part of that application can still code against the
- SLF4J API in a manner transparent to the larger application
- environment. Your choice of SLF4J API will be invisible to the rest
- of the application which can continue to use JCL.
- </p>
-
- <h3 class="doAnchor"
- name="jclRecursion"><em>jcl-over-slf4j.jar</em> should not be
- confused with <em>slf4j-jcl.jar</em></h3>
-
-
- <p>JCL-over-SLF4J, i.e. <em>jcl-over-slf4j.jar</em>, comes in handy
- in situations where JCL needs to be supported for backward
- compatibility reasons. It can be used to fix problems associated
- with JCL, without necessarily adopting the SLF4J API, a decision
- which can be deferred to a later time.
- </p>
-
- <p>On the other hand, <em>slf4j-jcl.jar</em> is useful
- <strong>after</strong> you have already adopted the SLF4J API for
- your component which needs to be embedded in a larger application
- environment where JCL is a formal requirement. Your software
- component can still use SLF4J API without disrupting the larger
- application. Indeed, <em>slf4j-jcl.jar</em> will delegate all
- logging decisions to JCL so that the dependency on SLF4J API by your
- component will be transparent to the larger whole.
- </p>
-
- <p>Please note that <em>jcl-over-slf4j.jar</em> and
- <em>slf4j-jcl.jar</em> cannot be deployed at the same time. The
- former jar file will cause JCL to delegate the choice of the
- logging system to SLF4J and the latter jar file will cause SLF4J
- to delegate the choice of the logging system to JCL, resulting in
- an <a href="codes.html#jclDelegationLoop">infinite loop</a>.
- </p>
-
-
- <h2 class="doAnchor" name="log4j-over-slf4j">log4j-over-slf4j</h2>
-
- <p>SLF4J ship with a module called <em>log4j-over-slf4j</em>. It
- allows log4j users to migrate existing applications to SLF4J without
- changing <em>a single line of code</em> but simply by replacing the
- <em>log4j.jar</em> file with <em>log4j-over-slf4j.jar</em>, as
- described below.
- </p>
-
- <h4 class="doAnchor" name="losHow">How does it work?</h4>
-
- <p>The log4j-over-slf4j module contains replacements of most widely
- used log4j classes, namely <code>org.apache.log4j.Category</code>,
- <code>org.apache.log4j.Logger</code>,
- <code>org.apache.log4j.Priority</code>,
- <code>org.apache.log4j.Level</code>,
- <code>org.apache.log4j.MDC</code>, and
- <code>org.apache.log4j.BasicConfigurator</code>. These replacement
- classes redirect all work to their corresponding SLF4J classes.
- </p>
-
- <p>To use log4j-over-slf4j in your own application, the first step
- is to locate and then to replace <em>log4j.jar</em> with
- <em>log4j-over-slf4j.jar</em>. Note that you still need an SLF4J
- binding and its dependencies for log4j-over-slf4j to work properly.
- </p>
-
- <p>In most situations, replacing a jar file is all it takes in
- order to migrate from log4j to SLF4J.
- </p>
-
- <p>Note that as a result of this migration, log4j configuration
- files will no longer be picked up. If you need to migrate your
- log4j.properties file to logback, the <a
- href="http://logback.qos.ch/translator/">log4j translator</a> might
- be of help. For configuring logback, please refer to <a
- href="http://logback.qos.ch/manual/index.html">its manual</a>.
- </p>
-
- <h4 class="doAnchor" name="losFail">When does it not work?</h4>
-
- <p>The <em>log4j-over-slf4j</em> module will not work when the
- application calls log4j components that are not present in the
- bridge. For example, when application code directly references
- log4j appenders, filters or the PropertyConfigurator, then
- log4j-over-slf4j would be an insufficient replacement for
- log4j. However, when log4j is configured through a configuration
- file, be it <em>log4j.properties</em> or <em>log4j.xml</em>, the
- log4j-over-slf4j module should just work fine.
- </p>
-
-
-
- <h4 class="doAnchor" name="losOverhead">What about the
- overhead?</h4>
-
- <p>There overhead of using log4j-over-slf4j instead of log4j
- directly is relatively small. Given that log4j-over-slf4j
- immediately delegates all work to SLF4J, the CPU overhead should be
- negligible, in the order of a few <em>nanoseconds</em>. There is a
- memory overhead corresponding to an entry in a hashmap per logger,
- which should be usually acceptable even for very large applications
- consisting of several thousand loggers. Moreover, if you choose
- logback as your underlying logging system, and given that logback is
- both much faster and more memory-efficient than log4j, the gains
- made by using logback should compensate for the overhead of using
- log4j-over-slf4j instead of log4j directly.
- </p>
-
- <h4 class="doAnchor" name="log4jRecursion">log4j-over-slf4j.jar
- and slf4j-log4j12.jar cannot be present simultaneously
- </h4>
-
- <p>The presence of <em>slf4j-log4j12.jar</em>, that is the log4j
- binding for SLF4J, will force all SLF4J calls to be delegated to
- log4j. The presence of <em>log4j-over-slf4j.jar</em> will in turn
- delegate all log4j API calls to their SLF4J equivalents. If both
- are present simultaneously, slf4j calls will be delegated to
- log4j, and log4j calls redirected to SLF4j, resulting in an <a
- href="codes.html#log4jDelegationLoop">endless loop</a>.
- </p>
-
-
-
- <h2 class="doAnchor" name="jul-to-slf4j">jul-to-slf4j bridge</h2>
-
- <p>The jul-to-slf4j module includes a java.util.logging (jul)
- handler, namely <code>SLF4JBridgeHandler</code>, which routes all
- incoming jul records to the SLF4j API. Please see <a
- href="api/org/slf4j/bridge/SLF4JBridgeHandler.html">SLF4JBridgeHandler
- javadocs</a> for usage instructions.
- </p>
-
- <p><span class="label notice">Note on performance</span> Contrary
- to other bridging modules, namely jcl-over-slf4j and
- log4j-over-slf4j, which reimplement JCL and respectively log4j,
- the jul-to-slf4j module does not reimplement the java.util.logging
- because packages under the java.* namespace cannot be
- replaced. Instead, jul-to-slf4j translates <a
- href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/logging/LogRecord.html?is-external=true">LogRecord</a>
- objects into their SLF4J equivalent. Please note this translation
- process incurs the cost of constructing a <code>LogRecord</code>
- instance regardless of whether the SLF4J logger is disabled for
- the given level or nor. <b>Consequently, j.u.l. to SLF4J
- translation can seriously increase the cost of disabled logging
- statements (60 fold or 6000%) and measurably impact the
- performance of enabled log statements (20% overall increase).</b>
- As of logback version 0.9.25, it is possible to completely
- eliminate the 60 fold translation overhead for disabled log
- statements with the help of <a
- href="http://logback.qos.ch/manual/configuration.html#LevelChangePropagator">LevelChangePropagator</a>.
- </p>
-
- <p>If you are concerned about application performance, then use of
- <code>SLF4JBridgeHandler</code> is appropriate only if any one of
- the following two conditions is true:
- </p>
- <ol>
- <li>few j.u.l. logging statements are in play </li>
- <li><code>LevelChangePropagator</code> has been installed</li>
- </ol>
-
-
- <h4 class="doAnchor" name="julRecursion">jul-to-slf4j.jar and slf4j-jdk14.jar cannot be present
- simultaneously
- </h4>
-
- <p>The presence of slf4j-jdk14.jar, that is the jul binding for
- SLF4J, will force SLF4J calls to be delegated to jul. On the other
- hand, the presence of jul-to-slf4j.jar, plus the installation of
- SLF4JBridgeHandler, by invoking "SLF4JBridgeHandler.install()" will
- route jul records to SLF4J. Thus, if both jar are present
- simultaneously (and SLF4JBridgeHandler is installed), slf4j calls
- will be delegated to jul and jul records will be routed to SLF4J,
- resulting in an endless loop.
- </p>
-
-
- <script src="templates/footer.js" type="text/javascript"></script>
- </div>
-</body>
-</html>
diff --git a/slf4j-site/src/site/pages/license.html b/slf4j-site/src/site/pages/license.html
deleted file mode 100644
index f895b75f..00000000
--- a/slf4j-site/src/site/pages/license.html
+++ /dev/null
@@ -1,68 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <title>SLF4J License</title>
- <link rel="stylesheet" type="text/css" media="screen" href="css/site.css" />
- </head>
- <body>
- <script type="text/javascript">prefix='';</script>
-
- <script src="templates/header.js" type="text/javascript"></script>
- <div id="left">
- <script src="templates/left.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
-
- <h1>Licensing terms for SLF4J</h1>
-
- <p>SLF4J source code and binaries are distributed under the
- MIT license.
- </p>
-
- <div class="source">
- Copyright (c) 2004-2013 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.
- </div>
-
- <p>These terms are <em>identical</em> to those of the <a
- href="http://en.wikipedia.org/wiki/MIT_License">MIT License</a>,
- also called the X License or the X11 License, which is a simple,
- permissive non-copyleft free software license. It is deemed
- compatible with virtually all types of licenses, commercial or
- otherwise. In particular, the Free Software Foundation has declared
- it compatible with <a
- href="http://www.fsf.org/licensing/licenses/license-list.html#GPLCompatibleLicenses">
- GNU GPL</a>. It is also known to be approved by the Apache Software
- Foundation as compatible with <a
- href="http://www.apache.org/licenses/">Apache Software License</a>.
- </p>
-
-
- <script src="templates/footer.js" type="text/javascript"></script>
-
-</div>
-</body>
-</html>
diff --git a/slf4j-site/src/site/pages/localization.html b/slf4j-site/src/site/pages/localization.html
deleted file mode 100755
index b321c63c..00000000
--- a/slf4j-site/src/site/pages/localization.html
+++ /dev/null
@@ -1,158 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <title>Localization</title>
- <link rel="stylesheet" type="text/css" media="screen" href="css/site.css" />
- <link rel="stylesheet" type="text/css" href="css/prettify.css" />
- </head>
- <body onload="prettyPrint()">
-
- <script type="text/javascript">prefix='';</script>
-
- <script type="text/javascript" src="js/prettify.js"></script>
- <script src="templates/header.js" type="text/javascript"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="templates/left.js" type="text/javascript"></script>
- </div>
-
- <div id="content">
-
-
- <h1>Localization support</h1>
-
- <p>A <a
- href="http://markmail.org/thread/drcabfc6z42sijdo">discussion</a>
- on the slf4j-dev mailing list spawned an open-source project
- called <a href="http://cal10n.qos.ch"><b>CAL10N or Compiler
- Assisted Localization</b></a>. As its name indicates, CAL10N
- focuses on the issue of localization/internationalization in Java
- applications.
- </p>
-
- <p>The <code>org.slf4j.cal10n</code> package which ships with
- <em>slf4j-ext-${project.version}.jar</em> adds an extremely thin
- layer on top of CALI0N to offer localized logging.</p>
-
-
- <p>Once you have a handle on an <a
- href="http://cal10n.qos.ch/apidocs/ch/qos/cal10n/IMessageConveyor.html">IMessageConveyor</a>
- instance, you can create a <a
- href="xref/org/slf4j/cal10n/LocLoggerFactory.html">LocLoggerFactory</a>,
- which in turn can create <a
- href="xref/org/slf4j/cal10n/LocLogger.html">LocLogger</a>
- instances capable of doing localized logging.
- </p>
-
-
- <p>Let us assume that you have defined localized message in your
- application. In accordance with the CAL10N's philosophy, you have
- the declared the keys for those messages in the enum type
- <code>Production</code>.</p>
-
-
- <pre class="prettyprint source">import ch.qos.cal10n.LocaleData;
-import ch.qos.cal10n.Locale;
-import ch.qos.cal10n.BaseName;
-
-@BaseName("production")
-@LocaleData( { @Locale("en_UK"), @Locale("ja_JP") })
-public enum Production {
- APPLICATION_STARTED,
- APPLICATION_STOPPED,
- ...
- DB_CONNECTION,
- DB_CONNECTION_FAILURE;
-}</pre>
-
- <p>It is assumed that you have created appropriate bundle file for
- the various locales "en_UK" and "ja_JP" as appropriate. Here is a
- sample bundle for the "en_UK" locale.
- </p>
-
-
- <pre class="source">APPLICATION_STARTED=Application <b>{0}</b> has started.
-APPLICATION_STOPPED=Application <b>{0}</b> has stopped.
-... </pre>
-
- <p>Then, you
- can instantiate a <code>IMessageConveyor</code>, inject it into a
- <code>LogLoggerFactory</code>, retrieve multiple
- <code>LogLogger</code> instances by name and log away, as the next
- sample code illustrates.
- </p>
-
-
- <pre class="prettyprint source">import java.util.Locale;
-
-import org.slf4j.cal10n.LocLogger;
-import org.slf4j.cal10n.LocLoggerFactory;
-
-import ch.qos.cal10n.IMessageConveyor;
-import ch.qos.cal10n.MessageConveyor;
-
-public class MyApplication {
-
- // create a message conveyor for a given locale
- IMessageConveyor messageConveyor = new MessageConveyor(Locale.UK);
-
- // create the LogLoggerFactory
- LocLoggerFactory llFactory_uk = new LocLoggerFactory(messageConveyor);
-
- // create a locLogger
- LocLogger locLogger = llFactory_uk.getLocLogger(this.getClass());
-
-
- public void applicationStart() {
- locLogger.info(Production.APPLICATION_STARTED, "fooApp");
- // ..
- }
-
- public void applicationStop() {
- locLogger.info(Production.APPLICATION_STOPPED, "fooApp");
- // ...
- }
-}</pre>
-
- <p>Assuming the resource bundle
- <em>production_en_UK.properties</em> exists, and the underlying
- logging framework is enabled for the info level, log messages will
- be output in UK English.
- </p>
-
- <p>Note that a <code>LogLogger</code> is a regular SLF4J logger
- with additional methods supporting localization. For those
- additional methods which take an enum as first parameter,
- <code>LogLogger</code> follows the standard Java convention for
- parameter substitution as defined by the <a
- href="http://java.sun.com/j2se/1.5.0/docs/api/java/text/MessageFormat.html">java.text.MessageFormat</a>
- class. For non-localized logs, which take a String as first
- parameter, <code>LogLogger</code> follows the {} convention, as
- customary for all <code>org.slf4j.Logger</code> implementations.
- </p>
-
- <p>Here is an example illustrating the difference.</p>
-
- <pre class="prettyprint source">import ...;
-public class MyApplication {
-
- IMessageConveyor messageConveyor = new MessageConveyor(Locale.UK);
- LocLoggerFactory llFactory_uk = new LocLoggerFactory(messageConveyor);
- LocLogger locLogger = llFactory_uk.getLocLogger(this.getClass());
-
- public void someMethod() {
- // follows the MessageFormat convention
- locLogger.info(Production.APPLICATION_STARTED, "fooApp");
-
- // follows the {} convention
- logLogger.info("Hello {}", name);
- ...
- }
-}</pre>
- <script src="templates/footer.js" type="text/javascript"></script>
- </div>
- </body>
-</html>
diff --git a/slf4j-site/src/site/pages/mailing-lists.html b/slf4j-site/src/site/pages/mailing-lists.html
deleted file mode 100755
index 09611469..00000000
--- a/slf4j-site/src/site/pages/mailing-lists.html
+++ /dev/null
@@ -1,128 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <title>SLF4J</title>
- <link rel="stylesheet" type="text/css" media="screen" href="css/site.css" />
- </head>
- <body>
- <script type="text/javascript">prefix='';</script>
-
- <script src="templates/header.js" type="text/javascript"></script>
- <div id="left">
- <script src="templates/left.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>SLF4J Mailing Lists</h1>
-
- <p>A mailing list is an electronic discussion forum that anyone can
- subscribe to. When someone sends an email message to the mailing
- list, a copy of that message is broadcast to everyone who is
- subscribed to that mailing list. Mailing lists provide a simple and
- effective communication mechanism. With potentially thousands of
- subscribers, there is a common set of etiquette guidelines that you
- should observe. Please keep on reading.
- </p>
-
- <h3>Respect the mailing list type</h3>
-
- <p>The "User" lists where you can send questions and comments about
- configuration, setup, usage and other "user" types of questions.
- The "Developer" lists where you can send questions and comments
- about the actual software source code and general "development"
- types of questions.
- </p>
-
- <p>Some questions are appropriate for posting on both the "user" and
- the "developer" lists. In this case, pick one and only one. Do not
- cross post.
- </p>
-
- <p>Please do your best to ensure that you are not sending HTML or
- "Stylized" email to the list. If you are using Outlook or Outlook
- Express or Eudora, chances are that you are sending HTML email by
- default. There is usually a setting that will allow you to send
- "Plain Text" email.
- </p>
-
-<!--
- <p>These lists are archived at
-
- <ul>
- <li><a href="http://logging.apache.org/mail/">Full mbox archives of all lists</a></li>
- <li> <a href="http://nagoya.apache.org/eyebrowse/">Eyebrowse Archives</a></li>
- <li>The Aims Group <a href="http://marc.theaimsgroup.com/">Archives</a></li>
- </ul>
- </p>
--->
-
-
-
- <h3>slf4j-announcements list</h3>
-
- <p>
- <b>Low Traffic:</b>
- <a href="http://www.qos.ch/mailman/listinfo/announce">Subscribe</a> |
- <a href="http://www.qos.ch/mailman/options/announce">Unsubscribe</a>
- <br/>
- <b>Archives:</b>
- <a href="http://www.qos.ch/pipermail/announce/">Pipermail</a> |
- <a href="http://slf4j.42922.n3.nabble.com/Slf4J-announce-f46208.html">Nabble</a>
- </p>
- <p>The announcements list is reserved for important SLF4J API
- related announcements. As such, the traffic on this list is
- guaranteed to be very low.
- </p>
-
- <p>Given that implementations are expected to statically bind with
- the SLF4J API, we recommend that any implementor of the SLF4J API
- be subscribed at least to the announcements list.
- </p>
-
- <h3>slf4j-user list</h3>
-
- <p>
- <b>Medium Traffic:</b>
- <a href="http://www.qos.ch/mailman/listinfo/slf4j-user">Subscribe</a> |
- <a href="http://www.qos.ch/mailman/options/slf4j-user">Unsubscribe</a>
- <br/>
- <b>Archives:</b>
- <a href="http://www.qos.ch/pipermail/slf4j-user/">qos.ch</a> |
- <a href="http://markmail.org/search/?q=order%3Adate-backward+list%3Aorg.slf4j.user">MarkLogic</a> |
- <a href="http://news.gmane.org/gmane.comp.java.slf4j.user">Gmane</a> |
- <a href="http://slf4j.42922.n3.nabble.com/slf4j-user-f41810.html">Nabble</a> |
- <a href="http://www.mail-archive.com/user%40slf4j.org/">MailArchive</a>
- <a href=""> </a>
-
-
- </p>
-
- <p>This is the list for users of slf4j. It is also a good forum for
- asking questions about how slf4j works, and how it can be
- used. SLF4J developers are usually subscribed to to this list in
- order to offer support.</p>
-
-
- <h3>slf4j-dev list</h3>
-
- <p>
- <b>Medium Traffic:</b>
- <a href="http://www.qos.ch/mailman/listinfo/slf4j-dev">Subscribe</a> |
- <a href="http://www.qos.ch/mailman/options/slf4j-dev">Unsubscribe</a>
- <br/>
- <b>Archives:</b>
- <a href="http://www.qos.ch/pipermail/slf4j-dev/">qos.ch</a> |
- <a href="http://markmail.org/search/?q=order%3Adate-backward+list%3Aorg.slf4j.dev">MarkLogic</a> |
- <a href="http://news.gmane.org/gmane.comp.java.slf4j.devel">Gmane</a> |
- <a href="http://slf4j.42922.n3.nabble.com/slf4j-dev-f41812.html">Nabble</a> |
- <a href="http://www.mail-archive.com/dev%40slf4j.org/">MailArchive</a>
- </p>
- <p>&nbsp;</p>
-
- <script src="templates/footer.js" type="text/javascript"></script>
-</div>
-</body>
-</html>
diff --git a/slf4j-site/src/site/pages/manual.html b/slf4j-site/src/site/pages/manual.html
deleted file mode 100755
index 2c4430f0..00000000
--- a/slf4j-site/src/site/pages/manual.html
+++ /dev/null
@@ -1,539 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <title>SLF4J Manual</title>
- <link rel="stylesheet" type="text/css" media="screen" href="css/site.css" />
- <link rel="stylesheet" type="text/css" href="css/prettify.css" />
- </head>
- <body onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='';</script>
- <script type="text/javascript" src="js/prettify.js"></script>
- <script type="text/javascript" src="js/jquery-min.js"></script>
- <script type="text/javascript" src="js/decorator.js"></script>
- <script type="text/javascript" src="templates/header.js"></script>
- <div id="left">
- <script type="text/javascript" src="templates/left.js"></script>
- </div>
- <div id="content">
-
-
- <h2>SLF4J user manual</h2>
-
- <p>The Simple Logging Facade for Java (SLF4J) serves as a simple
- facade or abstraction for various logging frameworks, such as
- java.util.logging, logback and log4j. SLF4J allows the end-user to
- plug in the desired logging framework at <em>deployment</em> time.
- Note that SLF4J-enabling your library/application implies the
- addition of only a single mandatory dependency, namely
- <em>slf4j-api-${project.version}.jar</em>.</p>
-
- <p><span class="label">since 1.6.0</span> If no binding is found on the
- class path, then SLF4J will default to a no-operation
- implementation.
- </p>
-
- <p><span class="label">since 1.7.0</span> Printing methods in the
- <a href="apidocs/org/slf4j/Logger.html"><code>Logger</code></a>
- interface now offer variants accepting <a
- href="http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html">varargs</a>
- instead of <code>Object[]</code>. This change implies that SLF4J
- requires JDK 1.5 or later. Under the hood the Java compiler
- transforms the varargs part in methods into
- <code>Object[]</code>. Thus, the Logger interface generated by the
- compiler is indistinguishable in 1.7.x from its 1.6.x
- counterpart. It follows that SLF4J version 1.7.x is totally 100%
- no-ifs-or-buts compatible with SLF4J version 1.6.x.
- </p>
-
- <p><span class="label">since 1.7.5</span> Significant improvement
- in logger retrieval times. Given the extent of the improvement,
- users are highly encouraged to migrate to SLF4J 1.7.5 or later.
- </p>
-
- <p><span class="label">since 1.7.9</span> By setting the
- <code>slf4j.detectLoggerNameMismatch</code> system property to
- true, SLF4J can automatically <a
- href="codes.html#loggerNameMismatch">spot incorrectly named
- loggers</a>.
- </p>
-
-
- <h3 class="doAnchor" name="hello_world">Hello World</h3>
-
- <p>As customary in programming tradition, here is an example
- illustrating the simplest way to output "Hello world" using SLF4J.
- It begins by getting a logger with the name "HelloWorld". This
- logger is in turn used to log the message "Hello World".
- </p>
-
-<pre class="prettyprint source">import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class HelloWorld {
- public static void main(String[] args) {
- Logger logger = LoggerFactory.getLogger(HelloWorld.class);
- logger.info("Hello World");
- }
-}</pre>
-
- <p>To run this example, you first need to <a
- href="download.html">download the slf4j distribution</a>, and
- then to unpack it. Once that is done, add the file
- <em>slf4j-api-${project.version}.jar</em> to your class path.</p>
-
- <p>Compiling and running <em>HelloWorld</em> will result in the
- following output being printed on the console.</p>
-
-<pre>SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
-SLF4J: Defaulting to no-operation (NOP) logger implementation
-SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.</pre>
-
- <p>This warning is printed because no slf4j binding could be
- found on your class path.</p>
-
- <p>The warning will disappear as soon as you add a <a
- href="#swapping">binding</a> to your class path. Assuming you add
- <em>slf4j-simple-${project.version}.jar</em> so that your class
- path contains:</p>
-
- <ul>
- <li>slf4j-api-${project.version}.jar</li>
- <li>slf4j-simple-${project.version}.jar</li>
- </ul>
-
- <p>Compiling and running <em>HelloWorld</em> will now result in
- the following output on the console.</p>
-
- <pre class="output">0 [main] INFO HelloWorld - Hello World</pre>
-
- <h3 class="doAnchor" name="typical_usage">Typical usage
- pattern</h3>
-
- <p>The sample code below illustrates the typical usage pattern
- for SLF4J. Note the use of {}-placeholders on line 15. See the
- question <a href="faq.html#logging_performance">"What is the
- fastest way of logging?"</a> in the FAQ for more details.
- </p>
-
- <p></p>
-
- <pre class="prettyprint source"> 1: <b>import org.slf4j.Logger;</b>
- 2: <b>import org.slf4j.LoggerFactory;</b>
- 3:
- 4: public class Wombat {
- 5:
- 6: <b>final Logger logger = LoggerFactory.getLogger(Wombat.class);</b>
- 7: Integer t;
- 8: Integer oldT;
- 9:
-10: public void setTemperature(Integer temperature) {
-11:
-12: oldT = t;
-13: t = temperature;
-14:
-15: <b>logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);</b>
-16:
-17: if(temperature.intValue() > 50) {
-18: <b>logger.info("Temperature has risen above 50 degrees.");</b>
-19: }
-20: }
-21: } </pre>
-
-
-
- <h3 class="doAnchor" name="swapping">Binding with a logging
- framework at deployment time</h3>
-
- <p>As mentioned previously, SLF4J supports various logging
- frameworks. The SLF4J distribution ships with several jar files
- referred to as "SLF4J bindings", with each binding corresponding
- to a supported framework. </p>
-
- <dl>
-
- <dt><em>slf4j-log4j12-${project.version}.jar</em>
- </dt>
- <dd>Binding for <a
- href="http://logging.apache.org/log4j/1.2/index.html">log4j
- version 1.2</a>, a widely used logging framework. You also
- need to place <em>log4j.jar</em> on your class path.<p/></dd>
-
- <dt><em>slf4j-jdk14-${project.version}.jar</em> </dt>
- <dd>Binding for java.util.logging, also referred to as JDK 1.4
- logging <p/></dd>
-
- <dt><em>slf4j-nop-${project.version}.jar</em></dt>
- <dd>Binding for <a
- href="http://www.slf4j.org/api/org/slf4j/helpers/NOPLogger.html">NOP</a>,
- silently discarding all logging.<p/></dd>
-
- <dt><em>slf4j-simple-${project.version}.jar</em></dt>
- <dd>Binding for <a
- href="http://www.slf4j.org/apidocs/org/slf4j/impl/SimpleLogger.html">Simple
- </a> implementation, which outputs all events to
- System.err. Only messages of level INFO and higher are
- printed. This binding may be useful in the context of small
- applications.<p/></dd>
-
- <dt><em>slf4j-jcl-${project.version}.jar</em></dt>
-
- <dd>Binding for <a
- href="http://commons.apache.org/logging/">Jakarta Commons
- Logging</a>. This binding will delegate all SLF4J logging to
- JCL.<p/>
- </dd>
-
- <dt><em>logback-classic-${logback.version}.jar (requires logback-core-${logback.version}.jar)</em></dt>
-
- <dd><span class="label notice">Native implementation</span> There are also
- SLF4J bindings external to the SLF4J project, e.g. <a
- href="http://logback.qos.ch/">logback</a> which implements
- SLF4J natively. Logback's
- <a href="http://logback.qos.ch/apidocs/ch/qos/logback/classic/Logger.html">
- <code>ch.qos.logback.classic.Logger</code></a> class is a
- direct implementation of SLF4J's <a
- href="http://www.slf4j.org/apidocs/org/slf4j/Logger.html">
- <code>org.slf4j.Logger</code></a> interface. Thus, using SLF4J
- in conjunction with logback involves strictly zero memory and
- computational overhead.
-
- </dd>
- </dl>
-
- <p>
- </p>
-
-
- <p>To switch logging frameworks, just replace slf4j bindings on
- your class path. For example, to switch from java.util.logging
- to log4j, just replace slf4j-jdk14-${project.version}.jar with
- slf4j-log4j12-${project.version}.jar.
- </p>
-
- <p>SLF4J does not rely on any special class loader machinery. In
- fact, each SLF4J binding is hardwired <em>at compile time</em>
- to use one and only one specific logging framework. For
- example, the slf4j-log4j12-${project.version}.jar binding is
- bound at compile time to use log4j. In your code, in addition
- to <em>slf4j-api-${project.version}.jar</em>, you simply drop
- <b>one and only one</b> binding of your choice onto the
- appropriate class path location. Do not place more than one
- binding on your class path. Here is a graphical illustration of
- the general idea.
- </p>
-
- <p><a href="images/concrete-bindings.png">
- <img border="1" src="images/concrete-bindings.png" alt="click to enlarge" width="800"/>
- </a></p>
-
- <p>The SLF4J interfaces and their various adapters are extremely
- simple. Most developers familiar with the Java language should
- be able to read and fully understand the code in less than one
- hour. No knowledge of class loaders is necessary as SLF4J does
- not make use nor does it directly access any class loaders. As a
- consequence, SLF4J suffers from none of the class loader
- problems or memory leaks observed with Jakarta Commons Logging
- (JCL).
- </p>
-
- <p>Given the simplicity of the SLF4J interfaces and its
- deployment model, developers of new logging frameworks should
- find it very easy to write SLF4J bindings.
- </p>
-
- <h3 class="doAnchor" name="libraries">Libraries</h3>
-
- <p>Authors of widely-distributed components and libraries may
- code against the SLF4J interface in order to avoid imposing an
- logging framework on their end-user. Thus, the end-user may
- choose the desired logging framework at deployment time by
- inserting the corresponding slf4j binding on the classpath,
- which may be changed later by replacing an existing binding with
- another on the class path and restarting the application. This
- approach has proven to be simple and very robust.
- </p>
-
- <p><b>As of SLF4J version 1.6.0</b>, if no binding is found on
- the class path, then slf4j-api will default to a no-operation
- implementation discarding all log requests. Thus, instead of
- throwing a <code>NoClassDefFoundError</code> because the
- <code>org.slf4j.impl.StaticLoggerBinder</code> class is missing,
- SLF4J version 1.6.0 and later will emit a single warning message
- about the absence of a binding and proceed to discard all log
- requests without further protest. For example, let Wombat be
- some biology-related framework depending on SLF4J for
- logging. In order to avoid imposing a logging framework on the
- end-user, Wombat's distribution includes <em>slf4j-api.jar</em>
- but no binding. Even in the absence of any SLF4J binding on the
- class path, Wombat's distribution will still work
- out-of-the-box, and without requiring the end-user to download a
- binding from SLF4J's web-site. Only when the end-user decides to
- enable logging will she need to install the SLF4J binding
- corresponding to the logging framework chosen by her.
- </p>
-
- <p><span class="label">Basic rule</span> <b>Embedded components
- such as libraries or frameworks should not declare a dependency
- on any SLF4J binding but only depend on slf4j-api</b>. When a
- library declares a transitive dependency on a specific binding,
- that binding is imposed on the end-user negating the purpose of
- SLF4J. Note that declaring a non-transitive dependency on a
- binding, for example for testing, does not affect the
- end-user.</p>
-
- <p>SLF4J usage in embedded components is also discussed in the
- FAQ in relation with <a
- href="faq.html#configure_logging">logging configuration</a>, <a
- href="faq.html#optional_dependency">dependency reduction</a> and
- <a href="faq.html#optional_dependency">testing</a>.</p>
-
- <h3 class="doAnchor" name="projectDep">Declaring project
- dependencies for logging</h3>
-
- <p>Given Maven's transitive dependency rules, for "regular"
- projects (not libraries or frameworks) declaring logging
- dependencies can be accomplished with a single dependency
- declaration.
- </p>
-
- <p><span class="label notice">logback-classic</span> If you wish
- to use logback-classic as the underlying logging framework, all
- you need to do is to declare "ch.qos.logback:logback-classic" as
- a dependency in your <em>pom.xml</em> file as shown below. In
- addition to <em>logback-classic-${logback.version}.jar</em>,
- this will pull <em>slf4j-api-${project.version}.jar</em> as well
- as <em>logback-core-${logback.version}.jar</em> into your
- project. Note that explicitly declaring a dependency on
- <em>logback-core-${logback.version}</em> or
- <em>slf4j-api-${project.version}.jar</em> is not wrong and may
- be necessary to impose the correct version of said artifacts by
- virtue of Maven's "nearest definition" dependency mediation
- rule.
- </p>
-
-<pre class="prettyprint source">&lt;dependency>
- &lt;groupId>ch.qos.logback&lt;/groupId>
- &lt;artifactId>logback-classic&lt;/artifactId>
- &lt;version>${logback.version}&lt;/version>
-&lt;/dependency></pre>
-
- <p/>
-
- <p><span class="label notice">log4j</span> If you wish to use
- log4j as the underlying logging framework, all you need to do is
- to declare "org.slf4j:slf4j-log4j12" as a dependency in your
- <em>pom.xml</em> file as shown below. In addition to
- <em>slf4j-log4j12-${project.version}.jar</em>, this will pull
- <em>slf4j-api-${project.version}.jar</em> as well as
- <em>log4j-${log4j.version}.jar</em> into your project. Note
- that explicitly declaring a dependency on
- <em>log4j-${log4j.version}.jar</em> or
- <em>slf4j-api-${project.version}.jar</em> is not wrong and may
- be necessary to impose the correct version of said artifacts by
- virtue of Maven's "nearest definition" dependency mediation
- rule.</p>
-
-<pre class="prettyprint source">&lt;dependency>
- &lt;groupId>org.slf4j&lt;/groupId>
- &lt;artifactId>slf4j-log4j12&lt;/artifactId>
- &lt;version>${project.version}&lt;/version>
-&lt;/dependency></pre>
-
- <p/>
-
- <p><span class="label notice">java.util.logging</span> If you
- wish to use java.util.logging as the underlying logging
- framework, all you need to do is to declare
- "org.slf4j:slf4j-jdk14" as a dependency in your <em>pom.xml</em>
- file as shown below. In addition to
- <em>slf4j-jdk14-${project.version}.jar</em>, this will pull
- <em>slf4j-api-${project.version}.jar</em> into your project.
- Note that explicitly declaring a dependency on
- <em>slf4j-api-${project.version}.jar</em> is not wrong and may
- be necessary to impose the correct version of said artifact by
- virtue of Maven's "nearest definition" dependency mediation
- rule.</p>
-
-<pre class="prettyprint source">&lt;dependency>
- &lt;groupId>org.slf4j&lt;/groupId>
- &lt;artifactId>slf4j-jdk14&lt;/artifactId>
- &lt;version>${project.version}&lt;/version>
-&lt;/dependency></pre>
-
-
-
- <h3 class="doAnchor" name="compatibility">Binary
- compatibility</h3>
-
- <p>An SLF4J binding designates an artifact such as
- <em>slf4j-jdk14.jar</em> or <em>slf4j-log4j12.jar</em> used to
- <em>bind</em> slf4j to an underlying logging framework, say,
- java.util.logging and respectively log4j.
- </p>
-
- <p class="highlight">From the client's perspective all versions
- of slf4j-api are compatible. Client code compiled with
- slf4j-api-N.jar will run perfectly fine with slf4j-api-M.jar for
- any N and M. You only need to ensure that the version of your
- binding matches that of the slf4j-api.jar. You do not have to
- worry about the version of slf4j-api.jar used by a given
- dependency in your project. </p>
-
-
- <p>Mixing different versions of <em>slf4j-api.jar</em> and SLF4J
- binding can cause problems. For example, if you are using
- slf4j-api-${project.version}.jar, then you should also use
- slf4j-simple-${project.version}.jar, using
- slf4j-simple-1.5.5.jar will not work.</p>
-
-
- <p>However, from the client's perspective all versions of
- slf4j-api are compatible. Client code compiled with
- <em>slf4j-api-N.jar</em> will run perfectly fine with
- <em>slf4j-api-M.jar</em> for any N and M. You only need to
- ensure that the version of your binding matches that of the
- slf4j-api.jar. You do not have to worry about the version of
- slf4j-api.jar used by a given dependency in your project. You
- can always use any version of <em>slf4j-api.jar</em>, and as
- long as the version of <em>slf4j-api.jar</em> and its binding
- match, you should be fine.
- </p>
-
- <p>At initialization time, if SLF4J suspects that there may be
- an slf4j-api vs. binding version mismatch problem, it will emit
- a warning about the suspected mismatch.
- </p>
-
-
- <h3 class="doAnchor" name="consolidate">Consolidate logging via
- SLF4J</h3>
-
- <p>Often times, a given project will depend on various
- components which rely on logging APIs other than SLF4J. It is
- common to find projects depending on a combination of JCL,
- java.util.logging, log4j and SLF4J. It then becomes desirable to
- consolidate logging through a single channel. SLF4J caters for
- this common use-case by providing bridging modules for JCL,
- java.util.logging and log4j. For more details, please refer to
- the page on <a href="legacy.html"><b>Bridging legacy
- APIs</b></a>.
- </p>
-
- <h3 class="doAnchor" name="mdc">Mapped Diagnostic Context (MDC) support</h3>
-
- <p>"Mapped Diagnostic Context" is essentially a map maintained
- by the logging framework where the application code provides
- key-value pairs which can then be inserted by the logging
- framework in log messages. MDC data can also be highly helpful
- in filtering messages or triggering certain actions.</p>
-
- <p>SLF4J supports MDC, or mapped diagnostic context. If the
- underlying logging framework offers MDC functionality, then
- SLF4J will delegate to the underlying framework's MDC. Note that
- at this time, only log4j and logback offer MDC functionality. If
- the underlying framework does not offer MDC, for example
- java.util.logging, then SLF4J will still store MDC data but the
- information therein will need to be retrieved by custom user
- code.</p>
-
- <p>Thus, as a SLF4J user, you can take advantage of MDC
- information in the presence of log4j or logback, but without
- forcing these logging frameworks upon your users as
- dependencies.
- </p>
-
- <p>For more information on MDC please see the <a
- href="http://logback.qos.ch/manual/mdc.html">chapter on MDC</a>
- in the logback manual.
- </p>
-
-
-
- <h3 class="doAnchor" name="summary">Executive summary</h3>
-
- <table class="bodyTable striped" cellspacing="4" cellpadding="4">
- <tr>
- <th align="left">Advantage</th>
- <th align="left">Description</th>
- </tr>
-
- <tr>
-
- <td>Select your logging framework at deployment time</td>
-
- <td>The desired logging framework can be plugged in at
- deployment time by inserting the appropriate jar file
- (binding) on your class path.
- </td>
- </tr>
-
-
- <tr>
- <td>Fail-fast operation</td>
-
- <td>Due to the way that classes are loaded by the JVM, the
- framework binding will be verified automatically very early
- on. If SLF4J cannot find a binding on the class path it
- will emit a single warning message and default to
- no-operation implementation.
- </td>
- </tr>
-
-
- <tr>
- <td>Bindings for popular logging frameworks
- </td>
-
- <td>SLF4J supports popular logging frameworks, namely log4j,
- java.util.logging, Simple logging and NOP. The <a
- href="http://logback.qos.ch">logback</a> project supports
- SLF4J natively. </td>
-
- </tr>
-
- <tr>
- <td>Bridging legacy logging APIs</td>
-
- <td>
- <p>The implementation of JCL over SLF4J, i.e
- <em>jcl-over-slf4j.jar</em>, will allow your project to
- migrate to SLF4J piecemeal, without breaking compatibility
- with existing software using JCL. Similarly,
- log4j-over-slf4j.jar and jul-to-slf4j modules will allow
- you to redirect log4j and respectively java.util.logging
- calls to SLF4J. See the page on <a
- href="legacy.html">Bridging legacy APIs</a> for more
- details.
- </p>
- </td>
- </tr>
-
- <tr>
- <td>Migrate your source code</td>
- <td>The <a href="migrator.html">slf4j-migrator</a> utility
- can help you migrate your source to use SLF4J.
- </td>
- </tr>
-
-
-
- <tr>
- <td>Support for parameterized log messages</td>
-
- <td>All SLF4J bindings support parameterized log messages
- with significantly <a
- href="faq.html#logging_performance">improved performance</a>
- results.</td>
- </tr>
-
-
- </table>
-
- <script src="templates/footer.js" type="text/javascript"></script>
-
-</div>
-</body>
-</html>
diff --git a/slf4j-site/src/site/pages/migrator.html b/slf4j-site/src/site/pages/migrator.html
deleted file mode 100755
index 76948f41..00000000
--- a/slf4j-site/src/site/pages/migrator.html
+++ /dev/null
@@ -1,226 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <title>SLF4J Migrator</title>
- <link rel="stylesheet" type="text/css" media="screen" href="css/site.css" />
- </head>
- <body>
- <script type="text/javascript">prefix='';</script>
-
- <script src="templates/header.js" type="text/javascript"></script>
- <div id="left">
- <script src="templates/left.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
-
- <h1>SLF4J Migrator</h1>
-
- <p>The SLF4J migrator is a small Java tool for migrating Java source
- files from the Jakarta Commons Logging (JCL) API to SLF4J. It can
- also migrate from the log4j API to SLF4J, or from
- <code>java.util.logging</code> API to SLF4J.
- </p>
-
- <p>The SLF4J migrator consists of a single jar file that can be
- launched as a stand-alone java application. Here is the command:
- </p>
-
- <p class="source">java -jar slf4j-migrator-${version}.jar </p>
-
- <br/>
-
- <p>Once the application is launched, a window similar to the
- following should appear.
- </p>
-
- <p><img src="images/slf4j-migrator.gif" alt="slf4j-migrator.gif"/></p>
-
- <p>Use of the application should be self-explanatory. Please note that
- this migration tool does in-place replacement of Java files, meaning
- that there will be no back-up copies of modified files. <b>It is
- your responsibility to backup your files before using SLF4J
- Migrator.</b>
- </p>
-
-
- <h2>Limitations</h2>
-
- <p>SLF4J migrator is intended as a simple tool to help you to
- migrate your project source using JCL, log4j or JUL to SLF4J. It can
- only perform elementary conversion steps. Essentially, it will
- replace appropriate import lines and logger declarations.
- </p>
-
- <p>MyClass is a sample class using JCL. Here it is before:</p>
-
- <p class="source">package some.package;
-
-<b>import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;</b>
-
-public MyClass {
-
- <b>Log logger = LogFactory.getLog(MyClass.class);</b>
-
- public void someMethod() {
- logger.info("Hello world");
- }
-}</p>
-
- <p>and after migration:</p>
-
- <p class="source">package some.package;
-
-<b>import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;</b>
-
-public MyClass {
-
- <b>Logger logger = LoggerFactory.getLogger(MyClass.class);</b>
-
- public void someMethod() {
- logger.info("Hello world");
- }
-}</p>
-
- <br/>
-
- <p>Although its conversion rules are elementary, the SLF4J migrator
- can still alleviate much of the grunt-work involved in migrating a
- Java project from JCL to SLF4J.
- </p>
-
- <p>Migration rules from log4j to SLF4J, or from JUL to SLF4J are
- similar.</p>
-
- <h3>General limitations</h3>
-
- <ul>
-
- <li>Build scripts are not modified
-
- <p>Your Ant/Maven/Ivy build scripts need to be modified manually to
- use SLF4J instead of JCL or log4j.</p>
-
- <p></p>
- </li>
-
- <li>only messages of type String are supported
-
- <p>If one of your log statements contains a non-string object as
- its sole parameter, you will have to manually add a toString()
- method call on the object.
- </p>
-
- <p>For example,</p>
- <p class="source">logger.debug(new Object()); </p>
- <p>has to be manually re-written as</p>
- <p class="source">logger.debug(new Object().toString()); </p>
-
- <p></p>
- </li>
-
- <li>the FATAL level is not supported.
-
- <p>You have to convert them manually. This limitation is not
- deemed very serious because there are usually very few log
- statements bearing the FATAL level.
- </p>
-
- <p>
- </p>
- </li>
-
- <li>if a method declares multiple loggers on the same line, the
- conversion will not be complete. Example:
-
- <p class="source"> public void someMethod(Log l1, Log l2) {
- ...
- }
-
-will be converted as
-
- public void someMethod(Log l1, Logger l2) {
- ...
- } </p>
- </li>
- </ul>
-
- <h3>Limitations when migrating from log4j</h3>
-
- <ul>
- <li>NDC statements are left as-is
-
- <p>Since NDC is not supported by SLF4J, the migrator cannot
- properly handle NDC statements. You have to migrate them to MDC
- manually. Again, this limitation is not deemed serious because
- there are usually very few NDC statements even in large projects.
- </p>
-
- <p>Please note that contrary to NDC, MDC statements are migrated
- correctly because SLF4J supports such statements.</p>
-
- <p></p>
- </li>
-
- <li>Calls to <code>PropertyConfigurator</code> or
- <code>DomConfigurator</code> cannot be migrated since they have no
- SLF4J equivalents.
-
- <p>
- </p>
-
- </li>
- </ul>
-
- <h3>Limitations when migrating from JUL</h3>
-
-
- <ul>
- <li>Calls to <code>finest()</code>, <code>finer()</code> or
- <code>finest()</code> methods of
- <code>java.util.logging.Logger</code> are left as is.
-
- <p>Given that <code>finest()</code>, <code>finer()</code> or
- <code>finest()</code> calls could map to both trace() or debug()
- calls in SLF4J, it is impossible to guess how the user wants to
- map these calls.
- </p>
-
- <p>
- </p>
-
- </li>
-
-
- <li>All strings matching ".severe(" are replaced by the string
- ".error(" without any contextual analysis. Similarly, all strings
- matching ".warning(" are replaced by ".warn(".
-
- <p>Since the match/replace operation is not contextual, if your
- code contains methods named "severe" or "warning", then the
- migration results will have compilation errors. Fortunately, such
- errors should be rare and easy to identify.
- </p>
-
- <p>
- </p>
-
- </li>
-
- <li>Invocations of the following methods defined in the
- <code>java.util.logging.Logger</code> class need to be migrated
- manually: <code>log</code>, <code>logp</code>, <code>logrb</code>,
- <code>entering</code>, <code>exiting</code>.
-
- </li>
- </ul>
-
- <script src="templates/footer.js" type="text/javascript"></script>
- </div>
-</body>
-</html>
diff --git a/slf4j-site/src/site/pages/news.html b/slf4j-site/src/site/pages/news.html
deleted file mode 100755
index 36d4b338..00000000
--- a/slf4j-site/src/site/pages/news.html
+++ /dev/null
@@ -1,1638 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <title>SLF4J News</title>
- <link rel="stylesheet" type="text/css" media="screen" href="css/site.css" />
- <link rel="stylesheet" type="text/css" href="css/prettify.css" />
- </head>
- <body onload="prettyPrint()">
- <script type="text/javascript">prefix='';</script>
- <script type="text/javascript" src="js/prettify.js"></script>
-
- <script src="templates/header.js" type="text/javascript"></script>
- <div id="left">
- <script src="templates/left.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
-
- <h1>SLF4J News</h1>
-
- <p>Please note that you can receive SLF4J related announcements by
- subscribing to the <a
- href="http://www.qos.ch/mailman/listinfo/announce">QOS.ch
- announce</a> mailing list.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>March 26th, 2015 - Release of SLF4J 1.7.12</h3>
-
- <p>All java files have been reformatted to with the code formatter
- style defined in <i>codeStyle.xml</i>. This style uses 4 spaces for
- indentation and a maximum line width of 160.</p>
-
- <p>As SLF4J requires JDK 1.5 or later, the
- <code>Bundle-RequiredExecutionEnvironment</code> declaration in the
- various MANIFEST files have been updated to J2SE-1.5.
- </p>
-
- <p>Added missing Bundle-ManifestVersion attribute in the MANIFEST
- files in log4j-over-slf4j. The issue was raised in <a
- href="http://jira.qos.ch/browse/SLF4J-321">SLF4J-231</a> by Nikolas
- Falco who also provided the the appropriate pull request. </p>
-
- <p>Added <code>getAppender(String)</code> method in
- <code>Category</code> class in the log4j-over-slf4j module. This
- addition was requested by Ramon Gordillo in <a
- href="http://jira.qos.ch/browse/SLF4J-319">SLF4J-319</a>.
- </p>
-
- <p>Added <code>setThreshold</code> method in
- <code>AppenderSkeleton</code> class in the log4j-over-slf4j
- module. This addition was requested by Dimitrios Liapis who also
- provided the appropriate pull request.
- </p>
-
- <p>Added <code>getParent</code> method in <code>Category</code>
- class in the log4j-over-slf4j module. This addition was requested
- by Himanshu Bhardwaj in <a
- href="http://jira.qos.ch/browse/SLF4J-318">SLF4J-318</a>.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>6th of January, 2015 - Release of SLF4J 1.7.10</h3>
-
- <p>The <code>MDC.putCloseable</code> method now explicitly returns
- <code>MDC.MDCloseable</code> instead of the more generic
- <code>java.io.Closeable</code>. This in turn allows one to write
- try-with-resources statement without a catch clause. Many thanks to
- William Delanoue for proposing this change.</p>
-
- <p>The various constructors in <code>FileAppender</code> in the
- log4j-over-slf4j module are now public.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>16th of December, 2014 - Release of SLF4J 1.7.9</h3>
-
- <p class="highlight"><a href="codes.html#loggerNameMismatch">Spot
- incorrectly named loggers</a> by setting the
- <code>slf4j.detectLoggerNameMismatch</code> system property to
- true.</p>
-
- <p><a href="codes.html#loggerNameMismatch">Spot incorrectly named
- loggers</a> by setting the
- <code>slf4j.detectLoggerNameMismatch</code> system property to
- true. This significant feature was contributed by Alexander
- Dorokhine.</p>
-
- <p>Added <code>MDC.putCloseable</code> method so that it can be
- used as a <a
- href="https://docs.oracle.com/javase/7/docs/technotes/guides/language/try-with-resources.html">closeable
- resource</a> under Java 7.</p>
-
- <p>Added <code>getContext</code> method returning a hashtable in
- org.apache.log4j.MDC in the log4j-over-slf4j module.
- </p>
-
- <p>The introduction of the @Nonnull JSR 305 annotation in SLF4J
- version 1.7.8 causes the Scala compiler to fail. This is issue has
- been documented in <a
- href="https://issues.scala-lang.org/browse/SI-5420">SI-5420</a>. Given
- that many Scala users will be affected by this issue for the
- foreseeable future, we have decided to renounce the user of JSR 305
- annotations in SLF4J for the time being.
- </p>
-
- <p>Numerous small code improvements too minor to be listed
- here.</p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>4th of April, 2014 - Release of SLF4J 1.7.7 </h3>
-
- <p>SFL4J API now uses generics. This enhancement was contributed by
- Otavio Garcia. Due to erasure of generics in Java, the changes are
- backward-compatible.</p>
-
- <p>The slf4j-migrator can now convert statements using the long deprecated
- <code>Category</code> class.</p>
-
- <p>Added the <code>SimpleLayout</code> and
- <code>FileAppender</code> classes to the log4j-over-slf4j
- module.</p>
-
-
- <h3>February 5th, 2014 - Release of SLF4J 1.7.6</h3>
-
- <p>Added slf4j-android module to the slf4j distribution. This
- module is contributed by Andrey Korzhevskiy.</p>
-
- <p>Loggers created during the initialization phase are no longer
- <code>NOPLoggers</code> which drop all logging calls. Instead,
- SLF4J now creates substitute loggers which delegate to the
- appropriate logger implementation after the initilization phase
- completes. Only calls made to these loggers during the
- initialization phase are dropped. This enhacement was proposed in
- <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=311">bug 311</a>
- by Chetan Mehrotra.
- </p>
-
- <p>Improvements to the <code>exit()</code> and
- <code>throwing()</code> methods in <code>XLogger</code>. This
- enhacement was requested in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=197">bug 197</a>.
- </p>
-
- <p>Concunrrency improvement in <code>MessageFormatter</code>. This
- improvement was contributed by Vivek Pathak in a <a
- href="https://github.com/qos-ch/slf4j/pull/52">pull
- request</a>.</p>
-
- <p>Concunrrency improvement in
- <code>BasicMarkerFactory</code>. This improvement was contributed
- by Mikhail Mazursky in a <a
- href="https://github.com/qos-ch/slf4j/pull/40">pull
- request</a>.</p>
-
- <p><code>JCLLoggerAdapter</code> was incorrectly invoking
- <code>isDebugEnabled</code> calls in its <code>trace()</code>
- methods. This issue was reported in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=281">bug 281</a>.
-
- </p>
-
- <p>In the log4j-over-slf4j module, the <code>setLevel</code>
- method in the <code>Category</code> class. This fixes <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=279">bug
- 279</a>. Alfredo Ramos provied the relevant patch.
- </p>
-
- <p>In the log4j-over-slf4j module, added empty implementations for
- <code>OptionHander</code>, <code>WriterAppender</code>,
- <code>ConsoleAppender</code> and <code>AppenderSkeleton</code>
- classes.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>25th of March, 2013 - Release of SLF4J 1.7.5</h3>
-
- <p class="highlight">Given the significance of these performance
- improvements, users are highly encouraged to migrate to SLF4J
- version 1.7.5 or later. </p>
-
- <p><span class="label notice">performance improvements</span> The
- logger factories in most SLF4J modules namely in jcl-over-slf4j,
- log4j-over-slf4j, slf4j-jcl, slf4j-jdk14, slf4j-log4j12, and
- slf4j-simple now use a <code>ConcurrentHashMap</code> instead of a
- regular <code>HashMap</code> to cache logger instances. This change
- significantly improves logger retrieval times at the cost of some
- memory overhead. This improvement was requested in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=298">bug #298</a>
- by Taras Tielkes who also provided the relevant patch.
- </p>
-
-
- <hr noshade="noshade" size="1"/>
-
- <h3>18th of March, 2013 - Release of SLF4J 1.7.4</h3>
-
- <p>Added a package private <code>reset()</code> method to
- <code>SimpleLoggerFactory</code> for testing purposes.</p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>15th of March, 2013 - Release of SLF4J 1.7.3</h3>
-
- <p>The jul-to-slf4j bridge now correctly handles cases where the
- message string contains {}-placeholders but has no or zero
- parameters. This fixes <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=212">bug
- #212</a>. The relevant patch was provided by Matthew Preston in a
- git pull request.</p>
-
- <p>Added missing methods and classes in log4j-over-slf4j module for
- Velocity compatibility. This issue was reported in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=280">bug 280</a> by
- Thomas Mortagne.</p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>11th of October, 2012 - Release of SLF4J 1.7.2</h3>
-
- <p>Added osgi-over-slf4j module which serves as an OSGi LogService
- implementation delegating to slf4j. This module is maintained by
- Matt Bishop and Libor Jelinek.</p>
-
- <p> Christian Trutz added missing PatternLayout class as well as
- several methods in the <code>Logger</code> and
- <code>Category</code> classes. See commit 442e90ba5785cba9 dated
- September 27th 2012 for details.
- </p>
-
- <p>Added org.slf4j.simpleLoggerwarnLevelString in slf4j-simple
- module.</p>
-
- <p>Fixed <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=272">bug
- 272</a>. All <code>Logger</code> implementations shipping with
- SLF4J use <code>Object...</code> instead of <code>Object[]</code>
- to avoid compiler warnings.</p>
-
-
-
- <hr noshade="noshade" size="1"/>
-
- <h3>14th of September, 2012 - Release of SLF4J 1.7.1</h3>
-
- <p><a
- href="apidocs/org/slf4j/impl/SimpleLogger.html"><code>SimpleLogger</code></a>
- now supports writing to a file. The property names for configuring
- <code>SimpleLogger</code> have been modified to be consistently in
- camel case. More configuration options have been added. In the
- absence of configuration directives, <code>SimpleLogger</code> will
- behave exactly the same as in the past. <b>If you are one of the
- few users configuring <code>SimpleLogger</code> with configuration
- properties, you will need to adapt to the new and more consistent
- property names.</b></p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>6th of September, 2012 - Release of SLF4J 1.7.0</h3>
-
- <p><span class="bold big green">SLF4J now requires JDK 1.5.</span></p>
-
- <p>Printing methods in the <a
- href="apidocs/org/slf4j/Logger.html">Logger</a> interface now offers
- variants accepting <a
- href="http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html">varargs</a>
- instead of Object[]. Given that under the hood, the Java compiler
- transforms varargs into an array, this change is totally 100%
- no-ifs-or-buts backward compatible with all existing client
- code. </p>
-
- <p>The logger field (of type <code>java.util.logging.Logger</code>)
- in <code>JDK14LoggerAdapter</code> is now marked as transient. This
- fixes <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=261">bug
- #261</a>, a serialization problem reported by Thorbj&oslash;rn Ravn
- Andersen.</p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>11th of June, 2012 - Release of SLF4J 1.6.6</h3>
-
- <p>Source repository has been moved to <a
- href="https://github.com/qos-ch/slf4j">https://github.com/qos-ch/slf4j</a>
- on github.</p>
-
- <p>In case multiple bindings are found on the class path, SLF4J
- will now output the name of the framework/implementation class it
- binds with.</p>
-
- <p><a
- href="apidocs/org/slf4j/impl/SimpleLogger.html">SimpleLogger</a>
- now supports configuration properties. </p>
-
- <p>LoggerWrapper in the slf4j-ext module now correctly deals with
- markers. This fixes <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=265">bug #265</a>
- reported by Dario Campagna.</p>
-
- <p>The log4j-over-slf4j module now supports legacy projects
- providing their own log4j <code>LoggerFactory</code>. This fixes <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=234">bug #234</a>
- reported by Laurent Pellegrino with Piotr Jagielski providing the
- appropriate patch.</p>
-
- <h3>4th of June, 2012 - Release of SLF4J 1.6.5</h3>
-
- <p>In the slf4j-log4j12 module, upgraded the log4j dependency to
- version 1.2.17.</p>
-
- <p>Added removeHandlersForRootLogger() method to <code><a
- href="apidocs/org/slf4j/bridge/SLF4JBridgeHandler.html">SLF4JBridgeHandler</a></code>
- class.</p>
-
- <p>The log4j-over-slf4j module now exports all its packages in its
- manifest. This issue was reported in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=262">262</a> by
- Mikhail Mazursky who also provided the relevant patch.
- </p>
-
- <h3>October 31st, 2011 - Release of SLF4J 1.6.4</h3>
-
- <p>Fixed in thread-safety issues in <code>BasicMDCAdapter</code>
- fixing <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=203">bug
- #203</a> and <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=224">bug
- #224</a>. Note that <code>BasicMDCAdapter</code> is only used with
- the slf4j-jdk14.jar binding.
- </p>
-
- <p><code>BasicMDCAdapter</code> invoked a method introduced in JDK
- 1.5 preventing it from running under JDK 1.4. Interestingly enough,
- this issue has never been reported by the user community.</p>
-
- <h3>October 17th, 2011 - Release of SLF4J 1.6.3</h3>
-
- <p><code>LogEvent</code> class in slf4j-ext module now correctly
- passes the event data as a parameter object. This fixes <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=246">bug #246</a>
- reported by Ralph Goers.
- </p>
-
- <p>Added missing OSGi manifest to the jul-to-slf4j module. This
- fixes <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=166">bug
- #166</a> reported by Ekkehard Gentz. </p>
-
- <p>In the log4j-over-slf4j module, added missing
- <code>getAllAppenders</code>() method in <code>Category</code>
- class. This fixes <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=235">bug #235</a>
- reported by Anthony Whitford.
- </p>
-
- <h3>August 19th, 2011 - Release of SLF4J 1.6.2</h3>
-
- <p>Fixed <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=138">bug
- #138</a>. SLF4J will no longer complain about multiple SLF4J
- bindings when running under a Weblogic server.
- </p>
-
- <p>Fixed <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=228">bug
- #228</a>. When running under IBM's JDK, and if no binding can be
- found, SLF4J will no longer throw a
- <code>NoClassDefFoundError</code>. Instead, it will default to an
- NOP implementation. Under the same circumstances but with Sun's
- JDK, SLF4J already defaulted to an NOP implementation since release
- 1.6.0.</p>
-
- <p>Added certain missing classes to the log4j-over-slf4j module as
- requested in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=225">bug 225</a> by
- Josh Stewart.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>July 5th, 2010 - Release of SLF4J 1.6.1</h3>
-
- <p>Updated log4j dependency to version 1.2.16 and <a
- href="http://cal10n.qos.ch/">CAL10N</a> dependency to version
- 0.7.4.
- </p>
-
- <p>Fixed missing versioning OSGi metadata in the log4j-over-slf4j
- module. This problem was reported in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=187">bug 187</a> by
- David Savage.
- </p>
-
-
-
- <hr noshade="noshade" size="1"/>
-
- <h3>May 8th, 2010 - Release of SLF4J 1.6.0</h3>
-
- <p>It is expected that <em>all</em> SLF4J releases in the 1.6.x
- series will be mutually compatible.
- </p>
-
- <p>As of SLF4J version 1.6.0, in the absence of an SLF4J binding,
- slf4j-api will default to a no-operation implementation discarding
- all log requests. Thus, instead of throwing an exception, SLF4J
- will emit a single warning message about the absence of a binding
- and proceed to discard all log requests without further
- protest. See also the <a href="manual.html#libraries">relevant
- section</a> in the user manual.
- </p>
-
- <p>In the presence of multiple parameters and if the last argument
- in a logging statement is an exception, then SLF4J will now presume
- that the user wants the last argument to be treated as an exception
- and not a simple parameter. See the relevant <a
- href="faq.html#paramException">FAQ entry</a> for further
- details. This fixes <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=70">bug 70</a>
- submitted by Joern Huxhorn who also provided the relevant patch.
- </p>
-
- <p>The <code>log</code> method in <code>LocationAwareLogger</code>
- interface now admits an additional parameter of type
- <code>Object[]</code> representing additional arguments of the log
- request. Due to this modification, slf4j-api version 1.6.x will not
- work with bindings shipping with SLF4J 1.5.x -- bindings shipping
- with 1.6.x must be used.
- </p>
-
-
- <p>Fixed <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=150">bug 150</a> by
- implementing missing <code>resetConfiguration()</code> and
- <code>shutdown()</code> methods in <code>LogManager</code> (in
- log4j-over-slf4j) as nop. In addition, the
- <code>getCurrentLoggers()</code> method has been implemented by
- returning an empty enumeration.
- </p>
-
-
- <p>Fixed <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=170">bug 170</a> by
- a bare-bones implementation of the <code>NDC</code> class in
- log4j-over-slf4j.</p>
-
- <p>Fixed <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=175">bug 175</a> by
- synchronizing access to the loggerNameList field.</p>
-
- <p>Fixed <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=164">bug 164</a>
- observed when SLF4J artifacts were placed under
- java.endorsed.dirs.</p>
-
- <p>Fixed sub-optimal list type usage in
- <code>SLF4JLogFactory</code> as reported in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=179">bug 179</a> by
- Sebastian Davids.
- </p>
-
-
- <p>Fixed documentation inconsistency in <code>SLF4JLog</code> as
- reported in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=180">bug 180</a> by
- Sebastian Davids.
- </p>
-
-
- <hr noshade="noshade" size="1"/>
-
- <h3>February 25th, 2010 - Release of SLF4J 1.5.11</h3>
-
-
- <p>Users yet unfamiliar with SLF4J sometimes unknowingly place both
- <em>log4j-over-slf4j.jar</em> and <em>slf4j-log4j12.jar</em>
- simultaneously on the class path causing stack overflow
- errors. Simultaneously placing both <em>jcl-over-slf4j.jar</em> and
- <em>slf4j-jcl.jar</em> on the class path, is another occurrence of
- the same general problem. As of this version, SLF4J preempts the
- inevitable stack overflow error by throwing an exception with
- details about the actual cause of the problem. This is deemed to be
- better than leaving the user wondering about the reasons of the
- <code>StackOverflowError</code>.
- </p>
-
- <p>Fixed <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=168">bug
- 168</a>. In case log4j-over-slf4j is used and a logback appender
- requires a third party library which depends on log4j, the
- <code>log(String FQCN, Priority p, Object msg, Throwable t)</code>
- method in log4j-over-slf4j's Category class would throw an
- <code>UnsupportedOperationException</code>. Problem reported by Seth
- Call.</p>
-
-
- <hr noshade="noshade" size="1"/>
-
- <h3>December 3rd, 2009 - Release of SLF4J 1.5.10</h3>
-
- <p>SLF4J version 1.5.10 consist of bug fixes and minor
- enhancements. It is totally backward compatible with SLF4J version
- 1.5.8. However, the slf4j-ext module ships with a new package called
- <code>org.slf4j.cal10n</code> which adds <a
- href="localization.html">localized/internationalized logging</a>
- support as a thin layer built upon the <a
- href="http://cal10n.qos.ch">CAL10N API</a>.</p>
-
- <p><a href="http://www.slf4j.org/android/">SLF4J-android</a>,
- maintained by <a
- href="http://dbis.cs.unibas.ch/team/thorsten-moller/dbis_staff_view">Thorsten
- M&ouml;ller</a>, was added as a daughter project of SLF4J.
- </p>
-
- <p>Added missing "Export-Package" declaration for cal10n in the OSGi
- manifest file for sfl4j-ext. This was requested in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=156">bug 156</a> by
- Pete Muir.</p>
-
- <p>In log4j-over-slf4j, added missing log(...) methods as requested
- by Zoltan Szel in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=139">bug report
- 139</a>.</p>
-
- <p>In log4j-over-slf4j, added missing <code>LogManager</code> class
- as requested by Rick Beton in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=150">bug report
- 150</a>.</p>
-
- <p>In the slf4j-ext module, added
- <code>getCopyOfChildTimeInstruments</code> and
- <code>getCopyOfGlobalStopWatch</code> methods to the
- <code>Profiler</code> class. This enables developers to build their
- own output formatters for a given Profiler. This feature was
- requested by David Lindel&ouml;f in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=141">bug 141</a>.
- </p>
-
- <p>Fixed a <code>NullPointerException</code> occurring in unspecified
- conditions as described in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=146">bug report
- 146</a> by Dapeng Ni.</p>
-
- <p>Added missing OSGi manifest to the <em>log4j-over-slf4j</em>
- module as requested by Wade Poziombka in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=117">bug 117</a>.
- </p>
-
- <p>OSGi manifests produced by SLF4J now replace the '-' character by
- '.' in compliance with the OSGi specification. This fixes <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=152">bug 152</a>
- according to the patch supplied by Hugues Malphettes.
- </p>
-
- <p>Fixed packaging issue in jcl104-over-slf4j which inadvertently
- produced a jar file as described in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=151">bug 151</a> by
- Jesse McConnell.</p>
-
-
-
-
- <hr noshade="noshade" size="1"/>
-
- <h3>June 11th, 2009 - Release of SLF4J 1.5.8</h3>
-
- <p>SLF4J version 1.5.8 consist of bug fixes. It is totally backward
- compatible with SLF4J version 1.5.7.</p>
-
- <p>The Maven pom file for the <code>log4j-over-slf4j</code> module
- contained a compile time dependency on the <code>slf4j-jdk14</code>
- module. The dependency should have been declared in the test
- scope. This problem was reported by Jean-Luc Geering on the slf4j
- user list.
- </p>
-
- <h3>June 10th, 2009 - Release of SLF4J 1.5.7</h3>
-
- <p>SLF4J version 1.5.7 consist of bug fixes and minor
- enhancements. It is totally backward compatible with SLF4J version
- 1.5.6.</p>
-
- <p>In SLF4J versions 1.5.5 and 1.5.6, the <code>LoggerFactory</code>
- class which is at the core of SLF4J, if a version compatibility
- issue was detected, accidentally invoked a method which was
- introduced in JDK 1.5. Thus, instead of issuing a clear warning
- message, SLF4J would throw a
- <code>NoClassDefFoundError</code>. Consequently, SLF4J would not run
- with JDK 1.4 and earlier but only if a version incompatibility issue
- was present. For example, if you were mixing
- <em>slf4j-api-1.5.6.jar</em> with <em>slf4j-simple-1.4.2.jar</em>,
- which are mutually incompatible. Please note that this bug affects
- only SLF4J versions 1.5.5 and 1.5.6 <em>and</em> only in the
- presence of incompatible versions of slf4j-api and its binding.
- </p>
-
- <p>SLF4J will now emit a warning if more than one binding is present
- on the class path. This enhancement was proposed in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=132">bug 132</a>
- contributed by by Robert Elliot.
- </p>
-
- <p>The Log interface implementations in the jcl-over-slf4j module
- will now correctly cope with serialization. This fixes <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=79">bug 79</a>
- reported by Mathias Bogaert. Many thanks to Eric Vargo for precisely
- identifying the problem and supplying the corresponding patch.</p>
-
- <p>The log4j-over-slf4j module will now correctly
- interact with logging frameworks supporting location information
- such as java.util.logging and logback. This fixes <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=131">bug 131</a>
- reported by Marc Zampetti.
- </p>
-
- <p><code>SLF4JBridgeHandler</code> will no longer ignore log records
- with an empty message. This fixes <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=108">bug 108</a>
- reported by Pepijn Van Eeckhoudt and independently by Dan Lewis.
- </p>
-
- <p>In case the <code>toString()</code> method of a parameter throws
- an exception, <code>MessageFormatter</code> will now print an error
- message, instead of letting the exception bubble higher up as
- previously. This fixes <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=112">bug 112</a>
- submitted by Joern Huxhorn.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>November 21st, 2008 - Release of SLF4J 1.5.6</h3>
-
- <p>SLF4J version 1.5.6 consists of bug fixes. Users are encouraged
- to upgrade to SLF4J version 1.5.6. The upgrade should pose no
- problems. Nevertheless, you might still want to refer to the SLF4J
- <a href="compatibility.html">compatibility report</a>.
- </p>
-
- <p>Fixed long standing <a
- href="http://jira.qos.ch/browse/LBCLASSIC-87">LBCLASSIC-87</a> and
- its younger sibling <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=113">bug
- 113</a>. With each call to getLogger() method,
- <code>LoggerContext</code> will now retrieve the ILoggerFactory
- afresh from <code>StaticLoggerBinder</code>. This change enables
- context selectors of native implementations, e.g logback, to work
- correctly.
- </p>
-
- <p>Fixed <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=114">bug
- 114</a> reported by Jason Arndt. Corrected the way
- <code>XLogger</code> (in slf4j-ext) passes its fully qualified class
- name so that the underlying logging system can correctly compute
- location information.
- </p>
-
-
- <p>The <code>install()</code> method of
- <code>SLF4JBridgeHandler</code> will no longer reset the entire
- j.u.l. environment but solely add a <code>SLF4JBridgeHandler</code>
- instance to jul's root logger. By the same token, the
- <code>uninstall()</code> method will remove previously added
- <code>SLF4JBridgeHandler</code> instances without making any other
- modifications to the j.u.l. configuration.
- </p>
-
- <p>Added <code>MDCStrLookup</code> to slf4j-ext. This class can be
- used with Apache Commons Lang's <code>StrSubstitutor</code> class to
- inject values in the SLF4J MDC into strings. Information on
- StrSubstitutor can be found at <a
- href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/text/StrSubstitutor.html">StrSubstitutor
- javadoc</a>.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>October 17th, 2008 - Release of SLF4J 1.5.5</h3>
-
- <p>The version check mechanism introduced in SLF4J 1.5.4 was
- inconsistent with the large size of SLF4J's installed user base. We
- cannot expect external SLF4J implementations to align their release
- schedule with that of SLF4J. Consequently, this SLF4J version,
- namely 1.5.5, retains versions checks but as an elective
- process. For further details see the <a
- href="faq.html#version_checks">relevant entry</a> in the FAQ.
- </p>
-
- <p>You are highly encouraged to upgrade to SLF4J version 1.5.5. The
- upgrade should pose no problems. Nevertheless, you might still want
- to refer to the SLF4J <a href="compatibility.html">compatibility
- report</a>.
- </p>
-
- <h3>October 16th, 2008 - Release of SLF4J 1.5.4</h3>
-
- <p>This version corrects critical bugs.
- </p>
-
- <p>Fixed <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=106">critical bug
- 106</a>. In previous versions of SLF4J, if during the initial
- binding phase, the underlying logging system's default configuration
- created or invoked loggers, a <code>NullPointerException</code>
- would be thrown. Refer to the <a
- href="codes.html#substituteLogger">in error codes</a> document for a
- fuller explanation.</p>
-
- <p>At initialization time, LoggerFactory will now check that the
- version of the slf4j-binding matches that of slf4j-api. If there is
- a mismatch a warning will be issued on the console. This should help
- users identify SLF4J related problems more quickly.</p>
-
- <p>Improvements in documentation as well as fix for <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=102">packaging
- problems</a> related to <em>slf4j-ext</em> module.
- </p>
-
- <p>SLF4JBridgeHandler (part of jul-to-slf4j) now accounts for
- loggers with resourceBundle as well parameters. This feature
- requested by Darryl Smith in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=98">bug 98</a> and
- by Jarek Gawor in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=103">bug
- 103</a>.</p>
-
- <p>We now say that markers contain <em>references</em> to other
- markers. We no longer talk about child markers. The javadocs of the
- <code>Marker</code> interface have been updated to reflect this
- change. Moreover, the <code>hasChildren()</code> method in the
- Marker interface has been deprecated and a new method called
- <code>hasReferences()</code> was added.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>September 12th, 2008 - Release of SLF4J 1.5.3</h3>
-
- <p>See also the <a href="compatibility.html#1_5_3">compatibility
- report for this version</a>.
- </p>
-
- <p>Added a new module called slf4j-ext for slf4j-extensions. See <a
- href="extensions.html">its documentation</a> for further
- details.</p>
-
- <p>Fixed <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=71">bug
- 71</a> which was re-opened by Manfred Geiler. SLF4J loggers now
- survive serialization. By survive serialization, we mean
- that the deserialized logger instance are fully functional. </p>
-
- <p>The fix for <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=68">bug 68</a> as
- implemented in version 1.5.1 was incomplete. Michael Furman supplied
- a more complete fix which was incorporated in this release.</p>
-
- <p>When slf4j bridges, e.g. jcl-over-slf4j or log4j-over-slf4j, were
- used in conjunction with JUL as the underlying logging system,
- JDK14LoggerAdapter created a LogRecord even for disabled log
- statements. This performance issue was reported in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=90">bug 90</a> by
- Matthew Mastracci.
- </p>
-
- <p>Added support for array values, including multi-dimensional
- arrays, as parameters. For example,</p>
- <p class="source">log.debug("{} {}", "A", new int[] {1, 2}});</p>
- <p>will print as "A [1, 2]" instead of "A [I@6ca1c" as
- previously. This enhancement was proposed by "lizongbo".
- </p>
-
- <p>Parameter substitution code has been simplified. SLF4J now only
- cares about the "{}" formatting anchor, that is the '{' character
- immediately followed by '}'. Previously, the '{' had meaning on its
- own. As a result of this change, users no longer need to escape the
- '{' unless it is immediately followed by '}'. Existing messages
- which escaped standalone '{' character will be printed with a
- preceding backslash. However, no data loss in the printed messages
- will occur.
- </p>
-
- <p>Added missing <code>getInstance</code> methods to the
- <code>Category</code> class in the log4j-over-slf4j module, fixing
- <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=95">bug 95</a>
- reported by Michael Rumpf.</p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>June 8th, 2008 - Release of SLF4J 1.5.2</h3>
-
- <p>Improvements to SLF4J documentation as well as fix of <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=88">packaging
- problems</a> related to <em>jul-to-slf4j.jar</em> and
- <em>jcl104-over-slf4j.jar</em>.
- </p>
-
- <h3>June 5th, 2008 - Release of SLF4J 1.5.1</h3>
-
- <p>See also the <a href="compatibility.html#1_5_1">compatibility
- report for this version</a>.</p>
-
- <p>In order to support JCL version 1.1.1, the
- <em>jcl<b>104</b>-over-slf4j</em> module was renamed as
- <em>jcl-over-slf4j</em>. SLF4J will no longer ship with
- <em>jcl104-over-slf4j.jar</em> but with <em>jcl-over-slf4j.jar</em>.
- The related work responds to enhancement request discussed in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=85">bug 85</a> as
- reported by Niklas Gustavsson.
- </p>
-
- <p>The <em>slf4j-jcl</em> binding now depends on commons-logging
- version 1.1.1 instead of the older 1.0.4</p>
-
-
- <p>Added a java.util.logging to SLF4J bridge as requested in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=38">bug 38</a> by
- Christian Stein, David Smiley, Johan Ferner, Joern Huxhorn and
- others.
- </p>
-
- <p>Fixed <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=68">bug
- 68</a> reported by Su Chuan and David Rauschenbach. SLF4J requires
- log4j 1.2.12 or later. However, if an older version of log4j is
- present (lacking the TRACE level), in order to avoid
- NoSuchMethodError exceptions, the SLF4J's
- <code>Log4jLoggerAdapter</code> will map the TRACE level as DEBUG.
- </p>
-
-
- <p>Fixed <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=78">bug
- 78</a> reported by Venu Thachappilly. If the argument array passed
- to a Logger printing method (debug, info, etc.) was null, a
- <code>NullPointerException</code> was thrown. With the correction,
- the messagePattern is returned as is, without parameter
- substitution.
- </p>
-
-
- <p>Added the <code>getCopyOfContextMap</code> and
- <code>setContextMap</code> methods to the <code>MDCAdapter</code>
- and <code>org.sf4j.MDC</code> classes. This was requested in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=84">bug 84</a> by
- Anton Tagunov.
- </p>
-
- <p>Fixed <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=74">bug
- 74</a>, an endless recursion problem in Marker.contains method,
- reported by Michael Newcomb. Also added he
- <code>getDetachedMarker</code> method to <code>IMarkerFactor</code>
- and <code>MarkerFactory</code> classes which was indirectly
- requested in bug 74.
- </p>
-
- <p>Added the methods <code>getLevel()</code> and
- <code>getEffectiveLevel()</code> to the <code>Category</code> class
- in log4j-over-slf4j. This addition was requested in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=74">bug 74</a> by
- Michael Newcomb.
- </p>
-
- <p>The <a href="migrator.html">SLF4J Migrator</a>
- tool has been improved to support migration from JUL to SLF4J.
- </p>
-
- <p>In <code>MarkerIgnoringBase</code> class, corrected mapping of
- trace methods with markers to their equivalents without marker
- data. Previously, the mapping was trace to debug. The incorrect
- mapping affected only calls to the trace method with
- markers. Interestingly enough, this bug was picked up by new unit
- tests and has not been reported as a bug by our users.
- </p>
-
-
- <h3>February 26th, 2008 - Release of SLF4J 1.5.0</h3>
-
-
- <p>A tool called <a href="migrator.html">SLF4J Migrator</a> now
- ships with SLF4J. It can help you migrate your project using JCL or
- log4j to use SLF4J instead.
- </p>
-
- <p>Fixed <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=61">bug
- 61</a> reported by Christopher Sahnwaldt. It is now possible to
- place a backslash in front of a formatting anchor, by escaping the
- backslash. For example, the call to
- <code>MessageFormatter.format("C:\\\\{}", "foo")</code> will now
- correctly return "C:\\foo". The backslash character needs to be
- escaped in Java, which leads to four backslashes.
- </p>
-
-
- <p>Fixed <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=63">bug
- 63</a> reported by Maarten Bosteels. SLF4J now supports MDC for
- <code>java.util.logging</code> package.
- </p>
-
- <p>Fixed <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=64">bug
- 64</a> reported by Michal Bernhard. The log4j binding will now alert
- the user if she uses SLF4J with a version of log4j earlier than 1.2.12.
- </p>
-
- <p>Fixed <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=65">bug
- 65</a> reported by Ben Gidley. Superfluous
- &lt;version>$&#x7B;parent.version}&lt;/version> lines have been
- removed from pom.xml files. These lines reportedly confuse certain
- Maven repositories.
- </p>
-
- <p>In the <code>org.apache.log4j.Category</code> class, as
- implemented in the log4j-over-slf4j module, calls to the printing
- trace() are now correctly mapped to SLF4J's trace() printing method
- (instead of debug()). Superfluous printing methods with the
- signature <code>xxxx(Object, Object)</code> and <code>xxxx(String,
- Object, Object)</code> have been removed.
- </p>
-
- <p>Fixed <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=67">bug
- 67</a> reported by Chris Custine. The manifest file for
- jcl104-over-slf4j now correctly declares version 1.0.4 for the
- exported JCL packages.
- </p>
-
-
- <p>Fixed <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=69">bug
- 69</a> reported by Joern Huxhorn, who graciously supplied the fix as
- well as a test case. The <code>add</code> method in
- <code>BasicMarker</code> class now correctly prevents multiple
- addition of the same child. Moreover, the <code>remove</code> method
- now correctly removes the specified child marker.
- </p>
-
- <p>Fixed <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=41">bug
- 41</a> reported by Sebastian Davids. The manifest files of various
- projects now mention J2SE-1.3 as the required execution
- environment.
- </p>
-
- <p>Fixed <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=71">bug
- 71</a> reported by Manfred Geiler. The SLF4JLog and
- SLF4JLocationAwareLog classes are now serializable solving
- serialization problems encountered with certain libraries which
- attempt to serialize JCL log instances.
- </p>
-
- <p>Fixed <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=73">bug
- 73</a> reported by Oleg Smirsky. A "Fragment-Host: slf4j.api" line
- has been added to every MANIFEST.MF file exporting
- <code>org.slf4j.impl</code>.
- </p>
-
-
- <p>Fixed <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=72">bug
- 72</a> reported by Ian Carr. Performance issues with slf4j-jdk14 for
- disabled log statements have now been corrected.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>August 20th, 2007 - Release of SLF4J 1.4.3</h3>
-
- <p>Fixed <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=60">bug
- 60</a> as reported by Costin Leau. OSGI manifest entries now declare
- the correct SLF4J version.
- </p>
-
- <p>Clarified the behavior of the various methods methods in the MDC
- class with respect to "null" parameters. This was requested in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=58">bug 58</a> by
- Sebastian Davids.
- </p>
-
- <p>Removed the slf4j-archetype module because nobody seems to have a
- use for it.</p>
-
- <h3>July 12th, 2007 - Release of SLF4J 1.4.2</h3>
-
- <p>The <a href="log4j-over-slf4j.html">log4j-over-slf4j</a> module
- has been moved back into SLF4J. Originally, this module was part of
- SLF4J and was moved into logback due to the lack of MDC support in
- SLF4J. With version 1.4.2 and the addition of MDC support in SLF4J
- 1.4.1, log4j-over-slf4j returns to its original home. Note that the
- previous name of the module was <a
- href="http://logback.qos.ch/bridge.html">log4j-bridge</a>.
- </p>
-
- <p>Addition of the <code>getMDCAdapter</code> method to
- org.slf4j.MDC class. This allows access to the actual MDC
- implementation which can on occasion come in very handy.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
-
-
- <h3>July 4th, 2007 - Release of SLF4J 1.4.1</h3>
-
-
- <p>SLF4J now supports <a href="manual.html#mdc">Mapped Diagnostic
- Contexts</a> (MDC) as requested by Andy Gerweck and Steve Ebersole
- in <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=49">bug
- 49</a>.
- </p>
-
- <p>Fixed <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=53">bug
- 53</a> as reported by Heinrich Nirschl. The public method
- <code>trace(String)</code> in the <code>Log4jLoggerAdapter</code>
- class incorrectly called the underlying log4j logger with level DEBUG
- instead of TRACE.
- </p>
-
- <p>Fixed various documentation related errors kindly reported by
- Mark Vedder.
- </p>
-
-
- <hr noshade="noshade" size="1"/>
-
-
- <h3>May 16th, 2007 - Release of SLF4J 1.4.0</h3>
-
-
- <p>In response to many user requests over time, the TRACE level has
- been added to <a
- href="api/org/slf4j/Logger.html">org.slf4j.Logger</a>
- interface. Please also see the <a href="faq.html#trace">FAQ entry
- discussing</a> the TRACE level.
- </p>
-
-
- <p>Fixed <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=47">bug
- 47</a> as reported by Terry Todd. In previous a SLF4J release the
- <code>org.apache.commons.logging.impl.SLF4FLogFactory</code> class
- was renamed as <code>SLF4JLogFactory</code>. The
- <em>META-INF/services/org.apache.commons.logging.LogFactory</em>
- resource file had not reflected this change. It does now.
- </p>
-
-
- <p>Eric Yung <a
- href="http://www.slf4j.org/pipermail/user/2007-April/000327.html">reported</a>
- that Apache commons-configuration access certain commons-logging
- classes, namely <code>org.apache.commons.logging.impl.NoOpLog</code>
- and SimpleLog, directly. Following Eric's suggestion,
- jcl104-over-slf4j now includes the aforementioned classes.
- </p>
-
-
- <hr noshade="noshade" size="1"/>
-
- <h3>April 15th, 2007 - Release of SLF4J 1.3.1</h3>
-
-
- <p>In response to a <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=39">enhancement
- request</a> made by Michael Newcomb, a marker can now be detached
- from the internal list of the <code>MarkerFactory</code> that
- generated it.
- </p>
-
- <p>Fixed a silly but nonetheless annoying bug where log request of
- level ERROR made through jcl104-over-slf4j would log twice. This bug
- was <a
- href="http://www.slf4j.org/pipermail/user/2007-April/000323.html">reported</a>
- and precisely described by Andrew Cooke.
- </p>
-
-
- <hr noshade="noshade" size="1"/>
-
- <h3>February 25th, 2007 - Release of SLF4J 1.3.0</h3>
-
- <p>This release consists of rearrangement of classes among
- projects. More specifically, the
- <code>org.slf4j.LoggerFactory</code> class is now packaged within
- the <em>slf4j-api.jar</em> file instead of the various slf4j
- bindings. <b>It follows that client code needs to depend on only
- slf4j-api in order to compile, while the various slf4j bindings are
- only needed as runtime dependencies.</b> See also the <a
- href="faq.html#maven2">Maven2-related FAQ entry</a>. Given the
- practical significance of this change, we highly recommend that
- library-authors upgrade to version 1.3 at their earliest
- convenience.
- </p>
-
- <p><a href="http://bugzilla.slf4j.org/show_bug.cgi?id=23">Bug number
- 23</a> has been fixed, at the cost of minor and backward compatible
- changes. In other words, jcl104-over-slf4j now preserves caller
- location information.
- </p>
-
- <p>It is now possible to obtain the root logger of the underlying
- logging implementation by requesting a logger named
- &quot;ROOT&quot;. This feature was requested by Sebastien Davids
- in <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=35">bug
- report 35</a>. </p>
-
- <p>For an exact list of changes please refer to the <a
- href="changes/changes-1.3.txt">1.3.0 compatibility report</a> file
- as generated by clirr.</p>
-
-
- <hr noshade="noshade" size="1"/>
-
- <h3>January 24th, 2007 - Release of SLF4J 1.2</h3>
- <p>This release includes several modifications to make SLF4J
- an <a href="http://www.osgi.org/">OSGi</a>-friendly framework.
- The modules' MANIFEST.MF files now include
- OSGi metadata. Regarding these improvements, and OSGi in general, the
- SLF4J project is happy to welcome John E. Conlon as a new committer.
- </p>
-
- <p>Marker objects are now Serializable.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>December 21st, 2006 - Release of SLF4J 1.1.0 (final)</h3>
-
- <p>This release consists of minor bug fixes and documentation
- changes. More importantly, the log4j-over-slf4j module has been
- moved to the logback project, under the name <a
- href="http://logback.qos.ch/bridge.html">log4j-bridge</a>.
- </p>
-
- <p>Added the file "org.apache.commons.logging.LogFactory" under
- META-INF/services directory which went missing in the 1.1.0 series
- of SLF4J. This fixes a compatibility problem with Apache Axis which
- uses its own discovery mechanism, namely, commons-discovery version
- 0.2. The problem was reported in bug <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=33">report 33</a>
- by David Varnes.
- </p>
-
- <p>The file jcl104-over-slf4j.jar had various entries missing in its
- MANIFEST.MF file, as reported by Boris Unkel in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=30">bug number
- 30</a>.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>November 16th, 2006 - Release of SLF4J 1.1.0-RC1</h3>
-
- <p>This release consists of packaging related bug fix in addition to
- minor documentation changes.
- </p>
-
- <p>Contrary to RC0, RC1 no longer uses SNAPSHOT versions for the
- slf4j-parent pom. The solution to <a
- href="http://ceki.blogspot.com/2006/11/solution-to-maven2-version-number.html">Maven
- version problem</a> does not work for public projects such as SLF4J
- because SNAPSHOTs are not allowed on ibiblio.
- </p>
-
-
- <hr noshade="noshade" size="1"/>
-
- <h3>November 4th, 2006 - Release of SLF4J 1.1.0-RC0</h3>
-
- <p>This release consists of bug fixes. Moreover, since the major
- packaging related changes in 1.1.0-beta0 seem to work well, this
- release is marked as RC0.</p>
-
- <p>Fixed the JDK 1.5 dependency for the SLF4J build, as reported by
- Boris Unkel in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=28">bug number
- 28</a>. SLF4J now explicitly declares a dependency on JDK 1.4 in its
- pom.xml file.
- </p>
-
- <p>Fixed an incorrect reference to the logback project in slf4j-api
- pom file. This bug was reported by Boris Unkel in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=29">bug number
- 29</a>.
- </p>
-
- <p>Fixed a synchronization problem in factories of almost all SLF4J
- bindings. This bug was reported independently by Howard M. Lewis Ship
- and Boris Unkel in bug reports <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=26">26</a> and
- respectively <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=26">27</a>.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>September 7th, 2006 - Release of SLF4J 1.1.0-beta0</h3>
-
- <p>Release 1.1.0-beta0 is a relatively important release with a
- refactoring of the way class files are organized in jar files. In
- previous releases, each binding was self-contained in a single jar
- file. In this release, each and every binding depends on
- <em>slf4j-api.jar</em> which contains the bulk of the classes
- required to use SLF4J, except for one or two adapter classes. Only
- the adapter classes are now shipped with each specific binding jar
- as appropriate for the underlying logging system..
- </p>
-
- <p>This release is built using Maven instead of Ant. As for the java
- code, it has not been changed.</p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>June 8th, 2006 - Release of SLF4J 1.0.2</h3>
-
- <p>Release 1.0.2 is a maintenance release containing bug fixes
- only.</p>
-
- <ul>
-
- <li>Fixed <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=22">bug number
- 22</a> reported by Bjorn Danielsson. This version of the SLF4J API
- will no longer systematically throw an exception when the
- <code>o.a.c.l.impl.SLF4FLogFactory#release()</code> method is
- invoked. Instead, the <code>release()</code> method will issue a
- <a href="http://www.slf4j.org/codes.html">warning</a>.
-
- </li>
-
- </ul>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>May 1st, 2006 - Release of SLF4J 1.0.1</h3>
-
- <p>Release 1.0.1 is a maintenance release containing bug fixes
- only.</p>
-
- <ul>
-
- <li>Fixed <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=20">bug number
- 20</a> reported by Steve Bate. <code>JDK14LoggerAdapter</code>
- will now correctly relay the logger name to the underlying JDK 14
- logging system.
- </li>
-
- <li>Added the file "org.apache.commons.logging.LogFactory" under
- META-INF/services directory in the jcl104-over-slf4j jar
- file. This fixes a compatibility problem with Apache Axis which
- uses its own discovery mechanism, namely, commons-discovery
- version 0.2. The bug was reported by Dave Wallace.
- </li>
-
- </ul>
-
-
- <hr noshade="noshade" size="1"/>
-
- <h3>March 8th, 2006 - Release of SLF4J 1.0</h3>
-
- <p>This is release labeled as 1.0 (final) contains few relatively
- minor changes:
- </p>
-
- <ul>
- <li>As <a
- href="http://marc.theaimsgroup.com/?t=114063163800004">discussed</a>
- on the slf4j user list, <code>SimpleLogger</code> now directs its
- output to stderr instead of stdout.
- </li>
-
- <li>Modified <code>JDK14LoggerAdapter</code> so that caller
- information is now correctly printed, as reported in <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=13">bug 13</a> by
- Peter Royal.
- </li>
-
- <li>Minor additions to the Marker interface.</li>
-
- </ul>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>February 4th, 2006 - Release of SLF4J 1.0-RC6 and NLOG4J
- 1.2.22</h3>
-
- <p>The <code>MarkingLogger</code> interface has been removed and its
- contents merged into <code>org.slf4j.Logger</code>. This change
- should not adversely affect end-users. However, SLF4J bindings need
- to be updated. This has been done for all the bindings shipped with
- SLF4J distribution as well as NLOG4J. As for x4juli, the update is
- planned for its next release.
- </p>
-
- <p>The merge between the <code>MarkingLogger</code> and
- <code>Logger</code> interfaces has been motivated by the need to
- allow end-users to easily switch between logging systems that
- support markers and those that do not.
- </p>
-
- <p>Added a default instance to SimpleLoggerFactory to serve as a
- last resort fallback mechanism. This instance is designed to be used
- by a very specific group of users, namely for those developing
- logging systems (e.g. log4j or LOGBack). It is not intended for
- end-users of the SLF4J API.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>January 9th, 2006 - Release of SLF4J 1.0-RC5 and NLOG4J
- 1.2.21</h3>
-
- <p>A maintenance release correcting bugs <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=11">#11</a> and <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=12">#12</a> and in
- general improved resilience to null input parameters across
- implementations. Many thanks to Boris Unckel and Kenneth for
- reporting the null input issue.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>December 27th, 2005 - Release of SLF4J 1.0-RC4 and NLOG4J
- 1.2.20</h3>
-
-
- <p>The printing methods in <code>org.slf4j.Logger</code> interface
- now support passing 3 or more parameters in an <code>Object</code>
- array. This was a frequently requested feature missing in previous
- versions of SLF4J.
- </p>
-
- <p>NLOG4J 1.2.20 reflects the addition of new methods in the
- <code>org.slf4j.Logger</code> interface.</p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>December 8th, 2005 - Release of SLF4J 1.0-RC3</h3>
-
- <p>Maintenance release fixing reported bugs <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=6">#6</a> and <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=7">#7</a>.
- </p>
-
-
- <h3>November 28th, 2005 - Release of SLF4J 1.0-RC2</h3>
-
- <p>In response to a request by Greg Wilkins, this release adds the
- jar file <em>slf4j-jcl.jar</em>, an SLF4J binding for JCL. Please
- read the <a href="manual.html#gradual">gradual migration section</a>
- in the manual for more details.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>November 21st, 2005 - Release of SLF4J 1.0-RC1</h3>
-
- <p>A maintenance release correcting bugs <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=4">#4</a> and <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=5">#5</a>. Many
- thanks to Christian Beil for accurately reporting bug #4.
- </p>
-
- <p>There has been also an effort to minimize the file sizes of the
- various jar files produced by SLF4J, resulting in jar files
- approximately 40% smaller than in version 1.0beta9.
- </p>
-
- <p>Given that the SLF4J API is now deemed stable, this release is
- marked as RC1, that is release candidate number 1.
- </p>
-
-
- <hr noshade="noshade" size="1"/>
-
- <h3>October 19th, 2005 - Release of SLF4J 1.0-beta9</h3>
-
- <p>The SLF4J distribution now includes two distinct bindings
- <em>slf4j-log4j12.jar</em> and <em>slf4j-log4j13.jar</em> in order
- to differentiate between log4j version 1.2 and version 1.3. This
- distinction is absolutely necessary because log4j 1.2 and 1.3 are
- not run-time compatible, although they are mostly compile-time
- compatible.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>October 19th, 2005 - Release of SLF4J 1.0-beta8 and NLOG4J 1.2.18</h3>
-
-
- <p>Added a new SLF4J binding, <em>slf4j-log4j.jar</em>, intended to
- be used in conjunction with vanilla <em>log4j.jar</em>, as
- distributed by the <a href="http://logging.apache.org">Apache
- Logging Services</a> project. The slf4j-log4j binding is quite
- similar in structure to the JDK 1.4 binding that existed
- previously.
- </p>
-
- <p>The slf4j-log4j binding addresses compatibility problems which
- arose when copies of both <em>log4j.jar</em> and <em>nlog4j.jar</em>
- lay on the class path, in particular when it was undesirable or
- impossible to remove the preexisting <em>log4j.jar</em> file.
- </p>
-
- <p>Methods in the <code>org.slf4j.Logger</code> interface related to
- markers were moved to a separate super interface called <a
- href="api/org/slf4j/MarkingLogger.html">
- <code>org.slf4j.MarkingLogger</code></a>. This refactoring reduces
- the weight of the <a href="api/org/slf4j/Logger.html">
- <code>Logger</code></a> interface.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>August 28th, 2005 - Release of SLF4J 1.0-beta7 and NLOG4J 1.2.17</h3>
-
- <p>Spurred by <a
- href="http://bugzilla.slf4j.org/show_bug.cgi?id=3">bug report
- #3</a>, SLF4J binding code has been refactored and
- simplified. Logging systems implementing SLF4J interfaces have to
- have less work in order to bind with SLF4J. Moreover, these changes
- have no incidence on the published interface of SLF4J.
- </p>
-
-
- <hr noshade="noshade" size="1"/>
-
- <h3>August 26th, 2005 - Release of SLF4J 1.0-beta6</h3>
-
- <p>To ease migration to SLF4J from JCL, this release includes a jar
- file called <em>jcl-over-slf4j-1.0.4.jar</em>. This jar file can be
- used as drop-in replacement for JCL version 1.0.4. It implements the
- public API of JCL using SLF4J underneath.
- </p>
-
- <p>Thus, you can immediately benefit from the advantages of SLF4J
- without waiting for all the libraries you depend on to migrate to
- SLF4J first.</p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>August 16th, 2005 - Release of NLOG4J 1.2.16</h3>
-
- <p>This release adds solves a compatibility problem between log4j
- and nlog4j. Previous to this release, code compiled with log4j
- would not run correctly with nlog4j.
- </p>
-
- <p>With the fixes introduced in NLOG4J 1.2.16, code compiled with
- log4j 1.2.x will run without problems when deployed using NLOG4j.
- </p>
-
- <p>However, the inverse is not true. Code compiled with nlog4j can
- only be deployed using nlog4j.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>August 12th, 2005 - Release of SLF4J 1.0-beta5 and NLOG4J
- 1.2.15</h3>
-
- <p>This release adds support for the <a
- href="api/org/slf4j/Marker.html">Marker</a> interface. Thus, log
- statements can be decorated with Marker data allowing more
- expressive power in the processing of log statements.
- </p>
-
- <p>For the sake of IoC frameworks, <code>Logger</code> instances can
- new be queried for their <a
- href="api/org/slf4j/Logger.html#getName()">name</a>.
- </p>
-
- <p>With the addition of markers, sub-domains are no longer
- needed.</p>
-
- <p>The <code>LoggerFactoryAdapter</code> has been simplified and
- renamed as <a
- href="api/org/slf4j/ILoggerFactory.html"><code>ILoggerFactory</code></a>.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>July 5th, 2005 - Release of NLOG4J 1.2.14</h3>
-
- <p>This release fixes compatibility problems between NLOG4J and
- Jakarta Commons Logging.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>June 28th, 2005 - Release of SLF4J 1.0-beta4 and NLOG4J
- 1.2.13</h3>
-
- <p>Following discussions on the SLF4J developers list, the
- signatures of the printing methods in <a
- href="api/org/slf4j/Logger.html"><code>org.slf4j.Logger</code></a>
- interface have been modified to admit messages of type
- <code>String</code> instead of type <code>Object</code> as
- previously. The current set of printing methods is listed below.
- </p>
-
- <pre class="source">
- void debug(String msg);
- void debug(String format, Object arg);
- void debug(String format, Object arg1, Object arg2);
- void debug(String msg, Throwable t);
-
- void error(String msg);
- void error(String format, Object arg;)
- void error(String format, Object arg1, Object arg2);
- void error(String msg, Throwable t);
-
- void info(String msg);
- void info(String format, Object arg);
- void info(String format, Object arg1, Object arg2);
- void info(String msg, Throwable t);
-
- void warn(String msg);
- void warn(String format, Object arg);
- void warn(String format, Object arg1, Object arg2);
- void warn(String msg, Throwable t); </pre>
-
-
- <p>NLOG4J release 1.2.13 reflects changes in the SLF4J API.
- </p>
-
- <p>You can download SLF4J and NLOG4J, including full source code,
- class files and documentation on our <a
- href="download.html">download page</a>.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>May 17th, 2005 - SLF4J version 1.0-beta-3 released</h3>
-
- <p>In response to user comments, the <code>org.slf4j.ULogger</code>
- interface has been renamed as <code>org.slf4j.Logger</code>.
- </p>
-
-
- <hr noshade="noshade" size="1"/>
-
- <h3>May 17th, 2005 - NLOG4J version 1.2.12 released</h3>
-
- <p>SLF4J.ORG is proud to release NLOG4J 1.2.12, a log4j-replacement
- with native SLF4J API support. Except for users of LF5, chainsaw or
- <code>NTEvenAppender</code>, NLOG4J should be considered as a 100%
- compatible, drop-in replacement for log4j version 1.2.9.
- </p>
-
- <p>This release reflects changes in the SLF4J API, i.e renaming of
- <code>org.slf4j.ULogger</code> interface as
- <code>org.slf4j.Logger</code>.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>May 17th, 2005 - SLF4J version 1.0-beta-3 released</h3>
-
- <p>SLF4J.ORG is proud to release SLF4J 1.0-beta-3. In response to
- user comments, the <code>org.slf4j.ULogger</code> interface has been
- renamed as <code>org.slf4j.Logger</code>.
- </p>
-
- <p>You can download SLF4J, including full source code, class files
- and documentation on our <a href="download.html">download page</a>.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>May 14th, 2005 - NLOG4J version 1.2.11 released</h3>
-
- <p>SLF4J.ORG is proud to release NLOG4J 1.2.11, a log4j-replacement
- with native SLF4J API support. Except for users of LF5, chainsaw or
- <code>NTEvenAppender</code>, NLOG4J should be considered as a 100%
- compatible, drop-in replacement for log4j version 1.2.9.
- </p>
-
- <p>You can download NLOG4J version 1.2.11, including full source
- code, class files and documentation on our <a
- href="download.html">download page</a>.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>May 4th, 2005 - SLF4J version 1.0-beta-2 released</h3>
-
- <p>SLF4J.ORG is proud to release SLF4J 1.0-beta-2. This release
- contains cosmetic or javadoc changes. For example, the project has a
- new logo.
- </p>
-
- <p>You can download SLF4J version 1.0-beta2, including full source
- code, class files and documentation on our <a
- href="download.html">download page</a>.
- </p>
-
-
- <hr noshade="noshade" size="1"/>
-
- <h3>1 May 2005 - not-log4j-1.2.10 released</h3>
-
- <p>Subsequent to the recall of log4j 1.2.10, SLF4J.ORG releases
- non-log4j-1.2.10 for those interested in SLF4J support in log4j.
- </p>
-
- <p>You can download not-log4j version 1.2.10, including full source
- code, class files and documentation on our <a
- href="download.html">download page</a>.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
-
- <h3>22 April 2005 - SLF4J project goes live</h3>
-
- <p>The SLF4J project site, including SVN repositories go
- live. Users can download SLF4J version 1.0-beta1.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>15 April 2005 - start of work on SLF4J source code</h3>
-
- <p>Start of work on the SLF4j source code.
- </p>
-
- <hr noshade="noshade" size="1"/>
-
- <h3>13 April 2005 - start of work on SLF4J project</h3>
-
- <p>Launch of the SLF4J project. Work has begun on the web-site, svn
- repositories as well as the source code.
- </p>
-
-
- <script src="templates/footer.js" type="text/javascript"></script>
-
-</div>
-</body>
-</html>
diff --git a/slf4j-site/src/site/pages/support.html b/slf4j-site/src/site/pages/support.html
deleted file mode 100644
index 010a56b0..00000000
--- a/slf4j-site/src/site/pages/support.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
-<title>Log4j Bridge</title>
-<link rel="stylesheet" type="text/css" media="screen" href="css/site.css" />
-<link rel="stylesheet" type="text/css" media="print" href="css/print.css" />
-
-</head>
-<body>
- <script>
-prefix='';
-</script>
-
-<script src="templates/header.js"></script>
-<div id="left">
- <script src="templates/left.js"></script>
-</div>
-<div id="right">
- <script src="templates/right.js"></script>
-</div>
-<div id="content">
-
- <h2>Contractual Support</h2>
-
-
- <p>The following companies, listed in alphabetical order, offer
- contractual support for SLF4J.
- </p>
-
- <ul>
- <li>QOS.ch, in Lausanne, Swizerland. For more information visit
- QOS.ch's <a href="">support page</a>. </li>
- </ul>
-
-
-
-<script src="templates/footer.js"></script>
-</div>
-</body>
-</html>
-
-
diff --git a/slf4j-site/src/site/pages/templates/footer.js b/slf4j-site/src/site/pages/templates/footer.js
deleted file mode 100755
index b7d01cf9..00000000
--- a/slf4j-site/src/site/pages/templates/footer.js
+++ /dev/null
@@ -1,28 +0,0 @@
-
-document.write('<table class="footer" border="0">')
-
-document.write('<tr>')
-
-document.write(' <td valign="top" align="left">Copyright &copy; 2004-2015 <a href="http://www.qos.ch/">QOS.ch</a></td>')
-
-//document.write(' <td rowspan="2">');
-//document.write(' <a href="http://twitter.com/qos_ch">');
-//document.write(' <img alt="Follow @qos_ch" src="images/follow_us.png" />');
-//document.write(' </a>');
-//document.write(' </td>');
-
-
-document.write('</tr>')
-
-AAT = '@'
-DOOTT = '.'
-document.write('<tr>')
-document.write('<td align="left" colspan="1">')
-document.write('We are actively looking for volunteers to proofread the documentation. Please send your corrections or suggestions for improvement to "corrections' + AAT +'qos'+DOOTT+'ch". See also the <a href="http://articles.qos.ch/contributing.html">instructions for contributors</a>.');
-document.write('</td>')
-document.write('</tr>')
-
-
-document.write('</table>')
-
-
diff --git a/slf4j-site/src/site/pages/templates/header.js b/slf4j-site/src/site/pages/templates/header.js
deleted file mode 100644
index 35f75bc9..00000000
--- a/slf4j-site/src/site/pages/templates/header.js
+++ /dev/null
@@ -1,12 +0,0 @@
-
-document.write('<table width="100%" border="0"><tr>');
-document.write('<td><a href="http://www.slf4j.org/">');
-document.write('<img src="' + prefix + 'images/logos/slf4j-logo.jpg" alt="" border="0"/>');
-document.write('</a></td>')
-
-//document.write('<td align="right"><a id="job" href="http://logback.qos.ch/job.html">');
-//document.write('<img src="' + prefix + 'images/myjob.png" alt="" border="0"/>');
-//document.write('</a></td>')
-
-document.write('</tr></table>');
-document.write('<div id="breadcrumbs"></div>'); \ No newline at end of file
diff --git a/slf4j-site/src/site/pages/templates/left.js b/slf4j-site/src/site/pages/templates/left.js
deleted file mode 100755
index 3fc7824b..00000000
--- a/slf4j-site/src/site/pages/templates/left.js
+++ /dev/null
@@ -1,59 +0,0 @@
-document.write('<div class="menuGroup">');
-document.write(' <p class="menu_header">SLF4J Project</p>');
-document.write(' <a href="index.html">Introduction</a>');
-document.write(' <a href="download.html">Download</a>');
-document.write(' <a href="docs.html">Documentation</a>');
-document.write(' <a href="license.html">License</a>');
-document.write(' <a href="news.html">News</a>');
-
-document.write(' <p class="menu_header">Support</p>');
-
-document.write(' <a href="mailing-lists.html">Mailing Lists</a>');
-document.write(' <a href="bug-reporting.html">Bug Reporting</a>');
-document.write(' <a href="https://github.com/qos-ch/slf4j">Source Repository</a>');
-document.write(' <a href="http://www.qos.ch/shop/products/professionalSupport">Support offerings</a>');
-document.write(' <a href="http://www.qos.ch/shop/products/training">Training</a>');
-
-document.write(' <p class="menu_header">Native implementations</p>');
-document.write(' <a href="http://logback.qos.ch/">Logback</a>');
-
-document.write(' <p class="menu_header">Wrapped implementations</p>');
-document.write(' <a href="http://bmc.github.com/avsl/">AVSL</a>');
-document.write(' <a href="api/org/slf4j/impl/JDK14LoggerAdapter.html">JDK14</a>');
-document.write(' <a href="api/org/slf4j/impl/Log4jLoggerAdapter.html">Log4j</a>');
-document.write(' <a href="api/org/slf4j/impl/SimpleLogger.html">Simple</a>');
-document.write(' <a href="android/">Android</a>');
-document.write(' </p>');
-
-document.write(' <p class="menu_header">Sub-projects</p>');
-document.write(' <a href="http://www.slf4j.org/taglib/">slf4j-taglib</a>');
-document.write(' </p>');
-
-document.write('</div>');
-
-
-document.write('<p>&nbsp;</p>');
-
-document.write('<div class="pub">');
-document.write(' <a href="http://twitter.com/qos_ch" style="">');
-document.write(' <img alt="Follow @qos_ch" src="images/follow_us.png" />');
-document.write(' </a>');
-document.write('</div>');
-
-document.write('<p>&nbsp;</p>');
-document.write('<div class="pub"><img src="https://travis-ci.org/qos-ch/slf4j.svg?branch=master"/></div>');
-
-
-//document.write('<p>&nbsp;</p>');
-//document.write('<div class="jobadd"><p><a href="http://logback.qos.ch/job.html">Your career<br/>@QOS.ch</a></p></div>');
-
-
-//document.write('<p>&nbsp;</p>');
-//document.write('<p class="pub">');
-//document.write(' <a href="https://www.qos.ch/shop/products/log4jManual">');
-//document.write(' <img src="images/buyDirect.jpg" border="0" title="" alt="buy direct from the developer"/>');
-//document.write(' </a>');
-//document.write('</p>');
-
-
-
diff --git a/slf4j-site/src/site/pages/templates/right.js b/slf4j-site/src/site/pages/templates/right.js
deleted file mode 100644
index 8b137891..00000000
--- a/slf4j-site/src/site/pages/templates/right.js
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/slf4j-site/src/site/resources/css/anchor12.png b/slf4j-site/src/site/resources/css/anchor12.png
deleted file mode 100644
index 2cd97acb..00000000
--- a/slf4j-site/src/site/resources/css/anchor12.png
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/css/anchor16.png b/slf4j-site/src/site/resources/css/anchor16.png
deleted file mode 100644
index c0676f49..00000000
--- a/slf4j-site/src/site/resources/css/anchor16.png
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/css/anchor20.png b/slf4j-site/src/site/resources/css/anchor20.png
deleted file mode 100644
index 76ca74bb..00000000
--- a/slf4j-site/src/site/resources/css/anchor20.png
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/css/anchor24.png b/slf4j-site/src/site/resources/css/anchor24.png
deleted file mode 100644
index 13c433fa..00000000
--- a/slf4j-site/src/site/resources/css/anchor24.png
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/PythonPowered.png b/slf4j-site/src/site/resources/images/PythonPowered.png
deleted file mode 100644
index 2e9d99c2..00000000
--- a/slf4j-site/src/site/resources/images/PythonPowered.png
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/beginnerSLF4J.png b/slf4j-site/src/site/resources/images/beginnerSLF4J.png
deleted file mode 100644
index c156a18f..00000000
--- a/slf4j-site/src/site/resources/images/beginnerSLF4J.png
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/bindings.png b/slf4j-site/src/site/resources/images/bindings.png
deleted file mode 100644
index 4021c095..00000000
--- a/slf4j-site/src/site/resources/images/bindings.png
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/bridging.png b/slf4j-site/src/site/resources/images/bridging.png
deleted file mode 100644
index b61c0a7b..00000000
--- a/slf4j-site/src/site/resources/images/bridging.png
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/buyDirect.jpg b/slf4j-site/src/site/resources/images/buyDirect.jpg
deleted file mode 100644
index dd2ff4c8..00000000
--- a/slf4j-site/src/site/resources/images/buyDirect.jpg
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/concrete-bindings.png b/slf4j-site/src/site/resources/images/concrete-bindings.png
deleted file mode 100644
index 9c7d1b16..00000000
--- a/slf4j-site/src/site/resources/images/concrete-bindings.png
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/devoxx09.jpeg b/slf4j-site/src/site/resources/images/devoxx09.jpeg
deleted file mode 100644
index f6f38ebb..00000000
--- a/slf4j-site/src/site/resources/images/devoxx09.jpeg
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/follow_us.png b/slf4j-site/src/site/resources/images/follow_us.png
deleted file mode 100644
index fe3a3888..00000000
--- a/slf4j-site/src/site/resources/images/follow_us.png
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/gnu-head-tiny.jpg b/slf4j-site/src/site/resources/images/gnu-head-tiny.jpg
deleted file mode 100644
index 441be50d..00000000
--- a/slf4j-site/src/site/resources/images/gnu-head-tiny.jpg
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/jazoon09.gif b/slf4j-site/src/site/resources/images/jazoon09.gif
deleted file mode 100644
index f386387c..00000000
--- a/slf4j-site/src/site/resources/images/jazoon09.gif
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/legacy.png b/slf4j-site/src/site/resources/images/legacy.png
deleted file mode 100644
index 46d1f6da..00000000
--- a/slf4j-site/src/site/resources/images/legacy.png
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/logos/qosLogo.png b/slf4j-site/src/site/resources/images/logos/qosLogo.png
deleted file mode 100644
index 52b216e9..00000000
--- a/slf4j-site/src/site/resources/images/logos/qosLogo.png
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/logos/qoslogo.gif b/slf4j-site/src/site/resources/images/logos/qoslogo.gif
deleted file mode 100644
index d06ec29b..00000000
--- a/slf4j-site/src/site/resources/images/logos/qoslogo.gif
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/logos/slf4j-logo.jpg b/slf4j-site/src/site/resources/images/logos/slf4j-logo.jpg
deleted file mode 100644
index 62295c91..00000000
--- a/slf4j-site/src/site/resources/images/logos/slf4j-logo.jpg
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/logos/slf4j-small.jpg b/slf4j-site/src/site/resources/images/logos/slf4j-small.jpg
deleted file mode 100644
index a26ab0c2..00000000
--- a/slf4j-site/src/site/resources/images/logos/slf4j-small.jpg
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/logos/valid-html401.png b/slf4j-site/src/site/resources/images/logos/valid-html401.png
deleted file mode 100644
index 7cd17ee5..00000000
--- a/slf4j-site/src/site/resources/images/logos/valid-html401.png
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/mailman.jpg b/slf4j-site/src/site/resources/images/mailman.jpg
deleted file mode 100644
index 94a4c011..00000000
--- a/slf4j-site/src/site/resources/images/mailman.jpg
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/myjob.png b/slf4j-site/src/site/resources/images/myjob.png
deleted file mode 100644
index 40b50d4f..00000000
--- a/slf4j-site/src/site/resources/images/myjob.png
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/slf4j-migrator.gif b/slf4j-site/src/site/resources/images/slf4j-migrator.gif
deleted file mode 100644
index 27c126ef..00000000
--- a/slf4j-site/src/site/resources/images/slf4j-migrator.gif
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/twitter-bird-light-bgs.png b/slf4j-site/src/site/resources/images/twitter-bird-light-bgs.png
deleted file mode 100644
index 188597e9..00000000
--- a/slf4j-site/src/site/resources/images/twitter-bird-light-bgs.png
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/images/twitter.png b/slf4j-site/src/site/resources/images/twitter.png
deleted file mode 100644
index 0e75e4d7..00000000
--- a/slf4j-site/src/site/resources/images/twitter.png
+++ /dev/null
Binary files differ
diff --git a/slf4j-site/src/site/resources/slf4j-in-10-slides.ppt b/slf4j-site/src/site/resources/slf4j-in-10-slides.ppt
deleted file mode 100644
index 8976db2e..00000000
--- a/slf4j-site/src/site/resources/slf4j-in-10-slides.ppt
+++ /dev/null
Binary files differ
diff --git a/src/main/assembly/source.xml b/src/main/assembly/source.xml
deleted file mode 100755
index 0013471f..00000000
--- a/src/main/assembly/source.xml
+++ /dev/null
@@ -1,342 +0,0 @@
-<assembly>
- <id>dist</id>
- <formats>
- <format>zip</format>
- <format>tar.gz</format>
- </formats>
- <fileSets>
- <!-- Module POMs -->
- <fileSet>
- <directory>slf4j-api/</directory>
- <outputDirectory>slf4j-api/</outputDirectory>
- <includes>
- <include>pom.xml</include>
- </includes>
- </fileSet>
-
- <fileSet>
- <directory>slf4j-jcl/</directory>
- <outputDirectory>slf4j-jcl/</outputDirectory>
- <includes>
- <include>pom.xml</include>
- </includes>
- </fileSet>
-
- <fileSet>
- <directory>slf4j-jdk14/</directory>
- <outputDirectory>slf4j-jdk14/</outputDirectory>
- <includes>
- <include>pom.xml</include>
- </includes>
- </fileSet>
-
- <fileSet>
- <directory>slf4j-log4j12/</directory>
- <outputDirectory>slf4j-log4j12/</outputDirectory>
- <includes>
- <include>pom.xml</include>
- </includes>
- </fileSet>
-
- <fileSet>
- <directory>slf4j-nop/</directory>
- <outputDirectory>slf4j-nop/</outputDirectory>
- <includes>
- <include>pom.xml</include>
- </includes>
- </fileSet>
-
- <fileSet>
- <directory>slf4j-simple/</directory>
- <outputDirectory>slf4j-simple/</outputDirectory>
- <includes>
- <include>pom.xml</include>
- </includes>
- </fileSet>
-
- <fileSet>
- <directory>slf4j-android/</directory>
- <outputDirectory>slf4j-android/</outputDirectory>
- <includes>
- <include>pom.xml</include>
- </includes>
- </fileSet>
-
- <fileSet>
- <directory>slf4j-ext/</directory>
- <outputDirectory>slf4j-ext/</outputDirectory>
- <includes>
- <include>pom.xml</include>
- </includes>
- </fileSet>
-
-
- <fileSet>
- <directory>jcl104-over-slf4j/</directory>
- <outputDirectory>jcl104-over-slf4j/</outputDirectory>
- <includes>
- <include>pom.xml</include>
- </includes>
- </fileSet>
-
- <fileSet>
- <directory>jcl-over-slf4j/</directory>
- <outputDirectory>jcl-over-slf4j/</outputDirectory>
- <includes>
- <include>pom.xml</include>
- </includes>
- </fileSet>
-
- <fileSet>
- <directory>jul-to-slf4j/</directory>
- <outputDirectory>jul-to-slf4j/</outputDirectory>
- <includes>
- <include>pom.xml</include>
- </includes>
- </fileSet>
-
- <fileSet>
- <directory>log4j-over-slf4j/</directory>
- <outputDirectory>log4j-over-slf4j/</outputDirectory>
- <includes><include>pom.xml</include></includes>
- </fileSet>
-
- <fileSet>
- <directory>osgi-over-slf4j/</directory>
- <outputDirectory>osgi-over-slf4j/</outputDirectory>
- <includes><include>pom.xml</include></includes>
- </fileSet>
-
- <fileSet>
- <directory>slf4j-site/</directory>
- <outputDirectory>slf4j-site/</outputDirectory>
- <includes>
- <include>pom.xml</include>
- </includes>
- </fileSet>
-
- <fileSet>
- <directory>slf4j-migrator/</directory>
- <outputDirectory>slf4j-migrator/</outputDirectory>
- <includes>
- <include>pom.xml</include>
- </includes>
- </fileSet>
-
- <fileSet>
- <directory>integration/</directory>
- <outputDirectory>integration/</outputDirectory>
- <includes>
- <include>pom.xml</include>
- <include>build.xml</include>
- <include>osgi-build.xml</include>
- <include>lib/*</include>
- </includes>
- </fileSet>
-
- <!-- Module Source directories (includes tests) -->
- <fileSet>
- <directory>slf4j-api/src/</directory>
- <outputDirectory>slf4j-api/src/</outputDirectory>
- <excludes>
- <exclude>test/output/</exclude>
- </excludes>
- </fileSet>
-
- <fileSet>
- <directory>slf4j-jcl/src/</directory>
- <outputDirectory>slf4j-jcl/src/</outputDirectory>
- </fileSet>
-
- <fileSet>
- <directory>slf4j-jdk14/src/</directory>
- <outputDirectory>slf4j-jdk14/src/</outputDirectory>
- </fileSet>
-
- <fileSet>
- <directory>slf4j-log4j12/src/</directory>
- <outputDirectory>slf4j-log4j12/src/</outputDirectory>
- </fileSet>
- <fileSet>
- <directory>slf4j-nop/src/</directory>
- <outputDirectory>slf4j-nop/src/</outputDirectory>
- </fileSet>
- <fileSet>
- <directory>slf4j-simple/src/</directory>
- <outputDirectory>slf4j-simple/src/</outputDirectory>
- </fileSet>
- <fileSet>
- <directory>slf4j-android/src/</directory>
- <outputDirectory>slf4j-android/src/</outputDirectory>
- </fileSet>
- <fileSet>
- <directory>slf4j-ext/src/</directory>
- <outputDirectory>slf4j-ext/src/</outputDirectory>
- </fileSet>
- <fileSet>
- <directory>jcl-over-slf4j/src/</directory>
- <outputDirectory>jcl-over-slf4j/src/</outputDirectory>
- </fileSet>
- <fileSet>
- <directory>jul-to-slf4j/src/</directory>
- <outputDirectory>jul-to-slf4j/src/</outputDirectory>
- </fileSet>
- <fileSet>
- <directory>log4j-over-slf4j/src/</directory>
- <outputDirectory>log4j-over-slf4j/src/</outputDirectory>
- </fileSet>
- <fileSet>
- <directory>osgi-over-slf4j/src/</directory>
- <outputDirectory>osgi-over-slf4j/src/</outputDirectory>
- </fileSet>
- <fileSet>
- <directory>slf4j-site/src/</directory>
- <outputDirectory>slf4j-site/src/</outputDirectory>
- </fileSet>
- <fileSet>
- <directory>slf4j-migrator/src/</directory>
- <outputDirectory>slf4j-migrator/src/</outputDirectory>
- </fileSet>
- <fileSet>
- <directory>integration/src/</directory>
- <outputDirectory>integration/src/</outputDirectory>
- </fileSet>
-
-
- <!-- Module JARs -->
- <fileSet>
- <directory>slf4j-api/target/</directory>
- <outputDirectory>/</outputDirectory>
- <includes>
- <include>slf4j-api-${project.version}-sources.jar</include>
- <include>slf4j-api-${project.version}.jar</include>
- </includes>
- </fileSet>
-
- <fileSet>
- <directory>slf4j-jcl/target/</directory>
- <outputDirectory>/</outputDirectory>
- <includes>
- <include>slf4j-jcl-${project.version}.jar</include>
- <include>slf4j-jcl-${project.version}-sources.jar</include>
- </includes>
- </fileSet>
-
- <fileSet>
- <directory>slf4j-jdk14/target/</directory>
- <outputDirectory>/</outputDirectory>
- <includes>
- <include>slf4j-jdk14-${project.version}-sources.jar</include>
- <include>slf4j-jdk14-${project.version}.jar</include>
- </includes>
- </fileSet>
-
- <fileSet>
- <directory>slf4j-log4j12/target/</directory>
- <outputDirectory>/</outputDirectory>
- <includes>
- <include>slf4j-log4j12-${project.version}.jar</include>
- <include>slf4j-log4j12-${project.version}-sources.jar</include>
- </includes>
- </fileSet>
-
- <fileSet>
- <directory>slf4j-nop/target/</directory>
- <outputDirectory>/</outputDirectory>
- <includes>
- <include>slf4j-nop-${project.version}.jar</include>
- <include>slf4j-nop-${project.version}-sources.jar</include>
- </includes>
- </fileSet>
-
- <fileSet>
- <directory>slf4j-simple/target/</directory>
- <outputDirectory>/</outputDirectory>
- <includes>
- <include>slf4j-simple-${project.version}-sources*.jar</include>
- <include>slf4j-simple-${project.version}.jar</include>
- </includes>
- </fileSet>
-
- <fileSet>
- <directory>slf4j-android/target/</directory>
- <outputDirectory>/</outputDirectory>
- <includes>
- <include>slf4j-android-${project.version}-sources*.jar</include>
- <include>slf4j-android-${project.version}.jar</include>
- </includes>
- </fileSet>
-
-
- <fileSet>
- <directory>slf4j-ext/target/</directory>
- <outputDirectory>/</outputDirectory>
- <includes>
- <include>slf4j-ext-${project.version}-sources*.jar</include>
- <include>slf4j-ext-${project.version}.jar</include>
- </includes>
- </fileSet>
-
-
- <fileSet>
- <directory>jcl-over-slf4j/target/</directory>
- <outputDirectory>/</outputDirectory>
- <includes>
- <include>jcl-over-slf4j-${project.version}-sources.jar</include>
- <include>jcl-over-slf4j-${project.version}.jar</include>
- </includes>
- </fileSet>
- <fileSet>
- <directory>jul-to-slf4j/target/</directory>
- <outputDirectory>/</outputDirectory>
- <includes>
- <include>jul-to-slf4j-${project.version}-sources.jar</include>
- <include>jul-to-slf4j-${project.version}.jar</include>
- </includes>
- </fileSet>
- <fileSet>
- <directory>log4j-over-slf4j/target/</directory>
- <outputDirectory>/</outputDirectory>
- <includes>
- <include>log4j-over-slf4j-${project.version}.jar</include>
- <include>log4j-over-slf4j-${project.version}-sources.jar</include>
- </includes>
- </fileSet>
- <fileSet>
- <directory>osgi-over-slf4j/target/</directory>
- <outputDirectory>/</outputDirectory>
- <includes>
- <include>osgi-over-slf4j-${project.version}.jar</include>
- <include>osgi-over-slf4j-${project.version}-sources.jar</include>
- </includes>
- </fileSet>
-
- <fileSet>
- <directory>slf4j-migrator/target/</directory>
- <outputDirectory>/</outputDirectory>
- <includes>
- <include>slf4j-migrator-${project.version}.jar</include>
- </includes>
- </fileSet>
-
- <!-- Website -->
- <fileSet>
- <directory>target/site</directory>
- <outputDirectory>/site</outputDirectory>
- <excludes>
- <exclude>dist/*</exclude>
- </excludes>
- </fileSet>
-
- <!-- Parent files -->
- <fileSet>
- <includes>
- <include>src/</include>
- <include>README*</include>
- <include>LICENSE*</include>
- <include>pom.xml</include>
- </includes>
- </fileSet>
- </fileSets>
-
-</assembly> \ No newline at end of file
diff --git a/test b/test
deleted file mode 100644
index e69de29b..00000000
--- a/test
+++ /dev/null
diff --git a/version.pl b/version.pl
deleted file mode 100644
index 5587b313..00000000
--- a/version.pl
+++ /dev/null
@@ -1,44 +0,0 @@
-
-if ($#ARGV < 1) {
- print "Usage: version.pl VER FILE {FILE, FILE}\n";
- exit;
-}
-
-$V=$ARGV[0];
-print "VER:'${V}'\r\n";
-shift(@ARGV);
-
-sub replace () {
- my $filename = $_[0];
-
- if(-s $filename) {
- print "Processing [" . $filename . "]\r\n";
-
- my $original = "$filename.original";
-
- rename($filename, $original);
- open(OUT, ">$filename");
- open(IN, "$original");
-
- my $hitCount=0;
- while(<IN>) {
- if($hitCount == 0 && /<version>.*<\/version>/) {
- s/<version>.*<\/version>/<version>${V}<\/version>/;
- $hitCount++;
- }
- print OUT;
- }
- close(IN);
- close(OUT);
- unlink($original);
- } else {
- print "File [" . $filename . "] does not exist\r\n"
- }
-}
-
-foreach $ARG (@ARGV) {
- do replace($ARG);
-}
-
-
-