From 4b4503085a41b21c3de4612180946c87d1fca3f6 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 12 Dec 2018 11:16:36 +0100 Subject: [PATCH] Prefer SLF4J SPI over Log4J in case of log4j-to-slf4j bridge Issue: SPR-17586 --- .../apache/commons/logging/LogAdapter.java | 60 ++++++++++++------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java b/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java index 51a74cec539..a2f44f160e6 100644 --- a/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java +++ b/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java @@ -36,32 +36,42 @@ import org.slf4j.spi.LocationAwareLogger; */ final class LogAdapter { - private static LogApi logApi = LogApi.JUL; + private static final String LOG4J_SPI = "org.apache.logging.log4j.spi.ExtendedLogger"; + + private static final String LOG4J_SLF4J_PROVIDER = "org.apache.logging.slf4j.SLF4JProvider"; + + private static final String SLF4J_SPI = "org.slf4j.spi.LocationAwareLogger"; + + private static final String SLF4J_API = "org.slf4j.Logger"; + + + private static final LogApi logApi; static { - ClassLoader cl = LogAdapter.class.getClassLoader(); - try { - // Try Log4j 2.x API - Class.forName("org.apache.logging.log4j.spi.ExtendedLogger", false, cl); - logApi = LogApi.LOG4J; - } - catch (ClassNotFoundException ex1) { - try { - // Try SLF4J 1.7 SPI - Class.forName("org.slf4j.spi.LocationAwareLogger", false, cl); + if (isPresent(LOG4J_SPI)) { + if (isPresent(LOG4J_SLF4J_PROVIDER) && isPresent(SLF4J_SPI)) { + // log4j-to-slf4j bridge -> we'll rather go with the SLF4J SPI; + // however, we still prefer Log4j over the plain SLF4J API since + // the latter does not have location awareness support. logApi = LogApi.SLF4J_LAL; } - catch (ClassNotFoundException ex2) { - try { - // Try SLF4J 1.7 API - Class.forName("org.slf4j.Logger", false, cl); - logApi = LogApi.SLF4J; - } - catch (ClassNotFoundException ex3) { - // Keep java.util.logging as default - } + else { + // Use Log4j 2.x directly, including location awareness support + logApi = LogApi.LOG4J; } } + else if (isPresent(SLF4J_SPI)) { + // Full SLF4J SPI including location awareness support + logApi = LogApi.SLF4J_LAL; + } + else if (isPresent(SLF4J_API)) { + // Minimal SLF4J API without location awareness support + logApi = LogApi.SLF4J; + } + else { + // java.util.logging as default + logApi = LogApi.JUL; + } } @@ -92,6 +102,16 @@ final class LogAdapter { } } + private static boolean isPresent(String className) { + try { + Class.forName(className, false, LogAdapter.class.getClassLoader()); + return true; + } + catch (ClassNotFoundException ex) { + return false; + } + } + private enum LogApi {LOG4J, SLF4J_LAL, SLF4J, JUL}