diff --git a/binderVersion.pl b/binderVersion.pl
index 158ff166..688d4ae4 100644
--- a/binderVersion.pl
+++ b/binderVersion.pl
@@ -5,6 +5,9 @@ if ($#ARGV < 1) {
}
$V= $ARGV[0];
+# Trim -SNAPSHOT
+$V =~ s/-SNAPSHOT//;
+
print "VER:${V}\r\n";
shift(@ARGV);
diff --git a/goVersion.sh b/goVersion.sh
index 9f19e976..77105f8b 100644
--- a/goVersion.sh
+++ b/goVersion.sh
@@ -4,4 +4,4 @@ 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}
-find slf4j-api -name "LoggerFactory.java" |xargs perl binderVersion.pl ${VER}
+
diff --git a/integration/build.xml b/integration/build.xml
index 3156ba6b..65bdc452 100644
--- a/integration/build.xml
+++ b/integration/build.xml
@@ -38,15 +38,15 @@
+ */
+ static private final String[] API_COMPATIBILITY_LIST = new String[] { "1.5.5" };
// private constructor prevents instantiation
private LoggerFactory() {
@@ -95,7 +102,7 @@ public final class LoggerFactory {
}
private final static void emitSubstitureLoggerWarning(List loggerNameList) {
- if(loggerNameList.size() == 0) {
+ if (loggerNameList.size() == 0) {
return;
}
Util
@@ -111,22 +118,29 @@ public final class LoggerFactory {
private final static void versionSanityCheck() {
try {
- String actualVer = StaticLoggerBinder.VERSION;
- if (!EXPECTED_VERSION.equals(actualVer)) {
- Util.reportFailure("The version " + actualVer
- + " of your slf4j-binding differs from " + EXPECTED_VERSION
- + ", the expected version.");
+ String requested = StaticLoggerBinder.REQUESTED_API_VERSION;
+
+ boolean match = false;
+ for (int i = 0; i < API_COMPATIBILITY_LIST.length; i++) {
+ if (API_COMPATIBILITY_LIST[i].equals(requested)) {
+ match = true;
+ }
+ }
+ if (!match) {
+ Util.reportFailure("The requested version " + requested
+ + " of your slf4j-binding does not match any of "
+ + Arrays.toString(API_COMPATIBILITY_LIST));
Util.reportFailure("See " + VERSION_MISMATCH + " for further details.");
}
} catch (java.lang.NoSuchFieldError nsfe) {
- Util
- .reportFailure("The version of your slf4j-binding is probably older than 1.5.4, and differs from "
- + EXPECTED_VERSION + ", the expected version.");
- Util.reportFailure("See " + VERSION_MISMATCH + " for further details.");
+ // given our large user base anbd 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) {
- Util
- .reportFailure("An unexpected problem occured while checking the version of your slf4j-binding");
- e.printStackTrace();
+ // we should never reach here
+ Util.reportFailure(
+ "Unexpected problem occured during version sanity check", e);
}
}
diff --git a/slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
index 0c2b780d..ab08a4d6 100644
--- a/slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
+++ b/slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
@@ -44,11 +44,11 @@ public class StaticLoggerBinder {
public static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
/**
- * Version tag used to check compatibility. The value of this field is
- * modified with each release.
+ * Declare the version of the SLF4J API this implementation is compiled against.
+ * The value of this field is usually modified with each release.
*/
- // to avoid constant folding by the compiler, VERSION field should *not* be final
- public static String VERSION = "1.5.4"; // !final
+ // to avoid constant folding by the compiler, this field must *not* be final
+ public static String REQUESTED_API_VERSION = "1.5.5"; // !final
private StaticLoggerBinder() {
throw new UnsupportedOperationException("This code should have never made it into the jar");
diff --git a/slf4j-ext/pom.xml b/slf4j-ext/pom.xml
index 7e8721de..afeb0ca2 100644
--- a/slf4j-ext/pom.xml
+++ b/slf4j-ext/pom.xml
@@ -5,7 +5,7 @@
Mixing mixing different versions of slf4j artifacts can cause
- problems. For example, if you are using slf4j-api-1.5.4.jar, then
- you should also use slf4j-simple-1.5.4.jar, using
- slf4j-simple-1.4.2.jar will not work.
+ problems. For example, if you are using slf4j-api-1.5.5.jar, then
+ you should also use slf4j-simple-1.5.5.jar, using
+ slf4j-simple-1.4.2.jar will not work.
In general, you should take sure that the slf4j-api version
@@ -178,43 +178,42 @@ prefix='';
Highly configurable logging systems such as logback and log4j may
- create components which invoke loggers during their own
- initialization. See issue lbcore-47 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, resulting in a
- Highly configurable logging systems such as logback and log4j
+ may create components which invoke loggers during their own
+ initialization. See issue lbcore-47 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, resulting in a
+ To avoid this chicken-and-egg problem, SLF4J substitutes a
- no-operation logger factory during this initialization
- phase. However, the loggers returned during this phase by the
- substitute logger factory are not operational. They are nop
- implementations.
- To avoid this chicken-and-egg problem, SLF4J substitutes a
+ no-operation logger factory during this initialization
+ phase. However, the substitute loggers returned during this phase
+ are not operational. They are nop implementations.
+ If any substitute logger had to be created, SLF4J will emit a
- warning listing such nop loggers. This warning is intended to let
- you know that you should not expect any logging output from these
- loggers.
- If any substitute logger had to be created, SLF4J will emit a
+ warning listing such nop loggers. This warning is intended to let
+ you know that you should not expect any logging output from these
+ loggers.
+ The only way to obtain output from the listed loggers, is to
- isolate the components invoking these loggers and to exclude them
- from the default configuration. Both logback and log4j allow
- multi-step configuration. It follows that the problematic components
- should be configured in a second step separate from default
- configuration.
- The only way to obtain output from the listed loggers, is to
+ isolate the components invoking these loggers and to exclude them
+ from the default configuration. Both logback and log4j allow
+ multi-step configuration. It follows that the problematic
+ components should be configured in a second step separate from
+ default configuration.
+ If you are not interested in the output from any of the
- substitute loggers, then no action is required on your part. If you are not interested in the output from any of the
+ substitute loggers, then no action is required on your part.Substitute
- loggers were created during the default configuration phase of the
- underlying logging system
+ Substitute
+ loggers were created during the default configuration phase of the
+ underlying logging system
- NullPointerException.NullPointerException.Marker interface? org.slf4j.Logger interface. Refer to slf4j-jcl,
slf4j-jdk14, and slf4j-log4j12 modules for examples of
adapters.
-
Once you have written an appropriate adapter, say
MyLoggerAdapter, you need to provide a factory
@@ -918,7 +922,7 @@ class MyClass {
interface. This factory should return instances
MyLoggerAdapter. Let MyLoggerFactory
be the name of your factory class.
-
Once you have the adapter, namely
MyLoggerAdapter, and a factory, namely
@@ -942,7 +946,7 @@ class MyClass {
org.slf4j.Logger interface
StaticLoggerBinder class to use the
+ StaticLoggerBinder class to use the
factory you created in the previous stepHowever, 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. In order to provide
- minimal support for markers, SLF4J conforming systems need to
- to include certain Marker related classes, namely,
- org.slf4j.Marker,
- org.slf4j.IMarkerFactory,
- org.slf4j.MarkerFactory,
- org.slf4j.impl.BasicMarker,
- org.slf4j.impl.BasicMarkerFactory,
- org.slf4j.impl.MarkerIgnoringBase,
- org.slf4j.impl.StaticMarkerBinder and
- org.slf4j.spi.MarkerFactoryBinder. Al of these
- classes are available in the SLF4J subversion repository.
-
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. +
-The MarkerIgnoringBase class can serve as a
- base for adapters or native implementations of logging systems
- lacking marker support. In MarkerIgnoringBase,
- 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
- MarkerIgnoringBase to quickly implement the
- methods in org.slf4j.Logger which take a
- Marker as the first argument.
-
The MarkerIgnoringBase class can serve as a
+ base for adapters or native implementations of logging
+ systems lacking marker support. In
+ MarkerIgnoringBase, 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
+ MarkerIgnoringBase to quickly implement the
+ methods in org.slf4j.Logger which take a
+ Marker as the first argument.
+
Given its huge installed user base, the version check + performed by SLF4J API during its initialization is an + elective process. Conforming SLF4J implementations may choose + not to participate, in which case, no version check + will be performed. +
+ +However, if you decide to participate, your SLF4J binding
+ needs to declare a variable called REQUESTED_API_VERSION
+ within your copy of the StaticLoggerBinder
+ class. The value of this variable should be equal to the
+ version of the slf4j-api.jar you are compiling against. If you
+ ugrade to a newer version of slf4j-api, you also need to
+ update the value of REQUESTED_API_VERSION. (That is all you
+ have to do.)
+
For earch 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, 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.
+ +As of SLF4J 1.5.5, all bindings shipped within SLF4J + distribution, e.g. slf4j-logj12, 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.6.jar is mixed with simple-api-1.5.5.jar, + then a version mismatch warning will be issued. Note that + SLF4J prior to 1.5.5 did not have a version check + mechanism. (Actually, version 1.5.4 offered a check policy + which was much too restritive and inconsistent with the size + of our user base. Consequently, SLF4J version 1.5.5 was + released just a day after 1.5.4.) +
+ ++
+ +