Jay
Jay

Reputation: 57

Changing JHipster to use log4j2

I've built a sample Jhipster app. One of the first things I want to do is change the default logging to use log4j2.

I've updated my app's spring-boot property to point to version 1.2.0 M2.

looking around I've found some samples of ways to exclude logback and include log4j2 but I'm not making much headway. I've managed to include log4j2 but It's still finding references to logback. I believe I may need to change some of the boilerplate code jhipster generated for me but in trying to learn manythings at once I'm not sure of the best approach(es).

Here is a portion of my gradle file where I tried to exclude logging (per other googling I did), and inserted log4j2:

compile group: 'com.mattbertolini', name: 'liquibase-slf4j', version: liquibase_slf4j_version
compile group: 'org.springframework.boot', name: 'spring-boot-actuator', version: spring_boot_version
compile group: 'org.springframework.boot', name: 'spring-boot-starter-log4j2', version:spring_boot_version
compile group: 'org.springframework.boot', name: 'spring-boot-autoconfigure', version: spring_boot_version
compile group: 'org.springframework.boot', name: 'spring-boot-loader-tools', version: spring_boot_version
compile group: 'org.springframework.boot', name: 'spring-boot-starter-aop', version: spring_boot_version
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: spring_boot_version
compile group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: spring_boot_version
compile group: 'org.springframework.boot', name: 'spring-boot-starter-tomcat', version: spring_boot_version
compile(group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: spring_boot_version) {
    exclude (module: 'spring-boot-starter-logging')
    exclude (module: 'spring_boot-starter-tomcat')
}
compile group: 'org.springframework.boot', name: 'spring-boot-starter-tomcat', version: spring_boot_version
compile group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf', version: spring_boot_version
compile group: 'org.springframework.cloud', name: 'spring-cloud-cloudfoundry-connector', version: spring_cloud_version
compile group: 'org.springframework.cloud', name: 'spring-cloud-spring-service-connector', version: spring_cloud_version
compile group: 'org.springframework.cloud', name: 'spring-cloud-localconfig-connector', version: spring_cloud_version
compile(group: 'org.springframework', name: 'spring-context-support') {
    exclude(module: 'quartz')
}

doing this I'm getting some odd errors when I try to start up my app:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Users/sssn/.gradle/caches/modules-2/files2.1/org.apache.logging.log4j/log4j-slf4j-impl/2.0.2/f2cc4647e51810c3dd11df832229fac01d41aa51/log4j-slf4j-impl-2.0.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/sssn/.gradle/caches/modules-2/files-2.1/ch.qos.logback/logback-classic/1.1.2/b316e9737eea25e9ddd6d88eaeee76878045c6b2/logback-classic-1.1.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]
Exception in thread "main" java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation (class org.apache.logging.slf4j.Log4jLoggerFactory loaded from file:/C:/Users/jmcgaffigan/.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-slf4j-impl/2.0.2/f2cc4647e51810c3dd11df832229fac01d41aa51/log4j-slf4j-impl-2.0.2.jar). Object of class [org.apache.logging.slf4j.Log4jLoggerFactory] must be an instance of class ch.qos.logback.classic.LoggerContext

If anyone has any tips or suggested "try this" it'd be most appreciated.

UPDATE: Running gradle dependencies always shows the logging coming in via the boot-start-aop package:

+--- org.springframework.boot:spring-boot-starter-aop:1.2.0.M2
|    +--- org.springframework.boot:spring-boot-starter:1.2.0.M2
|    |    +--- org.springframework.boot:spring-boot:1.2.0.M2 (*)
|    |    +--- org.springframework.boot:spring-boot-autoconfigure:1.2.0.M2 (*)
|    |    +--- org.springframework.boot:spring-boot-starter-logging:1.2.0.M2
|    |    |    +--- org.slf4j:jcl-over-slf4j:1.7.7
|    |    |    |    \--- org.slf4j:slf4j-api:1.7.7
|    |    |    +--- org.slf4j:jul-to-slf4j:1.7.7
|    |    |    |    \--- org.slf4j:slf4j-api:1.7.7
|    |    |    +--- org.slf4j:log4j-over-slf4j:1.7.7
|    |    |    |    \--- org.slf4j:slf4j-api:1.7.7
|    |    |    \--- ch.qos.logback:logback-classic:1.1.2
|    |    |         +--- ch.qos.logback:logback-core:1.1.2
|    |    |         \--- org.slf4j:slf4j-api:1.7.6 -> 1.7.7
|    |    +--- org.springframework:spring-core:4.1.1.RELEASE (*)
|    |    \--- org.yaml:snakeyaml:1.13
|    +--- org.springframework:spring-aop:4.1.1.RELEASE (*)
|    +--- org.springframework:spring-core:4.1.1.RELEASE (*)
|    +--- org.aspectj:aspectjrt:1.8.2
|    \--- org.aspectj:aspectjweaver:1.8.2
+--- org.springframework.boot:spring-boot-starter:1.2.0.M2 (*)

I've tried doing the exclude on teh starter-aop and start packages but still no luck.

Upvotes: 2

Views: 2350

Answers (1)

Andy Wilkinson
Andy Wilkinson

Reputation: 116191

If you want to use dependency excludes then, to successfully exclude something, the exclusion needs to be applied to every dependency that transitively depends on the module you're trying to exclude. This can get unwieldy very quickly – you'd need to declare the exclusion on pretty much all of your Spring Boot dependencies.

A better alternative is to apply the exclusion to the whole configuration:

configurations {
    compile.exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}

Or even to every configuration:

configurations {
    all*.exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}

Upvotes: 2

Related Questions