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.

ITFLY8 Architecture Home
ITFLY8 Architecture Home
ITFLY8 Architecture Home
Seamlessly Switch Java Logging Frameworks: Log4j, Logback, SLF4J, JDK

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‑api

3.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‑jcl

4 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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Integrationlogginglogbackslf4j
ITFLY8 Architecture Home
Written by

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.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.