SLF4J Warning : Class path contains multiple SLF4J bindings.

현주·2023년 7월 12일
0

Trouble Shooting

목록 보기
25/32

🔥 문제

과제를 하면서 프로젝트를 만드는 중,

log 기능을 만들다가 아래와 같은 에러를 만났다.

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Users/USER/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-simple/1.7.36/a41f9cfe6faafb2eb83a1c7dd2d0dfd844e2a936/slf4j-simple-1.7.36.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/USER/.gradle/caches/modules-2/files-2.1/ch.qos.logback/logback-classic/1.2.11/4741689214e9d1e8408b206506cbe76d1c6a7d60/logback-classic-1.2.11.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.slf4j.impl.SimpleLoggerFactory]
Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException
⠀⠀
Caused by: java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation (class org.slf4j.impl.SimpleLoggerFactory loaded from file:/C:/Users/USER/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-simple/1.7.36/a41f9cfe6faafb2eb83a1c7dd2d0dfd844e2a936/slf4j-simple-1.7.36.jar). If you are using WebLogic you will need to add 'org.slf4j' to prefer-application-packages in WEB-INF/weblogic.xml: org.slf4j.impl.SimpleLoggerFactory

위 에러 메세지를 대충 해석해보면 아래와 같다.

LoggerFactory가 Logback LoggerContext가 아닌데 Logback이 클래스 경로에 있습니다.
Logback 또는 경쟁 구현체를 제거합니다.
WebLogic을 사용하는 경우 애플리케이션 패키지에 'org.slf4j'를 추가해야 합니다.

이 에러는 SLF4J가 두 개의 바인딩을 발견했음을 알려주는 것 !
( 하나는 slf4j-log4j12-1.7.21.jar 에 / 다른 하나는 logback-classic-1.1.7.jar 에 )


💡 원인

위 에러 코드가 무슨 말인가 ~~ 하면 !

보통 Spring boot로 프로젝트를 만들게 되면 의존성으로 spring-boot-starter-web과 같은 스타터를 추가하는데

그렇게 되면 내부적으로 Logback이 설정되어 로깅을 수행하고,

이 Logback은 SLF4J의 구현체 중 하나로,

@Slf4j 애너테이션이 적용된 클래스는 Lombok이 컴파일 시간에 해당 클래스에 로거 필드를 자동으로 추가하여 Logback을 사용하도록 한다고 한다.

따라서 @Slf4j 애너테이션을 사용하면 내부적으로 Logback이 로거로 동작하며, 로그 메시지를 출력한다.

그런데 로그 기능을 만들면서 build.gradle에 SLF4J와 log4j 두개 모두 dependency를 추가하면서,

SLF4J는 한 번에 하나의 로깅 프레임워크에만 바인딩되는데,

클래스 경로에 둘 이상의 바인딩이 있어 에러가 발생한 것이었다.

SLF4J

  • facade 디자인 패턴을 사용한 로깅 프레임워크
  • Log4j, LogBack 이 SLF4J 를 구현한 구현체

facade 패턴

  • 여러개의 클래스가 하나의 역할을 수행할 때, 대표적인 인터페이스만을 다루는 클래스를두어 원하는 기능을 처리할 수 있게 도와주는 패턴

☘️ 해결

build.gradle의 configurations 부분에 표시해둔 부분을 추가하면 된다.

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
    // 여기부터 
	configureEach {
		exclude group: 'org.slf4j', module: 'slf4j-log4j12'
		exclude group: 'log4j', module: 'log4j'
		exclude group: 'org.slf4j', module: 'slf4j-jdk14'
		exclude group: 'org.slf4j', module: 'slf4j-simple'
	}
    // 여기까지
	asciidoctorExtensions
}

근데 나는 log4j 의존성 추가 안했는데 왜 났는지 모르겠지만 일단 저렇게 해결했다 !

< 참고한 사이트 >

0개의 댓글