웹 애플리케이션을 배포할 때 우리는 흔히 JAR 또는 WAR 형식으로 빌드한다. 대부분은 Spring Boot 프로젝트를 jar
로 패키징해 배포하지만 일부 기업에서는 여전히 war
방식을 고수하기도 한다. 그래서 JAR와 WAR는 어떤 것이고 어떤 차이점이 있는지 작성했다.
JAR(Java ARchive)은 Java 클래스 파일, 라이브러리(JAR), 리소스 파일 등을 하나의 압축 파일로 묶은 형식이다. 내부적으로는 ZIP 포맷을 사용하며 .jar
확장자를 갖는다. Spring Boot에서는 내장 Tomcat을 포함시켜 JAR 자체로 웹 서버 역할까지 수행할 수 있다.
Spring Boot 기준으로 다음과 같이 JAR를 생성한다.
./gradlew bootJar
생성된 .jar
파일은 build/libs/
디렉토리에 위치하며 아래 명령어로 실행할 수 있다.
java -jar my-app.jar
.jar
파일을 빌드 후 SCP/SFTP로 서버에 전달 -> 실행 스크립트로 배포Dockerfile
내에서 java -jar
로 바로 실행되므로 컨테이너화에 매우 적합WAR(Web ARchive)는 웹 애플리케이션을 Java EE 표준 구조에 따라 압축한 파일로 JSP, Servlet, HTML, CSS, Javascript, 클래스, 라이브러리 등을 포함한다. .war
파일은 WAS(Web Application Server) 위에서 동작한다.
Spring Boot 기준으로 WAR 생성을 위해 build.gradle
에 아래 설정을 추가한다
// build.gradle
plugins {
id 'war'
}
bootWar {
enabled = true
}
bootJar {
enabled = false
}
이후 다음 명령어로 WAR 파일을 빌드한다.
./gradlew bootWar
생성된 WAR 파일은 build/libs/my-app.war
에 위치한다.
webapps/
폴더에 .war
파일을 복사http://host:8080/my-app
).war
파일을 scp
, rsync
, 또는 FTP
로 WAS 서버에 전달한 뒤 재시작항목 | JAR | WAR |
---|---|---|
실행 방식 | java -jar (내장 Tomcat) | WAS에 배포 |
배포 대상 | 독립 실행 (EC2, Docker, K8s) | Web Application Server (Tomcat 등) |
주요 환경 | 마이크로서비스, 클라우드 기반 환경 | 레거시 시스템, 금융/공공기관 |
장점 | 배포 단순, 독립적 실행, 빠름 | 기존 WAS 인프라 활용, 보안 정책 대응 |
단점 | WAS 기능 부족, 일부 보안 정책 미지원 | 설정 복잡, 유연성 낮음 |
대표 사례 | Spring Boot REST API, 마이크로서비스 | JSP 기반 웹서비스, 정부 시스템 |
JAR 방식이 더 간편해도 실제로 WAR로 배포하는 기업이 많은 이유는 다음과 같다.
즉, WAR는 배포 단순성보다는 인프라 운영 일관성과 장애 대응 전략에 무게를 두는 방식이다.
로드밸런싱 환경에서는 대부분 JAR 방식을 사용하는 것이 일반적이며 특히 클라우드 기반의 인프라나 마이크로서비스 구조에서는 사실상 표준처럼 자리 잡았다. 그 이유는 JAR 파일은 내장 Tomcat을 포함하고 있어 자체적으로 서버를 실행할 수 있기 때문에 각 인스턴스가 독립적으로 동작하며 무상태(stateless)로 서비스를 구성하기에 매우 적합하다. 이러한 무상태 구조는 로드밸런서가 유입되는 트래픽을 여러 인스턴스에 자유롭게 분산시키는 데 필수적인 요소이다.
예를 들어, AWS EC2나 ECS, Kubernetes 환경에서는 동일한 JAR 파일을 여러 컨테이너나 인스턴스에 배포한 후 ALB(Application Load Balancer)나 서비스 디스커버리를 통해 트래픽을 분산한다. 이때 각각의 JAR 인스턴스는 독립적으로 실행되며 톰캣이나 웹서버의 외부 설정에 의존하지 않기 때문에 신속한 확장(Scale-Out)과 장애 복구(Failover)가 가능하다.
반면, WAR 기반의 구조는 보통 하나의 중앙 Tomcat 또는 WebLogic 서버에 여러 WAR를 배포하는 방식이기 때문에 수평 확장에 적합하지 않다. WAS가 공유 자원(CPU, ThreadPool 등)을 여러 WAR가 함께 쓰는 구조이므로 확장성을 확보하기 위해서는 WAS 자체를 수동으로 늘려야 하며 각 WAR 간 간섭 가능성도 존재한다. 또한 WAR 방식은 일반적으로 세션 기반 처리를 많이 사용하기 때문에 세션 클러스터링이나 Sticky Session과 같은 설정 없이 단순 로드밸런싱을 적용하면 문제가 발생할 수 있다.
정리하면 수평 확장성과 무상태성을 요구하는 로드밸런싱 환경에서는 JAR 구조가 유리하며 클라우드 환경에서도 JAR는 경량화된 배포 단위로서 빠른 롤링 배포와 장애 복원력을 제공한다. WAR는 주로 기존에 WAS 중심의 인프라를 운영 중인 조직에서 내부의 시스템 통합이나 정책 때문에 여전히 사용되지만 신규 시스템이나 마이크로서비스 아키텍처에서는 JAR 방식을 채택하는 것이 일반적이다. 로드밸런싱이 적용된 구조에서는 결국 JAR 방식이 관리 효율성과 확장성 측면에서 훨씬 유리하다고 볼 수 있다.
운영 중 예상치 못한 장애가 발생했을 때 얼마나 빠르게 복구할 수 있느냐도 시스템 선택의 중요한 기준이 된다. 이 점에서 보면 WAR 구조는 클래스 단위로 빠르게 핫픽스할 수 있어 유리한 측면이 있다.
WAR 방식은 외부 WAS 위에 배포되므로 애플리케이션 전체를 재배포하지 않고도 특정 .class
파일만 직접 수정하여 context reload
를 통해 빠르게 반영할 수 있다. 즉, 단일 클래스 로직의 버그라면 빌드 없이 빠른 긴급 패치가 가능하다는 점이 특징이다. 실제로 많은 레거시 시스템에서는 이런 방식으로 장애 복구를 처리해왔고 운영자의 숙련도에 따라 매우 빠른 대응이 가능하다.
반면 JAR 구조는 모든 클래스와 리소스가 하나의 압축 파일로 묶여 있기 때문에 작은 수정이라도 전체 JAR 파일을 다시 빌드해야 하고 이로 인해 복구 속도는 느릴 수 있다. 특히 배포 자동화가 미흡하거나 운영 환경에 제약이 있을 경우 전체 재배포가 부담이 될 수 있다. 하지만 JAR 방식은 클라우드 환경에서의 무상태 서비스와 자동화된 배포 시스템(CI/CD)을 전제로 설계되는 만큼 장애 발생 시 자동 롤백, 빠른 재배포 등으로 복구 자체는 일관되고 안정적으로 수행할 수 있다.
즉, WAR는 수동 대응이 빠르고 클래스 단위로 유연하게 처리할 수 있지만 일관된 릴리즈 및 버전 관리에는 취약하다. JAR는 배포 단위가 크고 변경이 어렵지만 자동화와 안정성 면에서는 훨씬 우수하다. 따라서 JAR 방식의 장애 복구는 ‘자동화 기반’이고 WAR 방식은 ‘운영자 중심의 수동 대응’이라고 요약할 수 있다.
결국 어떤 방식이 더 유연하다고 단정할 수는 없으며 장애 복구에 대한 조직의 대응 체계, 자동화 수준, 개발·운영 프로세스의 일관성이 함께 고려되어야 한다는 점을 확실히 느꼈다.
JAR과 WAR은 모두 Java 애플리케이션을 배포하기 위한 아카이브 형식이지만 실제 운영 환경에 따라 쓰임새가 완전히 달라진다. Spring Boot 등장 이후 대부분은 내장 톰캣 기반 JAR 구조로 전환되고 있지만, 여전히 금융기관이나 대기업, 공공 시스템에서는 WAR 기반의 외부 WAS 운영을 유지하는 경우가 많다. 특히 클라우드 기반의 로드밸런싱 환경에서는 JAR의 유연함과 단순함이 빛을 발하며 무상태 서비스 설계와도 잘 맞는다. 반면 WAR는 레거시 시스템과 연동이 필요하거나 운영 정책이 고정된 환경에서 여전히 유효한 선택이다. 두 방식 모두 상황에 따라 장단점이 뚜렷하므로 인프라 구조와 서비스 규모, 운영 정책을 고려해 합리적인 선택이 중요하다는 점을 다시금 느꼈다.