프로젝트/해커톤

[spring boot][docker] jar vs war vs ear

김yejin 2022. 9. 17. 01:48

프로젝트 배포 작업에 들어갔다.
프로젝트 구성상, chat 페이지를 구현하기 위해서는 web 페이지의 배포작업이 우선되어야 한다.
따라서 먼저 리눅스 서버에 도커 컨테이너로 nginxproxymanager, tomcat, mysql 를 구성하고 서비스 배포를 진행하였다.


스펙 구성
ncp - centos 7.9.2009 (core) 서버
- nginx proxy manager Version 2.9.18 (cce73be) docker jc21/nginxproxymanager:latest
- Apache Tomcat/9.0.65 JVM version 17.0.4.1+1 docker tomcat:9 
- mysql  Ver 8.0.30 for Linux on x86_64 (MySQL Community Server - GPL) docker mysql:latest

web 페이지
사용자 : 쇼핑몰 개발자

1) 일반 요청
클라이언트 (https://shadows.site) -> nginxproxymanager(443 -> 8080) -> tomcat(8080) -> mysql(3306)

chat 페이지
사용자 : 쇼핑몰 이용 일반 유저 

2) naver clova api 요청
클라이언트 (https://shadows.site) -> nginxproxymanager(443 -> 8080) -> tomcat -> mysql(3306) -> tomcat(websocket) -> clova(websocket) -> tomcat -> mysql(3306) -> tomcat



배포에 들어가면서 tomcat 에 war로 배포를 하며, 여러번의 시행착오를 겪었는데 (각각의 시행착오도 글을 나누었다.)

1) spring boot 2.7.3 - tomcat 10 : 불가능
tomcat 9 -> 10 으로 올라가면서 javax.servlet -> jakarta.servlet 으로 변경되었는데
spring boot 에서는 아직 jakarta EE 9 를 지원하지 않아 에러 발생

2) gradle + war 배포 : SpringBootServletInitializer 상속 받아 configure 메소드 override 필요
war 파일 내의 WEB-INF에 web.xml 파일 대신 SpringBootServletInitializer 가 서블릿 필터와 매핑에 관한 초기 설정을 진행해주는데, 이를 상속하지 않아 에러 발생

여기서 두가지의 궁금점이 생겼다.

1) jar로 배포하는 것과 war로 배포하는 것의 차이

2) spring boot 의 내장 톰캣의 구동방식
- build 된 아카이프 파일 내의 내장 톰캣을 위한  org/springbootframework/boot/loader 라이브러리가 포함된 경우와 미포함 된 경우의 작동의 차이


각각의 내용이 내용이 방대할 것으로 예상되어 

1) jar로 배포하는 것과 war로 배포하는 것의 차이 를 먼저 확인해 보았다.


서론이 길었으나, 주제는 

JAR vs WAR vs EAR

이다.

먼저 위키백과에 기재되어있는 용어 설명을 확인해보면 아래와 같다.

1. JAR  (Java Archive)

JAR는 여러개의 자바 클래스 파일과, 클래스들이 이용하는 관련 리소스 및 메타데이터를 하나의 파일로 모아서 자바 플랫폼에 응용 소프트웨어나 라이브러리를 배포하기 위한 소프트웨어 패키지 파일 포맷이다. by 위키백과

 

2. WAR (Web Archive)

WAR 파일은 소프트웨어 공학에서 자바서버 페이지, 자바 서블릿, 자바 클래스, XML, 파일, 태그 라이브러리, 정적 웹 페이지 및 웹 애플리케이션을 함께 이루는 기타 자원을 한데 모아 배포하는데 사용되는 JAR 파일이다. by 위키백과

 

3. EAR (Enterprise Archive)

EAR은 하나 이상의 모듈들은 하나의 아카이브로 묶어서 여러 모듈이 애플리케이션 서버에 동시에 일관성 있게 배치될 수 있도록 하기 위한 자바 EE에 쓰이는 파일 형식이다. by 위키백과

 

이 내용과 baeldung 의 비교자료를 기준으로 내가 이해한 대로 비교해 보았다.

JAR
- java 어플리케이션을 위한 기본적인 압축 파일
- classes, resources, meta 데이터
WAR
- java web 어플리케이션을 위한 압축 파일
- 라이브러리 형태의 jar, JSP, servlet, **static web 파일(**HTML, CSS, Javascript, 등)
EAR
- jar의 확장 형태로 여러개의 멀티 모듈로 구성된 enterprise 어플리케이션을 위한 압축 파일
- jar, war 포함

 

압축하는 모듈의 크기 비교

각각의 압축하는 범주를 기준으로 비교해보면 아래와 같다.

JAR < WAR < EAR

jar 가 가장 작은 application 단위의 압축 이고,

war는 좀더 확장된 web application 단위의 압축, (jar 포함)

ear는 여러개의 모듈이 합쳐진 jar에서 확장된, war의 기능까지 포함하는 단위의 압축이다. (jar, war 포함)

출처 : https://assignmentpoint.com/difference-jar-war-ear-files/

 

 

파일 내부 구성 비교

각각의 아카이브가 어떤 구조로 이루어지는지 비교해보면서 특징을 정리하면 아래와 같다.

JAR

META-INF/
    MANIFEST.MF
com/
    *.class

jre 만으로 구동 가능

 

WAR

META-INF/
    MANIFEST.MF
WEB-INF/
    web.xml
    jsp/
        *.jsp
    classes/
        static/
        templates/
        application.properties
    lib/
        // *.jar files as libs

WEB-INF/web.xml 이 반드시 있어야 함,
tomcat,jetty와 같은 was를 통해서만 구동 가능 

EAR

META-INF/application.xml
... 생략

META-INF/application.xml이 반드시 있어야 함
tomcat,jetty과 같은 standalone web container 방식의 was에서는 구동이 불가, windfly는 가능
--> standalone web container 방식이 무엇인가? 에 대하여는 추가 공부를 해보아야 겠다. (메모)

 

정리

 

최근 서비스 단위의 배포를 사용하는 추세이기 때문에, ear과 war보다는 jar 형태로 배포하는 것을 더 많이 사용한다고 한다.

따라서,
jenkins와 같은 CI/CD 툴 에서 jar 형태의 자동 배포를 지원하며,
maven, gradle 과 같은 build 툴에서 jar 형태로 build 할 수 있도록 제공하기 때문에
현재 프로젝트에서 구성한 war 대신 jenkins를 이용하여 spring 로컬에서 바로 jar 형태로 서비스 단위로 배포할 수 있도록 변경해 보면 좋을 것 같다.


전체적인 내용은 아래의 블로그와 bealdung 을 참고하였다.

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=ki630808&logNo=221726845624

https://www.baeldung.com/java-jar-war-packaging

https://www.baeldung.com/war-vs-ear-files