Tomcat War Deploy 404 (Feat. EC2) - Maven Clean

 오늘의 글은 나의 경험담을 정리하려고 한다. 무슨 경험이라고? 내가 삽질한 경험이다.

우선, 개발 환경부터 간단하게 정리해보겠다. 


단일 EC2 환경이다. 아래와 같이 여러 가지 개발 툴 을 설치했다.

- Jenkins (9090 port)

- Tomcat (8080 port) 

- Github

- Maven


Tomcat 에 Github 의 Spring 프로젝트를 Maven 을 이용하여 War 로 패키징하는 간단한 Deploy 방식이였다.

Deploy 는 Jenkins 프리스타일 프로젝트를 사용했다.


1. Git Parameter Plugin 을 이용해서 브랜치를 선택할 수 있게 한다.

2. NodeJS Plugin 과 기존에 설치해 둔 Maven 을 이용하여 Shell Script 를 실행하여 War 패키징 및 해당 EC2 Tomcat 에 올리고 실행하게 한다.


아래는 간단한 shell script 이다. 

maven PATH 를 잡아주고, 미리 설정해 둔 S3에서 properties 파일을 가져온다.

그리고 mvn 명령어를 통해서 war 로 패키징하고, 패키징 한 war 를 S3 에서 버전관리 한다.


그리고 톰캣을 우선 정지하고, 새로 패키징한 war 를 tomcat 경로에 맞게 올린다.

그리고 잠시 스레드를 5초 동안 잠재운다. 

그후에 다시 톰캣을 시작한다.




이러한 과정에서 여러 브랜치를 아마 대략 70 번 (?) 정도 배포 했다. 

70번 밑으로 배포는 정상적으로 배포가 잘 되었고, 테스트로 잘 할 수 있었다. 

그러나 70번 정도가 넘어가자, 달콤한 404 를 맞이하게 된다.


뭐지? 왜 잘 되던게 갑자기 안될까??? 제일 짜증나는 부분이다.

삽질을 하다가 tomcat log 를 찾아봤다.

/var/log/tomcat8/catalina.out

아래와 같이 ConflictingBeanDefinitionException 을 확인한다. 




ConflictingBeanDefinitionException 이 언제 일어나는 것일까?

예외를 말 그대로 해석하게 되면 Spring Bean 의 정의가 충돌한다고 한다.

근데.. Fuck.. 암만 코드레벨에서 찾아봐도 똑같은 Bean 이 없다..

https://docs.spring.io/spring/docs/4.2.0.RELEASE_to_4.2.1.RELEASE/Spring%20Framework%204.2.1.RELEASE/org/springframework/context/annotation/ConflictingBeanDefinitionException.html

삽질은 하다가, 원인을 찾았다.

개발을 진행하다보면, 기존의 java 파일들의 위치를 변경하게 된다. @Component ( @Controller, @RestContoller, @Service, @Repository ) 를 사용하여 Spring Bean 으로 등록할 경우에 문제가 생긴다.

예를 들어보자. 기존에 com.ndgndg91.member.controller.MemberController 라는 Controller 가 있었다.

그리고 해당 프로젝트를 war 로 패키징을 했을 경우, target 디렉토리 밑에 com.ndgndg91.member.controller.MemberController 라는 타입의 클래스 파일이 생성된다.

그리고 다른 브랜치에서 com.ndgndg91.member.controller.MemberController 를 com.ndgndg91.controller.memeber.MemberController 로 패키지를 이동을 했다. 그리고 나서 war 패키징을 시도한다.

결과적으로, MemberController 라는 @Controller 는 아래와 같이 2개가 존재하게 된다.

- com.ndgndg91.member.controller.MemberController

- com.ndgndg91.controller.member.MemberController

그리고 이는 달콤한 ConflictingBeanDefinitionException 를 마주하게 된다.

ConflictingBeanDefinitionException 이 제일 X 같은 것은 War 로 패키징 할 때는 전혀 문제가 되지 않는다. Build Success 라는 문구로 나를 기분좋게 현혹 시킨다. 하지만 EC2 에 War 를 Tomcat 에 올리고 시작하게 되면, 달콤하게 404 와 ConflictingBeanDefinitionException 을 맞이한다.

그래서, 내가 조치한 점은 mvn clean 이다. War 로 패키징하기 전에 무조건 clean 명령어를 통해서 target 디렉토리를 청소한다. 이를 통해 해당 이슈가 발생할 일을 없앤다.


이런 삽질하는 경험을 통해서 피닉스 서버의 필요성을 느끼게 되었다.
Immutable Infrastructure 가 좋다.

댓글

이 블로그의 인기 게시물

About JVM Warm up

About idempotent

About Kafka Basic

About ZGC

sneak peek jitpack

Spring Boot Actuator readiness, liveness probes on k8s

About Websocket minimize data size and data transfer cost on cloud

About G1 GC

대학생 코딩 과제 대행 java, python, oracle 네 번째