Seamlessly Switch Java Logging Frameworks: Log4j, Logback, SLF4J, JDK
This guide explains how to integrate and switch among Java logging libraries—including JDK logging, Log4j 1, Log4j 2, Logback, Commons‑Logging, and SLF4J—by using bridge jars, configuring dependencies, and understanding conflict resolution for seamless migration.
1 Series Catalog
JDK logging, Log4j, Logback introduction and principles
Commons‑logging integration with JDK logging, Log4j 1, Log4j 2, Logback
SLF4J, JCL, JUL, Log4j 1, Log4j 2, Logback comprehensive summary
2 Various JAR Packages Summary
log4j1
log4j – all Log4j 1 content
log4j2
log4j-api – API defined by Log4j 2
log4j-core – implementation of the API
logback
logback-core – core package
logback-classic – implements the SLF4J API
commons‑logging
commons‑logging – native content
log4j-jcl – bridge from commons‑logging to Log4j 2
jcl‑over‑slf4j – bridge from commons‑logging to SLF4J
SLF4J to a concrete logging framework
slf4j‑jdk14 – bridge to JDK logging
slf4j‑log4j12 – bridge to Log4j 1
log4j‑slf4j‑impl – bridge to Log4j 2
logback‑classic – bridge to Logback
slf4j‑jcl – bridge to Commons‑logging
Concrete logging framework to SLF4J
jul‑to‑slf4j – JDK logging to SLF4J
log4j‑over‑slf4j – Log4j 1 to SLF4J
jcl‑over‑slf4j – Commons‑logging to SLF4J
3 Integration Summary
3.1 Commons‑logging with other logging frameworks
1) Commons‑logging with JDK logging – requires commons‑logging 2) Commons‑logging with Log4j 1 – requires commons‑logging and log4j 3) Commons‑logging with Log4j 2 – requires commons‑logging, log4j‑api, log4j‑core, log4j‑jcl 4) Commons‑logging with Logback – requires logback‑core, logback‑classic, slf4j‑api, jcl‑over‑slf4j 5) Commons‑logging with SLF4J – requires jcl‑over‑slf4j and
slf4j‑api3.2 SLF4J with other logging frameworks
SLF4J with JDK logging – requires slf4j‑api and slf4j‑jdk14 SLF4J with Log4j 1 – requires slf4j‑api, log4j, slf4j‑log4j12 SLF4J with Log4j 2 – requires slf4j‑api, log4j‑api, log4j‑core, log4j‑slf4j‑impl SLF4J with Logback – requires slf4j‑api, logback‑core, logback‑classic SLF4J with Commons‑logging – requires slf4j‑api, commons‑logging,
slf4j‑jcl4 Switching Between Logging Systems
4.1 Log4j 1 to Logback
4.1.1 Example
Code originally uses Log4j 1 API:
private static final Logger logger = Logger.getLogger(Log4jTest.class);
public static void main(String[] args) {
if (logger.isInfoEnabled()) {
logger.info("log4j info message");
}
}To redirect output to Logback without changing source code, replace the JARs:
Remove log4j JAR
Add log4j‑over‑slf4j, slf4j‑api, logback‑core, logback‑classic Place a Logback configuration file on the classpath
4.1.2 Switching Principle
The log4j‑over‑slf4j JAR provides a simplified Log4j implementation that delegates to SLF4J. The simplified Logger looks like:
public class Category {
private String name;
protected org.slf4j.Logger slf4jLogger;
private org.slf4j.spi.LocationAwareLogger locationAwareLogger;
Category(String name) {
this.name = name;
slf4jLogger = LoggerFactory.getLogger(name);
if (slf4jLogger instanceof LocationAwareLogger) {
locationAwareLogger = (LocationAwareLogger) slf4jLogger;
}
}
}Because SLF4J finds Logback on the classpath, Logback becomes the actual output destination, achieving a seamless Log4j 1 → Logback migration.
4.2 JDK Logging to Logback
4.2.1 Example
private static final Logger logger = Logger.getLogger(JulSlf4jLog4jTest.class.getName());
public static void main(String[] args) {
logger.log(Level.INFO, "jul info a msg");
logger.log(Level.WARNING, "jul warning a msg");
}Solution:
Add jul‑to‑slf4j, slf4j‑api, logback‑core, logback‑classic Place a Logback configuration file on the classpath
Register the bridge handler:
static {
SLF4JBridgeHandler.install();
}4.2.2 Switching Principle
The jul‑to‑slf4j JAR contains SLF4JBridgeHandler, which extends java.util.logging.Handler. After calling SLF4JBridgeHandler.install(), JDK logging records are forwarded to SLF4J, which then uses Logback for actual output.
4.3 Commons‑logging to Logback
4.3.1 Example
private static Log logger = LogFactory.getLog(JulJclTest.class);
public static void main(String[] args) {
if (logger.isTraceEnabled()) {
logger.trace("commons‑logging‑jcl trace message");
}
}Solution:
Remove (optional) commons‑logging JAR
Add jcl‑over‑slf4j, slf4j‑api, logback‑core, logback‑classic Place a Logback configuration file on the classpath
4.3.2 Switching Principle
Commons‑logging is bridged to SLF4J via jcl‑over‑slf4j; SLF4J then selects Logback, completing the migration.
4.4 Common Switching Scenarios
Three typical migration diagrams (originally from SLF4J documentation) illustrate how mixed logging APIs can be unified to a single backend (Logback, Log4j 1, or JDK logging) by first bridging everything to SLF4J and then selecting the desired concrete implementation.
4.4.1 Scenario: Consolidate to Logback
Existing APIs: Commons‑logging, Log4j 1, JDK logging
Steps:
Add slf4j‑api, logback‑core, logback‑classic Bridge Commons‑logging with jcl‑over‑slf4j Bridge Log4j 1 with log4j‑over‑slf4j (remove original Log4j 1 JAR)
Bridge JDK logging with jul‑to‑slf4j Result: All logs flow through SLF4J to Logback
4.4.2 Scenario: Consolidate to Log4j 1
Existing APIs: Commons‑logging, JDK logging
Steps:
Add slf4j‑api, log4j, slf4j‑log4j12 Bridge Commons‑logging with jcl‑over‑slf4j Bridge JDK logging with jul‑to‑slf4j Result: All logs flow through SLF4J to Log4j 1
4.4.3 Scenario: Consolidate to JDK logging
Existing APIs: Commons‑logging, Log4j 1
Steps:
Add slf4j‑api, slf4j‑jdk14 Bridge Commons‑logging with jcl‑over‑slf4j Bridge Log4j 1 with log4j‑over‑slf4j (remove original Log4j 1 JAR)
Result: All logs flow through SLF4J to JDK logging
5 Conflict Explanation
Some bridge and implementation JARs conflict when both directions are present, leading to circular delegation and potential memory leaks.
5.1 jcl‑over‑slf4j vs slf4j‑jcl
jcl‑over‑slf4j: Commons‑logging → SLF4J
slf4j‑jcl: SLF4J → Commons‑logging
Having both creates mutual delegation and can cause OOM.
5.2 log4j‑over‑slf4j vs slf4j‑log4j12
log4j‑over‑slf4j: Log4j 1 → SLF4J
slf4j‑log4j12: SLF4J → Log4j 1
Both together cause circular delegation, but Log4j‑over‑SLF4J checks for the presence of Log4jLoggerFactory and throws an exception to prevent the conflict.
5.3 jul‑to‑slf4j vs slf4j‑jdk14
jul‑to‑slf4j: JDK logging → SLF4J
slf4j‑jdk14: SLF4J → JDK logging
Both together also lead to circular delegation and possible memory overflow.
6 Conclusion
This series completes the overview of interactions and integrations among Java logging systems. For deeper architectural details of each individual logging framework, further independent study is required.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
ITFLY8 Architecture Home
ITFLY8 Architecture Home - focused on architecture knowledge sharing and exchange, covering project management and product design. Includes large-scale distributed website architecture (high performance, high availability, caching, message queues...), design patterns, architecture patterns, big data, project management (SCRUM, PMP, Prince2), product design, and more.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
