Tarmo
Tarmo

Reputation: 1266

Problems with slf4j dependency breaking log4j configuration

I have a project where I use log4j for logging and it used to work great. Now I had to add a dependency, which uses slf4j and suddenly the logging does not work as intended any more - some parts of the code disregard my log4j configuration and log in red color in Eclipse console.

This is the dependency tree when logging worked:

my.package.program:program-database:jar:0.3.0
+- my.package.program:program-common:jar:0.3.0:compile
|  +- org.apache.commons:commons-lang3:jar:3.4:compile
|  \- commons-io:commons-io:jar:2.4:compile
+- org.springframework:spring-tx:jar:4.1.0.RELEASE:compile
|  \- org.springframework:spring-core:jar:4.1.0.RELEASE:compile
|     \- commons-logging:commons-logging:jar:1.1.3:compile
+- org.springframework:spring-jdbc:jar:4.1.0.RELEASE:compile
+- org.jooq:jooq:jar:3.6.2:compile
+- org.jooq:jooq-meta:jar:3.6.2:compile
+- org.jooq:jooq-codegen:jar:3.6.2:compile
+- postgresql:postgresql:jar:9.1-901-1.jdbc4:compile
+- org.springframework:spring-beans:jar:4.1.0.RELEASE:compile
+- org.springframework:spring-context:jar:4.1.0.RELEASE:compile
|  +- org.springframework:spring-aop:jar:4.1.0.RELEASE:compile
|  |  \- aopalliance:aopalliance:jar:1.0:compile
|  \- org.springframework:spring-expression:jar:4.1.0.RELEASE:compile
+- org.apache.logging.log4j:log4j-api:jar:2.1:compile
+- org.apache.logging.log4j:log4j-core:jar:2.1:compile
+- org.apache.logging.log4j:log4j-1.2-api:jar:2.1:compile
+- junit:junit:jar:4.11:test
|  \- org.hamcrest:hamcrest-core:jar:1.3:test
+- org.springframework:spring-test:jar:4.1.0.RELEASE:test

This is the tree after I added a flyway plugin and which broke logging:

my.package.program:program-database:jar:0.3.0
+- my.package.program:program-common:jar:0.3.0:compile
|  +- org.apache.commons:commons-lang3:jar:3.4:compile
|  \- commons-io:commons-io:jar:2.4:compile
+- org.springframework:spring-tx:jar:4.1.0.RELEASE:compile
|  \- org.springframework:spring-core:jar:4.1.0.RELEASE:compile
|     \- commons-logging:commons-logging:jar:1.1.3:compile
+- org.springframework:spring-jdbc:jar:4.1.0.RELEASE:compile
+- org.jooq:jooq:jar:3.6.2:compile
+- org.jooq:jooq-meta:jar:3.6.2:compile
+- org.jooq:jooq-codegen:jar:3.6.2:compile
+- postgresql:postgresql:jar:9.1-901-1.jdbc4:compile
+- org.flywaydb.flyway-test-extensions:flyway-spring-test:jar:3.2.1:test
|  +- org.slf4j:slf4j-api:jar:1.5.6:test
|  +- org.slf4j:slf4j-simple:jar:1.5.6:test
|  +- org.flywaydb:flyway-core:jar:3.2.1:test
|  \- commons-dbcp:commons-dbcp:jar:1.4:test
|     \- commons-pool:commons-pool:jar:1.5.4:test
+- org.springframework:spring-beans:jar:4.1.0.RELEASE:compile
+- org.springframework:spring-context:jar:4.1.0.RELEASE:compile
|  +- org.springframework:spring-aop:jar:4.1.0.RELEASE:compile
|  |  \- aopalliance:aopalliance:jar:1.0:compile
|  \- org.springframework:spring-expression:jar:4.1.0.RELEASE:compile
+- org.apache.logging.log4j:log4j-api:jar:2.1:compile
+- org.apache.logging.log4j:log4j-core:jar:2.1:compile
+- org.apache.logging.log4j:log4j-1.2-api:jar:2.1:compile
+- junit:junit:jar:4.11:test
|  \- org.hamcrest:hamcrest-core:jar:1.3:test
+- org.springframework:spring-test:jar:4.1.0.RELEASE:test

I think the problem comes from the fact that spring includes a transitive dependency of commons-logging and when flyway pulls in slf4j, cli gets priority and my log4j configuration is ignored by some libraries (etc jooq and flyway starts to log in red).

I tried all 3 options mentioned here: http://www.slf4j.org/faq.html#excludingJCL but somewhy none of them worked. There was certainly an effect, but after solutions 2 and 3, spring also started logging in red.

After trying to blindly plug in different slf4j bindings and bridges and having no luck - I have to admit I do not know the logging frameworks well enough to come up with a solution myself. Any help and advice would be welcome.

Upvotes: 2

Views: 1288

Answers (1)

Tarmo
Tarmo

Reputation: 1266

Turns out my problems were caused by the flyway-spring-test extension which was including slf4j-simple binding as a dependency. Even when I added log4j binding myself, the slf4j-simple binding was still used and my log4j configuration had therefore no effect on the parts of code which used slf4j for logging.

To complicate matters further, jOOQ checks for logging frameworks at load time and prefers slf4j if it is found - so the addition of slf4j dependency with the flyway-spring-test extension forced jOOQ to switch logging frameworks automatically, creating more confusion for me.

In the end, once it was clear, what was the cause of problems, the fix was simple - remove the slf4j-simple binding and add slf4j-log4j binding. Due to a version mismatch problem, I had to replace the slf4j-api dependency with a newer version as well. The steps I took were:

  1. Excluding org.slf4j:slf4j-api from flyway-spring-test dependency
  2. Excluding org.slf4j:slf4j-simple from flyway-spring-test dependency
  3. Adding newer version of org.slf4j:slf4j-api to the project
  4. Adding org.apache.logging.log4j:log4j-slf4j-impl to the project

Logging seems to work now. The final dependency tree is:

my.package.program:program-database:jar:0.3.0
+- my.package.program:program-common:jar:0.3.0:compile
|  +- org.apache.commons:commons-lang3:jar:3.4:compile
|  \- commons-io:commons-io:jar:2.4:compile
+- org.springframework:spring-tx:jar:4.1.0.RELEASE:compile
|  \- org.springframework:spring-core:jar:4.1.0.RELEASE:compile
|     \- commons-logging:commons-logging:jar:1.1.3:compile
+- org.springframework:spring-jdbc:jar:4.1.0.RELEASE:compile
+- org.jooq:jooq:jar:3.6.2:compile
+- org.jooq:jooq-meta:jar:3.6.2:compile
+- org.jooq:jooq-codegen:jar:3.6.2:compile
+- postgresql:postgresql:jar:9.1-901-1.jdbc4:compile
+- org.flywaydb.flyway-test-extensions:flyway-spring-test:jar:3.2.1:test
|  +- org.flywaydb:flyway-core:jar:3.2.1:test
|  \- commons-dbcp:commons-dbcp:jar:1.4:test
|     \- commons-pool:commons-pool:jar:1.5.4:test
+- org.springframework:spring-beans:jar:4.1.0.RELEASE:compile
+- org.springframework:spring-context:jar:4.1.0.RELEASE:compile
|  +- org.springframework:spring-aop:jar:4.1.0.RELEASE:compile
|  |  \- aopalliance:aopalliance:jar:1.0:compile
|  \- org.springframework:spring-expression:jar:4.1.0.RELEASE:compile
+- org.apache.logging.log4j:log4j-api:jar:2.3:compile
+- org.apache.logging.log4j:log4j-core:jar:2.3:compile
+- org.apache.logging.log4j:log4j-1.2-api:jar:2.3:compile
+- org.apache.logging.log4j:log4j-slf4j-impl:jar:2.3:compile
+- org.slf4j:slf4j-api:jar:1.7.12:compile
+- junit:junit:jar:4.11:test
|  \- org.hamcrest:hamcrest-core:jar:1.3:test
+- org.springframework:spring-test:jar:4.1.0.RELEASE:test

Upvotes: 2

Related Questions