Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing SLF4J in an application with many transitive dependencies

I am in the process of refactoring a Java web application which has a fairly large number of dependencies. I would like to use slf4j, with log4j2 as the underlying logging implementation. However, the application includes some Spring dependencies. Spring using JCL (Jakarta common logging) for its logging, so it is bringing in commons-logging as a transitive dependency. This is a potential problem, because it means that slf4j might pick up on jcl as a logging implementation, and that Spring might log somewhere in an undesirable way.

From the slf4j documentation, the solution is to first turn off commons-logging by excluding it from the POM, then to use jcl-over-slf4j to replace commons-logging. Of course, jcl-over-slf4j will route all previous logging calls made by Spring to slf4j.

I have tried excluding commons-logging, e.g.

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <exclusions>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

However, when checking the Maven dependency tree, commons-logging still showed up now as a dependency of json-lib, another dependency which the project has.

It became clear quickly that manually excluding all unwanted logging dependencies would not scale well. The slf4j documentation goes on to suggest using scope provided as an option:

<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <scope>provided</scope>
</dependency>

However, as this SO question discusses, this approach still means that the other logging frameworks would be present during testing. Also, it is not clear to me whether this provided option would apply to all versions of commons-logging, or would a specific entry be needed for each version. If the latter be the case, then this would be as tedious as just manually excluding commons-logging everywhere.

What is the best practice for excluding unwanted logging dependencies to configure slf4j in a Java application?

like image 801
Tim Biegeleisen Avatar asked Nov 06 '22 16:11

Tim Biegeleisen


1 Answers

Commons logging is not an slf4j implementation. Just leave it on the class path and include Log4J-Jcl to route all commons logging calls to Log4J.

like image 162
rgoers Avatar answered Nov 14 '22 19:11

rgoers