AWS EC2 Tomcat SpringBoot 배포 에러 수정하기

Date:     Updated:

카테고리:

태그: , , ,

1. SpringBoot 프로젝트를 WAR배포 중 오류 발생

지난 시간 AWS EC2에 배포를 위해 tomcat8.5를 구축 하였다.

AWS EC2 tomcat 구축 참조 : https://hagenti0612.github.io/aws/aws-tomcat/

멘토링을 하면서 가르치던 학생에게 로컬로 동작시키면 같은네트워크에서만 접속이 가능하고 나중에 포트폴리오 작성이나 취업단계 면접에서 조금 부족한감이 있으니 서버호스팅을 받아서 배포까지 해보라고 했었다. jar동작은 문제 없었는데, war로 만들어서 WAS에 배포하는 것이 계속 실패 한다고 도움을 요청받았다.

접속 정보와 WAR파일을 받고 분석을 시작하였다.

증상 확인

로그 확인

org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/8.5.87]
org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [/usr/local/tomcat8.5/webapps/gympti.war]
org.apache.jasper.EmbeddedServletOptions.<init> The scratchDir you specified: [/usr/local/tomcat8.5/work/Catalina/localhost/gympti] is unusable.
org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [/usr/local/tomcat8.5/webapps/gympti.war] has finished in [61] ms
org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8888"]
org.apache.catalina.startup.Catalina.start Server startup in 1524 ms

에러가 없다. 그런데 없는게 문제인 상황인다. 부탁받은 war파일은 Springboot로 되어 있다. 정사적인 동작이라면 스프링로그가 출력이 되어야하는데 에러도 없이 실행이 안된다.

문제점

  1. WarLauncher가 실행되지하지 않았다.
  2. 부트 중 에러가 발생하지 않았다.
  3. 단순 웹서버로만 동작이 되었다.

2. 빌드 환경 확인

첫번째 문제점 발견

public class GymPtiApplication {

	public static void main(String[] args) {
		SpringApplication.run(GymPtiApplication.class, args);
	}

}

메인문지 위와 같이 작성되어 있었다. 동작 설명이 부족했었던거 같다.

jar 실행일 경우 상속없이 메인문만 작성하면 된다.
그러나 WAS에서 동작하는 웹어플리케이션으로 동작할 경우 해당하는 Start-boot를 설정해야한다.

이번의 경우 tomcat으로 동작 시킬것이니 의존성에 추가를 하라고 하였다.

학생이 만든 프로젝트는 maven이 아니라 gradle로 만들어져 있어서 아래와 같이 추가 하도록 하였다.

implementation 'org.springframework.boot:spring-boot-starter-tomcat'

그리고 메인문을 수정을 하였다.

@SpringBootApplication
public class GymPtiApplication extends SpringBootServletInitializer {

	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
		return application.sources(GymPtiApplication.class);
	}

	public static void main(String[] args) {
		SpringApplication.run(GymPtiApplication.class, args);
	}

}

재배포 동일 에러 발생

로그 재확인

org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/8.5.87]
org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [/usr/local/tomcat8.5/webapps/gympti.war]
org.apache.jasper.EmbeddedServletOptions.<init> The scratchDir you specified: [/usr/local/tomcat8.5/work/Catalina/localhost/gympti] is unusable.
org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [/usr/local/tomcat8.5/webapps/gympti.war] has finished in [61] ms
org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8888"]
org.apache.catalina.startup.Catalina.start Server startup in 1524 ms

이상하다 이번엔 War를 실행 할 수 있도록 다 연결하였는데 에러가 발생하였다. 에러 없이 실행이 안된다.

이번엔 예상이 안되서 혹시 몰라서 WAR파일을 압축 프로그램으로 풀고 구조를 분석해서 다시 보았다.

image image

META-INF > MANIFEST.MF

일반적으로 Boot.war로 빌드 할 경우 MANIFEST.MF 프로젝트의 정보가 요약되어 있다.

Manifest-Version: 1.0
Main-Class: org.springframework.boot.loader.WarLauncher
Start-Class: kr.hs.dgsw.GymPTI.GymPtiApplication
Spring-Boot-Version: 3.0.5
Spring-Boot-Classes: WEB-INF/classes/
Spring-Boot-Lib: WEB-INF/lib/
Spring-Boot-Classpath-Index: WEB-INF/classpath.idx
Spring-Boot-Layers-Index: WEB-INF/layers.idx
Build-Jdk-Spec: 17
Implementation-Title: GymPTI
Implementation-Version: 0.0.1-SNAPSHOT

열어 보았더니 이상한 것이 보인다. java는 17버전 문제 없었다. 그런데 Spring-Boot-Vesion이 3.0.5이다. 너무 높았다. 업무상으로 진행한 프로젝트는 대부분 java8로 빌드 되었고, Spring-Boot-Version이 2.X였다. 라이브러리 의존성을 확인해보았다.

image

어 느낌이 온다. Maven repository에서 확인해보자

참조 사이트 : https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-tomcat/3.0.5

image

찾았다! Springboot:3.0.5 당연히 연결된 boot-starterTomcat 10.1.7이 필요하다.

해결방안

  1. Server에 설치 된 Tomcat8.5를 Tomcat 10.1.7 이상으로 올린다.
  2. 프로젝트의 SpringBoot를 2.0.x 버전으로 변경하고 의존성을 해결한다.

2번 방법에 이미 익숙해서 이번엔 학습겸 1번으로 처리해보도록 한다.

2. 문제 해결

Tomcat 10 설치

톰캣 설치는 이전 포스팅을 확인해보자.

공식 사이트 : https://tomcat.apache.org/download-10.cgi

image

AWS EC2에 설치 할 것이니 tar파일로 받는다.

다운링크 : https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.7/bin/apache-tomcat-10.1.7.tar.gz

같은 내용이니 중의 점만 빠르게 요약한다.

# 이전 서버 동작 정지
sudo /usr/local/tomcat8.5/bin/shutdown.sh

# wget으로 tomcat 8.5를 다움 받는다.
sudo wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.7/bin/apache-tomcat-10.1.7.tar.gz
# 압축 해제
sudo tar xvfz apache-tomcat-10.1.7.tar.gz

# 폴더를 이동시키면서 폴더명변경
sudo mv apache-tomcat-10.1.7/ /usr/local/tomcat10

tomcat 환경 변경

# 환경 설정
sudo vi /etc/profile
# 첫 설치일 경우 추가, 이미 있을경우 변경
export CATALINA_HOME=/usr/local/tomcat10

# 환경 재적용
source /etc/profile

# 환경변수 확인
echo $CATALINA_HOME
# 환경 설정 파일을 수정한다.
sudo vi /usr/local/tomcat10/conf/server.xml

# 아래 내용을 찾은 후 UTF8 인코딩 설정을 추가한다.
<Connector port="8080" protocol="HTTP/1.1"
               URIEncoding="UTF-8"
               connectionTimeout="20000"
               redirectPort="8443" />

서버 재기동

# 시작
/usr/local/tomcat8.5/bin/startup.sh

# 중지
/usr/local/tomcat8.5/bin/shutdown.sh

# 동작확인
ps -ef | grep tomcat

# 로그위치
/usr/local/tomcat10/bin/logs/catalina.out

문제 해결 확인

org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/10.1.7]
org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat10/webapps/gympti]
org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.0.5)

kr.hs.dgsw.GymPTI.GymPtiApplication      : Starting GymPtiApplication v0.0.1-SNAPSHOT using Java 17.0.6 with PID 306080 (/usr/local/tomcat10/webapps/gympti/WEB-INF/classes started by ec2-user in /usr/local/tomcat10/bin)

Spirng 로고와 함께 Spring Boot v3.0.5가 표시되면서 정상적으로 동작을 한다.

3. 느낀점

gradle을 maven을 사용할 때 회사의 프로젝트는 대부분 외부와 차단된 내부망으로 동작을 한다. 그럴 경우 항상 버전에 의한 외부요인은 없었으며 front, bacnkend 둘다 일반적으로 구조 맞게 빈파일이나 카피 하여 작업을 했었다. 그런데 인터넷에 연결된 상태에서 의존성에 버전을 명시 하지 않으니 라이브러리가 최신버전으로 업데이트가 되면서 코드 한 줄 수정하지 않았는데 배포가 안되는 현상이 발생했다. 문제를 인식하고 하나씩 확인 하는 과정에서 원인을 찾아낸 후 해결하여 동작을 하였다.

안될 때는 머리가 좀 아팠지만 해결이되니 매우 기분이 좋았다.

그리고 질문을 던진 학생이 고마웠다.

학생들은 도전정신이 강했다. java최신버전, maven, gradle을 이용한 최신라이브러리 갱신, 새로운 아이디어, 시도를 많이 하고 있었다. 회사는 효율 중심이다 보니 이미 해봤던거, 빨리 개발 할 수있는 방식으로 선호한다. 그러나 이 친구들은 그런것이 없으니 같이 공부 할 것이 많았다.


개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우 
댓글 또는 메일로 알려주시면 감사하겠습니다.

맨 위로 이동하기

aws 카테고리 내 다른 글 보러가기

댓글 남기기