Spring Boot + Gradle 배포 파일 변경
jar에서 war로 패키징 방식 변경하기
Jar
- Java Archive
- class 파일과 메타 데이터, resources를 하나의 파일로 압축한 패키지 파일로, 배포와 전달이 용이하다.
- JSP나 서블릿 컨테이너에 대한 표준 기능을 활용하기 어려우며 동적 웹 컨텐츠 생성 및 관리가 제한적이기 때문에 웹 애플리케이션 개발을 할 때는 war 파일에 비해 제약 사항이 존재한다.
- 템플릿 엔진인 Thymeleaf 사용 시 JAR 패키징이 가능하다.
- Thymeleaf은 스프링 부트가 권장하는 서버 사이드 템플릿 엔진으로, 스프링 부트에서 자동 설정을 지원하기 때문에 웹 서버가 필요한 War가 없어도 브라우저에 직접 띄울 수 있다. 또한, Thymeleaf는 서블릿으로 변환되지 않아 비즈니스 로직이 분리된다.
- Thymeleaf은 JSP와 달리 순수 HTML 파일을 최대한 유지하기 때문에 웹에서 파일을 직접 열어도 내용 확인이 가능하다.
- 단점은 JSP보다 응답 속도가 느리다는 것이다.
- Spring의 경우, Thymeleaf에게 View의 역할을 맞기는 것을 추구한다.
- 확장자는 .jar이다.
War
- Web Archive
- 웹 구성 요소인 JSP, 서블릿 등과 웹 애플리케이션 실행을 위한 서블릿 컨테이너 (웹 컨테이너) 설정 파일, 라이브러리, 리소스 등을 포함해 한 번에 배포 및 실행이 가능하기 때문에 JAVA 웹 애플리케이션을 패키징하는 데 최적화 되어 있다.
- 웹 컨테이너나 서버에 종속적이기 때문에 특정한 웹 컨테이너 환경이 필요하며 배포 및 전달에 있어서 jar 파일에 비해 크기가 크고 번거로울 수 있다.
- 만약 View를 JSP로 구성한다면 WAR 패키징만 가능하다. 내장 톰캣을 사용하는 Spring Boot Application에서 JSP를 지원하지 않기 때문이다.
- 서버 사이드 템플릿 엔진인 JSP는 서블릿 형태로 변환되어 실행된다. 서블릿은 자바 소스로 이루어져 있어서 JSP에서 자바 코드를 사용할 수 있는데, 이렇게 되면 View에 비즈니스 로직이 포함되어 복잡하고 무겁다.
- JSP는 일반적인 Java MVC 구조에서 View 역할을 하며, HTML 코드와 JSP 코드가 함께 있기 때문에 서버를 통해 렌더링 되고, HTML 응답 결과를 받아야만 내용을 확인할 수 있다.
- 확장자는 .war이다.
JAR vs WAR
- JAR
- 독립적인 실행이 가능한 애플리케이션을 구성할 때 사용하는 것을 추천한다.
- 필자의 경우, 안드로이드와 협업을 할 때, 안드로이드에서 사용할 API를 개발하여 JAR 파일로 패키징을 했다.
- WAR
- 웹 환경에서 실행되는 애플리케이션을 구성할 때 사용하는 것을 추천한다.
- 필자의 경우, jsp 등을 활용하여 front를 구성하고 spring boot로 back을 구성할 때 사용했다.
변경 방법
build.gradle에 필요한 plugin, bootWar, dependencies를 추가한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
plugins { id 'java' id 'org.springframework.boot' version '3.2.6' id 'io.spring.dependency-management' version '1.1.5' id 'war' } ... bootWar { enabled = true } ... dependencies { ... implementation 'org.springframework.boot:spring-boot-starter-tomcat' ... }
MybatisApplication.java에 SpringBootServletInitializer를 상속 받아 오버라이딩 한다.
- SpringBootServletInitializer
- Sevlet이 업데이트 되면서 아파치 톰캣이 외부 톰캣에서 동작하도록 하기 위해 읽었던 web.xml을 WebApplicationInitializer 인터페이스로 대신하게 되었다.
- 이로 인해 web.xml이 없는 Spring Boot 웹 앱을 외부 톰캣에서 동작하려면 WebApplicationInitializer 인터페이스를 구현한 SpringBootServletInitializer 인터페이스를 상속 받아야 한다.
- 위의 이유로, war 파일로 배포를 진행하지 않는다면 상속 받을 필요가 없다.
1 2 3 4 5 6 7 8
@SpringBootApplication @MapperScan(basePackages = "com.example.mybatis", annotationClass = Repository.class) public class MybatisApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(MybatisApplication.class, args); } }
- SpringBootServletInitializer
Error
FAILURE: Build failed with an exception
jar를 war로 변경하는 과정에서 FAILURE: Build failed with an exception가 발생했을 경우, .gradle 경로를 지정하면 된다.
참고
사람냄새나는 개발일기 님 - SpringBootServletInitializer 란 무엇이고 왜 상속을 받고 있는가?
민뭉아치 님 - [Spring boot] 배포 패키징 jar 에서 war로 변경
잘못된 정보를 발견하시면 제보 부탁드립니다.
이 포스트는 저작권자의 CC BY 4.0 라이센스를 따릅니다.