Java/Maven

[Troubleshooting] Spring Boot 2.3 + JEUS 로그 라이브러리 충돌 해결

범데이 2026. 5. 5. 11:20

Spring Boot 2.3 기반 프로젝트를 JEUS에 배포하는 과정에서 로그 라이브러리 충돌 문제가 발생했다.

특이한 점은 로컬에서 src 폴더를 직접 구동할 때는 아무 문제가 없었다는 것이다. 빌드된 target 폴더를 실행하거나 JEUS에 배포할 때만 문제가 생겼다.

 

1. 문제 상황

로컬 Smart Tomcat에서 소스(src) 폴더를 직접 지정해 실행하면 정상 동작했다.

그런데 빌드 결과물인 target 폴더를 실행 대상으로 잡거나 운영 서버(JEUS)에 배포하면 Multiple SLF4J bindings 에러와 함께 기동이 실패했다.

 

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/.../logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/.../log4j-slf4j-impl-2.17.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]

 

 

 

2. 원인 분석

소스 코드 실행과 빌드 결과물 실행의 차이에서 오는 의존성 충돌 문제였다.

 

src 모드에서는 IntelliJ가 클래스패스를 관리하며 중복된 라이브러리 중 하나에 임의로 우선순위를 두어 실행한다. 덕분에 충돌이 잠복해 있어도 표면에 드러나지 않는다.

 

반면 Maven이 빌드를 수행하면 pom.xml에 정의된 모든 의존성을 WEB-INF/lib으로 물리적으로 복사한다. 이때 의존성 전이(Transitive Dependency)로 끌려온 log4j-slf4j-impllogback과 같은 폴더에 놓이면서 물리적 충돌이 비로소 발생한다.

 

JEUS는 클래스패스 내 모든 JAR를 엄격하게 검사하기 때문에 중복 바인딩이 발견되면 기동 자체를 거부한다.

 

 

3. 해결 방법

빌드 결과물에 불필요한 라이브러리가 포함되지 않도록 강제 조치해야 한다.

 

방법 1: Provided Scope 활용 (추천)

log4j-slf4j-impl이 어떤 경로로 유입되는지 특정하기 어려울 때 가장 확실한 방법이다. pom.xml에 해당 의존성을 명시하고 배포 시 제외되도록 설정한다.

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.17.1</version>
    <scope>provided</scope>
</dependency>

 

 

방법 2: Exclusion 설정

유입 경로를 확인했다면 상위 라이브러리 설정에서 직접 해당 모듈을 제외한다.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
        </exclusion>
    </exclusions>
</dependency>

 

 

4. 정리

src 폴더 실행 시 문제가 없다고 해서 의존성이 깨끗한 것은 아니다.

 

provided 스코프는 "서버가 제공할 것이니 빌드 결과물에는 넣지 마라"는 의미다. 원치 않는 중복 라이브러리가 target에 유입되는 것을 막는 가장 확실한 방법이다.

 

빌드 후 WEB-INF/lib 안에 두 라이브러리가 공존하는지 확인하는 습관이 필요하다.

 
 
728x90
반응형