레거시

(레거시) StackOverflowError, 순환 참조 오류

Drider 2025. 7. 22. 16:56

1. "자식 컨테이너를 시작 중 실패했습니다."

      심각: 자식 컨테이너를 시작 중 실패했습니다.
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: 
    구성요소 [StandardEngine[Catalina].StandardHost[localhost]... ]을(를) 시작하지 못했습니다.
...
Caused by: java.lang.IllegalStateException: StackOverflowError로 인하여, 
    웹 애플리케이션에서 annotation 스캔을 완료하지 못했습니다. 
    ... 불허된 순환 상속 의존관계들일 수 있습니다. 
    처리되는 클래스의 상속 계층구조는 
    [java.security.KeyPairGeneratorSpi->java.security.KeyPairGenerator->java.security.KeyPairGeneratorSpi]입니다.
    

 

로그는 친절하게도 원인이 StackOverflowError이며, "순환 상속 의존관계" 때문일 수 있다고 알려주었습니다. 톰캣이 웹 애플리케이션의 라이브러리(JAR)들을 스캔하다가, 특정 클래스의 상속 구조가 꼬리에 꼬리를 무는 무한 반복에 빠져버린 것입니다.

 

2. 첫 번째 시도: 스택 크기를 늘리면 되지 않을까? (실패)

오류 메시지는 -Xss 설정이 너무 작을 수 있다는 가능성도 제시했습니다. 가장 손쉬운 방법이었죠. 이클립스 서버 설정(Open launch configuration)의 VM arguments에 -Xss1024k 옵션을 추가하고 서버를 재시작했습니다.

 

결과: 실패. 로그는 토씨 하나 바뀌지 않고 동일한 오류를 뿜어냈습니다. 이는 스택의 절대적인 크기가 문제가 아니라, 해결 불가능한 논리적 루프가 문제의 핵심임을 의미했습니다.

 

3. 두 번째 시도: 범인은 이 안에 있어! jarsToSkip

이제 정공법으로 가기로 했습니다. 톰캣의 어노테이션 스캔 기능이 문제를 일으키니, 문제가 되는 라이브러리를 스캔 대상에서 제외하는 것입니다.

이런 종류의 순환 참조 오류는 주로 BouncyCastle과 같은 암호화 라이브러리에서 발생한다는 사실을 경험적으로 알고 있었습니다.

  1. 톰캣 설정 파일인 conf/catalina.properties를 열었습니다.
  2. 어노테이션 스캔 제외를 담당하는 org.apache.catalina.startup.ContextConfig.jarsToSkip 속성을 찾아, 가장 유력한 용의자인 bcprov-*.jar를 추가했습니다.
      org.apache.catalina.startup.ContextConfig.jarsToSkip=bcprov-*.jar
    

결과: 또 실패. 하지만... 새로운 단서 발견!

놀랍게도 오류 메시지가 바뀌었습니다!

 

      Caused by: java.lang.IllegalStateException: StackOverflowError...
    처리되는 클래스의 상속 계층구조는 
    [예시A솔루션.예시.예시.예시클래스->java.security.KeyPairGenerator->...]입니다.

범인이 bcprov가 아니라 예시A솔루션 관련 라이브러리라고 자백한 셈입니다. 방향이 맞았다는 확신이 들었습니다.

 

4. 세 번째 시도: 진짜 범인과 끝나지 않는 악몽

저는 환호하며 catalina.properties 파일을 다시 열어 예시A솔루션*.jar를 추가했습니다.

      org.apache.catalina.startup.ContextConfig.jarsToSkip=bcprov-*.jar,예시A솔루션*.jar```

2단계: 환경 완전 초기화 (가장 중요!)

이클립스가 물고 있는 낡은 설정과 임시 파일을 완전히 제거하는 작업입니다. 

  1. 이클립스 Servers 뷰에서 톰캣 서버를 삭제(Delete)했습니다.
  2. 프로젝트 메뉴에서 Project -> Clean 을 실행했습니다.
  3. 워크스페이스의 .metadata 폴더 깊숙이 숨어있는, 이클립스가 만든 톰캣 임시 폴더(.../.plugins/org.eclipse.wst.server.core/tmp0)를 물리적으로 삭제 하면 더욱 철저 하지만 안함.
  4. 이클립스를 재시작하고, Servers 뷰에서 톰캣 서버를 새로 추가했습니다.

결과: 대성공!

마침내 서버가 시작되었습니다. 콘솔에는 StackOverflowError 대신, 스프링 빈(Bean)들이 정상적으로 로딩되는 반가운 로그들이 가득했습니다.

 
  1. 오류 로그가 가리키는 범인이 계속 바뀐다면, 여러 라이브러리가 복합적으로 문제를 일으키거나 개발 환경의 캐시가 꼬였을 확률이 높습니다.
  2. 원인을 알 수 없을 땐, 의심되는 설정을 모두 적용하고 개발 환경(특히 이클립스의 서버 설정)을 초기화하는 것이 가장 확실한 해결책일 수 있습니다.

'레거시' 카테고리의 다른 글

오래된 프로젝트 복원 -2-  (0) 2026.06.16
오래된 프로젝트 복원 -1-  (0) 2026.06.16