Java Ninja Chronicles By Norris Shelton

Things I learned in the pursuit of code

Logging is needed, but all of the different frameworks makes this a pain. You are trying to research a problem and you have to bounce from log to log to research it.

SLF4J has bridge implementations that delegate to SLF4J APIs for commons-logging, log4j and even jdk logging.

You need to include the dependency for the logging API that you want to hijack as provided so they will not be packaged, then include the SLF4J bridge api. Repeat for each logging API you want to hijack, then include a SLF4J logging implementation, then away you go.

Here is how to hijack log4j

        <!--hijack log4j-->
        <!--NOTE Saying it is provided so it will not be packaged in my builds if a dependency is using it-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.16</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j-over-slf4j</artifactId>
            <version>${slf4j.version}</version>
            <scope>provided</scope>
        </dependency>

There are 3 strains of log4j (1.2, 1.3 & 2.0). None are compatible with any of the other. Luckily, only 1.2 is commonly used.

Here is how to hijack commons-logging

        <!--hijack commons logging-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${slf4j.version}</version>
        </dependency>

There is also a jcl104-over-slf4j for commons-logging 1.0.x. I tried to be slick and include that on a project and it got ugly. Those versions of the commons-logging API must not be compatible.

I usually don’t hijack the jdk logging because I rarely encounter it.

All that is remaining is to include a SLF4J implementation. There is one for commons-logging and log4j, but my preferred solution is logback.

        <!-- LogBack -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>0.9.27</version>
        </dependency>

This is what works for me, but I see where there could be problems. The logging APIs that I am hijacking are in the compile classpath, but not in the deploy classpath. It could be possible to use Maven exclusions to totally strip out the artifacts, but you must put an exclusion on each dependency that uses the artifact. Good luck keeping up with that. They are supposed to fix this in maven 3.1

February 3rd, 2011

Posted In: Java, logback, slf4j

Tags: , , , , , , , ,

Leave a Reply

Your email address will not be published. Required fields are marked *

WP to LinkedIn Auto Publish Powered By : XYZScripts.com