JAR vs WAR
JAR와 WAR 비교하기
현재 회사에는 war를 사용하여 빌드를 하는데, 개인 프로젝트를 할 때는 jar를 썼다. 지금까지는 남들이 다 그렇게 하니까, 회사에서 쓰라니까 라는 이유로 무지성으로 썼는데, 문득 두 개의 차이가 궁금해졌다.
JAR
JAR (Java ARchive)는 .jar 확장자를 가진 패키지 형식으로, JAVA 애플리케이션을 배포하는 데 주로 사용된다. JAR 파일은 컴파일된 자바 클래스 파일 (.class) 뿐만 아니라, 애플리케이션 설정을 위한 .properties 파일, 이미지, 텍스트 등 다양한 리소스를 함께 포함한다. 또한, 메타데이터를 포함해 JAVA 프로그램이 원활하게 동작할 수 있게 필요한 모든 요소를 하나의 파일로 묶어주는 역할을 한다. spring boot로 빌드를 할 때 default인 패키지 파일 형식이기도 하며, Maven과 Gradle 모두 JAR로 패키징을 할 수 있다.
간단히 말해, JAR은 JAVA 애플리케이션이 동작할 수 있게 자바 프로젝트를 압축한 파일이다.
팀 프로젝트에서 Spring Boot와 Gradle을 사용해 프로젝트를 JAR 형태로 패키징한 적이 있다. 로컬에서 개발한 뒤 외부 접근이 가능한 서버로 옮길 대, JAR 파일은 하나의 단일 파일로 생성되기 때문에 scp 명령어로 간편하게 전송할 수 있었다. 또한 Spring Boot에는 내장 톰캣이 포함되어 있어 서버에 JAVA만 설치되어 있다면 바로 실행할 수 있었다. (이는 .class 파일을 실행하기 위해 JDK에 포함된 JRE (java runtime environment)가 필요하기 때문이다.) 당시 프론트엔드는 React로 구성되어 서버는 단순히 API만 제공했기 때문에, 별도의 웹 애플리케이션 배포가 필요한 WAR 방식 대신 JAR 패키징이 효율적이었다.
JAR 파일 구조
1
2
3
4
5
6
// 파일 구조 레이아웃
META-INF/
MANIFEST.MF
com/
baeldung/
MyApplication.class
- META-INF/ : 아카이브에 대한 메타데이터를 담고 있는 디렉토리
- MANIFEST.MF : 실행 클래스 정보나 버전, 의존성 등의 추가 정보 (==메타데이터)를 담은 파일
즉, MANIFEST.MF는 JAR 파일의 설명서 같은 역할을 한다. 이 중 MANIFEST.MF 파일에는 아래와 같은 속성이 존재한다.
1
2
Manifest-Version: 1.0
Main-Class: com.example.testApplication
여기서 Main-Class는 JAR 파일의 엔트리 포인트를 나타낸다.
예시
예를 들어, testApplication.java를 아래와 같이 구현했다고 가정하자.
1
2
3
4
5
6
7
package com.example;
public class testApplication {
public static void main(String[] args) {
System.out.println("JAR!");
}
}
이걸 JAR로 묶을 때 MANIFEST.MF에 Main-Class: com.example.testApplication과 같이 적혀있다면, 터미널에서 아래의 명령어를 사용해 jar를 실행할 수 있다.
1
java -jar testApplication.jar
자바가 testApplication.jar를 읽을 때 내부의 MANIFEST.MF를 보고 실행할 클래스를 확인한 후 찾아서 실행하는 것이다.
따라서 만약 Main-Class가 없다면, 자바는 어떤 클래스를 실행해야 하는 지 알 수 없기 때문에 오류가 발생한다. 이 경우에는 직접 클래스 이름을 지정해 실행해야 한다.
1
java -cp testApplication.jar com.example.testApplication
여기서 -cp는 클래스패스 (ClassPath)를 지정하는 옵션이다. 즉, 위 명령어는 이 JAR 안에서 com.example.testApplication 클래스를 실행하라는 의미다.
Spring Boot에서는 왜 대부분 JAR를 사용할까?
Springboot_initializr[https://start.spring.io/]에서 프로젝트를 생성하면 기본적으로 jar가 선택되어 있다. 이는 기존의 Spring MVC 프로젝트와 Spring boot의 차이 때문인데, Spring MVC는 개발자가 WAR 파일로 빌드하고 톰캣과 같은 외부 서버에 배포하여 실행하는 방식이었다면, Spring boot는 내장 톰캣을 포함시켜 실행하는 방식이기 때문이다.
| Spring MVC | Spring Boot |
|---|---|
| 개발자 -> war 파일로 빌드 -> 외부 서버에 배포 -> 서버 실행 | 애플리케이션 안에 내장 톰캣 포함 -> 빌드 파일 실행 |
| 서버 (tomcat)과 애플리케이션 (war)가 분리된 형태 | 하나의 JAR 파일이 애플리케이션과 서버의 역할을 모두 수행하는 구조 |
Spring Boot는 독립 실행형 애플리케이션을 지향해서 빌드 시 기본적으로 JAR 형태로 패키징된다. JAR를 사용하면 별도의 톰캣을 설치할 필요가 없고, 배포 및 실행이 간단하며 클라우드 혹은 Docker환경에 적합하기 때문이다.
템플릿 엔진을 쓸 경우
Spring boot의 템플릿 엔진인 Thymeleaf는 HTMl 렌더링을 도와주는 뷰 템플릿 엔진이라서 서버의 구동 방식과는 별개다. 즉, JAR실행 시에도 내장 톰캣이 돌아가기 때문에 Thymelaf 템플릿을 렌더링하는 데 아무 문제가 없다.
WAR
WAR는 web application archive 또는 web application resource의 약자로, .war 확장자를 가지는 웹 애플리케이션 패키징 형식이다.
주로 서블릿 (Servlet)이나 JSP 기반의 웹 애플리케이션을 톰캣 같은 웹 컨테이너 (Web Application Server)에 배포할 때 사용된다.
즉, WAR 파일은 웹 관련 자원을 모두 포함한 웹 전용 JAR로 볼 수 있다. HTML, 이미지, Java Script, Java Server Pages 파일 뿐 아니라 서블릿 클래스와 라이브러리까지 하나의 패키지로 묶어 웹 서버에 쉽게 배포할 수 있도록 만들어진 구조다.
현재 회사에서 사용하는 패키징 방식이다. Spring boot가 아닌 Spring 프레임워크를 사용하며, jsp로 프론트를 구성하고 외부 톰캣을 사용하기 때문인 것으로 추측한다. (전자정부프레임워크를 쓰는 곳은 대부분 WAR를 쓰는 것 같기도 하다.)
WAR 파일 구조
1
2
3
4
5
6
7
8
9
10
11
12
META-INF/
MANIFEST.MF
WEB-INF/
web.xml
jsp/
helloWorld.jsp
classes/
static/
templates/
application.properties
lib/
// *.jar files as libs
- META-INF/ : MANIFEST.MF 파일이 위치한 디렉토리로, 웹 아카이브에 대한 메타데이터를 포함한다. 이 디렉터리는 외부에서 직접 접근할 수 없도록 보호된 영역이다.
- WEB-INF/ : WAR 파일의 핵심 디렉터리다. 이 안에는 웹 애플리케이션 구동에 필요한 모든 리소스와 설정 파일이 담겨있다.
- web.xml : 웹 애플리케이션의 동작 방식을 정의한느 파일이다. 어떤 서블릿이 요청을 처리할지, 어떤 필터를 적용할지 등의 정보가 명시된다.
- classes/ : 애플리케이션의 .class 파일 (컴파일된 자바 코드)과 설정 파일 (application.properties)이 위치한다.
- lib/ : 애플리케이션에서 사용하는 라이브러리 (.jar 파일)이 포함된다.
- jsp/, templates/, static/ : jsp나 정적 자원 (HTML, CSS, JavaScript)이 포함된 폴더다.
서블릿이란, 동적 웹 페이지를 만들 때 사용하는 자바 기반의 웹 애플리케이션 프로그래밍 기술로, 웹 요청과 응답 흐름을 간단한 메서드 호출만으로 체계적으로 다룰 수 있게 한다. 간단히 말해, 자바를 이용해 웹 페이지를 동적으로 구성하는 서버측 프로그램이다. 자바로 구현된 CGI라고도 부른다.
CGI는 별도로 제작된 웹 서버와 프로그램 간의 교환 방식을 말한다. 어떤 특정한 도구를 의미하는 것은 아니고, 웹 브라우저용 출력 화면을 만드는 방법을 통틀어 말한다.
JAR vs WAR
JAR와 WAR는 모두 자바 애플리케이션을 패키징하기 위한 파일 형식이지만, 용도와 구조, 실행 바식에서 뚜렷한 차이를 가지고 있다.
간단히 말해, JAR는 자바 애플리케이션 전체를 하나로 묶은 실행 파일, WAR는 웹 애플리케이션 전체를 묶은 배포 파일이다.
주요 차이점
- 용도와 활용 범위
- JAR는 자바 애플리케이션 전체를 압축한 실행 파일로, 라이브러리, 플러그인 또는 독립 실행형 애플리케이션으로 활용할 수 있다.
- WAR는 웹 애플리케이션을 배포하기 위한 파일로, 서블릿/JSP 기반의 웹 서버 환경 (WAS) 에서만 사용된다.
- 디렉토리 구조
- JAR는 자유로운 구조로 아카이빙할 수 있다.
- WAR는 WEB-INF와 META-INF 디렉토리를 포함한 고정된 구조를 가진다.
- 실행 방식
- JAR는 별도의 서버 없이,
java -jar app.jar명령어만으로 실행할 수 있다. (Spring Boot의 내장 톰캣 덕분에 독립 실행 가능)- 만약 Spring MVC에서 jar를 사용하고자 한다면, 추가 설정을 해야 한다.
- WAR는 반드시 톰캣이나 제티 같은 웹 컨테이너 (WAS) 위에서만 실행된다.
- JAR는 별도의 서버 없이,
- 확장자와 파일 형태
- JAR는 .jar 확장자를 가진다.
- WAR는 .war 확장자를 가진다.
- 실행 환경
- JAR는 일반 자바 프로그램 실행용 포맷이다.
- WAR는 서블릿/JSP 컨테이너에서 동작할 수 있도록 설계된 웹 전용 구조다.
한 눈에 보는 비교표
| 구분 | JAR (Java ARchive) | WAR (Web Application ARchive) |
|---|---|---|
| 의미 | 자바 애플리케이션 전체를 묶은 실행 파일 | 웹 애플리케이션 전체를 묶은 배포 파일 |
| 용도 | 일반 애플리케이션, 라이브러리, 플러그인 등 | JSP/Servlet 기반 웹 애플리케이션 |
| 디렉터리 구조 | 자유로운 구조 | META-INF/, WEB-INF/ 등 고정 구조 |
| 실행 방식 | java -jar app.jar (내장 톰캣 가능) | 외부 톰캣(WAS)에 배포 필요 |
| 서버 필요 여부 | ❌ (JRE만 있으면 실행 가능) | ✅ (웹 서버/WAS 필요) |
| 확장자 | .jar | .war |
| 실행 환경 | JRE(Java Runtime Environment) | WAS(Web Application Server) |
| 대표 사용 예시 | Spring Boot, Gradle 기반 API 서버 | 전통적인 JSP/Servlet 웹 서비스 |