logging-capabilities
logging-capabilities copied to clipboard
Using enforceLog4J2 within Spring Boot projects
Many thanks for this plugin! The detection part is working great for me, but I have a query on the configuration part.
Recommended approach
Within a Gradle project I'm apply 2 Spring Boot dependencies:
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web:2.6.2")
implementation("org.springframework.boot:spring-boot-starter-log4j2:2.6.2")
}
And I have a simple application class to show me what logging implementation is being used.
package com.tomgregory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Application {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(Application.class);
logger.error("Logging class: {}", logger.getClass());
}
}
Spring Boot's recommends using a module replacement rule to remove the default logback implementation from spring-boot-starter-web and replace it with log4j2.
modules {
module("org.springframework.boot:spring-boot-starter-logging") {
replacedBy("org.springframework.boot:spring-boot-starter-log4j2", "Use Log4j2 instead of Logback")
}
}
This works great when I run the application.
$ ./gradlew run -q
10:31:40.536 [main] ERROR com.tomgregory.Application - Logging class: class org.apache.logging.slf4j.Log4jLogger
Doing the same thing with the logging-capabilities plugin.
I remove the module replacement rule, apply the plugin, and call enforceLog4J2()
as per the build.gradle.kts below.
plugins {
application
id("dev.jacomet.logging-capabilities") version "0.10.0"
}
application {
mainClass.set("com.tomgregory.Application")
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web:2.6.2")
implementation("org.springframework.boot:spring-boot-starter-log4j2:2.6.2")
}
loggingCapabilities {
enforceLog4J2()
}
But I get an error at runtime.
$ ./gradlew run
> Task :compileJava FAILED
C:\workspace\exclude-dependency-examples\example3\src\main\java\com\tomgregory\Application.java:3: error: package org.slf4j does not exist
import org.slf4j.Logger;
What I found so far
The error comes because org.slf4j:slf4j-api that contains import org.slf4j.Logger;
isn't on the runtime classpath.
Using the module replacement rule, in the dependencies task output we see slf4j-api brought in by log4j-slf4j-impl.
| | +--- org.springframework.boot:spring-boot-starter-logging:2.6.2 -> org.springframework.boot:spring-boot-starter-log4j2:2.6.2
| | | +--- org.apache.logging.log4j:log4j-slf4j-impl:2.17.0
| | | | +--- org.slf4j:slf4j-api:1.7.25 -> 1.7.32
Using the logging-capabilities plugin, we see that log4j-slf4j-impl doesn't bring in any transitive dependencies, as it does above:
\--- org.springframework.boot:spring-boot-starter-log4j2:2.6.2
+--- org.apache.logging.log4j:log4j-slf4j-impl:2.17.0
+--- org.apache.logging.log4j:log4j-core:2.17.0 (*)
It could be quite helpful for Spring Boot developers to be able to use this plugin rather than use the module replacement rule.
Is my intended use case supported?
Thank you for your interest in this plugin.
This looks like another symptom of #12. There is a compatibility issue with the Spring Dependency Management plugin. I need to dig into that to figure out what's happening.
Replaced by:
- gradlex-org/jvm-dependency-conflict-resolution#166