Compile time bindings with slf4j
SLF4j (Simple Logging Facade for Java) is an api which is implemented by various logging frameworks(log4j, logback, jul*, jcl** etc). The SLF4J distribution ships with several jar files referred to as “SLF4J bindings”, with each binding corresponding to a supported framework.
The SLF4j Manual says
SLF4J does not rely on any special class loader machinery. In fact, the each SLF4J binding is hardwired at compile time to use one and only one specific logging framework. For example, the slf4j-log12-1.6.1.jar binding is bound at compile time to use log4j.
I was curious to understand how slf4j binds to the logging implementation at compile-time. After looking at the code I got a better picture. This is how it works
1. Any class which wants to log includes a call to LoggerFactory.getLogger(UserClass.class.getName);
2. LoggerFactory.getLogger() method tries to load a class with qualified name “org/slf4j/impl/StaticLoggerBinder.class” (if not already loaded). org.slf4j.impl.StaticLoggerBinder class is supposed to present in any logging framework binder library (for e.g. logback) which implements slf4j. If there is no such class found, a default no logger implementation is used. If more then one implementations are found an error is printed. This implementation can be found in singleImplementationSanityCheck() method of LoggerFactory class.
3. StaticLoggerBinder is suppose to be an singleton class. The LoggerFactory code then calls StaticLoggerBinder.getSingleton() method which is also supposed to be present in the StaticLoggerBinder class.
4. The StaticLoggerBinder.getSingleton() method then takes it over from there to instantiate the LoggerContext (one of the interfaces exposed in the slf4j api).
This code explains how slf4j binds with the logging framework. It also explains why slf4j distribution comes with the binding libraries for different logging frameworks like log4j. Logback has a native implementation of slf4j hence slf4j distribution does not need to have a binding jar for logback.
This post proves the slogan “only in code we trust” 🙂
*jul – java.util.logging
**jcl – jakarta commons logging.