🆚 WAR vs JAR

eGovFrame VSCode Initializr를 사용해보면 프로젝트 생성 단계에서 여러 템플릿을 선택할 수 있다. 그중 가장 먼저 눈에 들어오는 차이는 Web 템플릿Boot 템플릿이다.

Web 템플릿은 전통적인 WAR 방식으로 배포하는 프로젝트이고, Boot 템플릿은 Spring Boot 기반의 JAR 방식으로 실행하는 프로젝트다.

처음에는 단순히 .war, .jar 와 같이 확장자만 다른 줄 알았는데, 직접 생성하고 실행해보니 두 방식은 단순히 파일 확장자만 다른 것이 아니었다. 핵심 차이는 다음 질문으로 정리할 수 있다.

"애플리케이션을 누가 실행하는가?"
"외부 Tomcat이 실행하는가, 아니면 애플리케이션이 스스로 서버를 포함해서 실행하는가?"

 

🤔 WAR 방식이란?

WAR(Web Application Archive)는 Java 웹 애플리케이션을 배포하기 위해 필요한 파일들을 하나로 묶은 압축 파일이라고 생각하면 된다. WAR 파일 안에는 보통 다음과 같은 것들이 들어간다.

  • 컴파일된 Java 클래스
  • JSP 파일
  • CSS, JavaScript, 이미지 같은 정적 리소스
  • web.xml 같은 배포 설정 파일
  • 애플리케이션에서 사용하는 라이브러리 JAR 파일

 

하지만 여기서 반드시 알아야 할 부분은 WAR 파일은 일반적으로 혼자 실행되지 않는다는 점이다. WAR 파일은 Tomcat, Jetty, JBoss 같은 외부 WAS(Web Application Server) 또는 서블릿 컨테이너에 배포되어야 실행된다. 즉, WAR 방식에서는 애플리케이션이 직접 서버를 실행하는 것이 아니라, 예를 들어 Tomcat이 먼저 실행되고 그 위에 애플리케이션이 올라가는 구조라는 것이다.

 

흐름을 간단히 표현하면 다음과 같다.

  1. Tomcat 실행
  2. webapps 폴더에 WAR 배포
  3. Tomcat이 WAR 압축 해제
  4. web.xml 읽기
  5. DispatcherServlet 등록
  6. Spring MVC 애플리케이션 실행

비유하자면 Tomcat은 건물을 관리하는 운영 시설이고, WAR 파일은 그 건물 안에 입주하는 하나의 서비스 공간이라고 할 수 있다. 서비스 공간은 혼자 존재할 수는 있지만, 실제로 손님을 받으려면 건물의 전기, 수도, 출입구, 관리 시스템이 필요하다. WAR 방식에서 그 역할을 하는 것이 Tomcat 같은 WAS다.

 

🤔 JAR 방식이란?

JAR(Java Archive)는 Java 클래스와 리소스를 하나로 묶는 일반적인 Java 압축 파일 형식이다. 그런데 Spring Boot에서는 이 JAR 파일을 조금 특별하게 사용한다.

Spring Boot의 JAR는 단순한 라이브러리 묶음이 아니라, 실행 가능한 JAR(Executable JAR)이다. 즉, 다음 명령어 하나로 애플리케이션을 바로 실행할 수 있다는 말이다.

java -jar app.jar

 

이게 가능한 이유는 Spring Boot JAR 안에 애플리케이션 코드뿐만 아니라 내장 Tomcat도 함께 포함되기 때문이다. WAR 방식이 외부 Tomcat을 실행하고 그 위에서 WAR를 배포하면 애플리케이션이 실행되는 흐름이었다면, JAR 방식은 위의 명령어로 Spring Boot 애플리케이션을 시작하면 내장 Tomcat이 실행되고 애플리케이션이 실행되는 흐름인 것이다.

즉, JAR 방식에서는 실행의 주도권이 외부 Tomcat이 아니라 애플리케이션 자신에게 있다는 말이다. 이해를 위해 비유를 하자면 WAR 방식은 “건물에 입주하는 가게” 이고, JAR 방식은 “푸드트럭” 에 가깝다. 푸드트럭은 주방, 전기, 판매 공간을 어느 정도 스스로 갖고 있기 때문에 특정 건물에 입주하지 않아도 바로 영업할 수 있다. 이 구조는 클라우드, Docker, Kubernetes 같은 환경과 잘 어울린다. 서버에 별도로 Tomcat을 설치하고 설정할 필요 없이, JAR 파일 하나와 Java 실행 환경만 있으면 애플리케이션을 실행할 수 있기 때문이다.

 

🗂️ eGovFrame Initializr에서의 Web 템플릿과 Boot 템플릿

eGovFrame VSCode Initializr에서 직접 생성해본 프로젝트는 크게 두 가지였다.

🏹 Web 템플릿

Web 템플릿은 전통적인 Java 웹 애플리케이션 방식이다. 빌드 결과물이 .war 파일로 만들어지고, 이 파일을 외부 Tomcat 같은 WAS에 배포해서 실행한다.

Web 템플릿은 다음과 같은 특징을 가진다.

  • 외부 Tomcat에 배포한다.
  • src/main/webapp 폴더가 중요하다.
  • WEB-INF/web.xml이 존재한다.
  • dispatcher-servlet.xml 같은 Spring MVC XML 설정이 있다.
  • 화면은 JSP 기반이다.
  • Maven으로 빌드하면 WAR 파일이 생성된다.

 

✨ Boot 템플릿

Boot 템플릿은 Spring Boot 기반 프로젝트다. 빌드 결과물이 .jar 파일로 만들어지고, 애플리케이션 내부에 내장 Tomcat이 포함되어 있어 java -jar 명령어만으로 실행할 수 있다.

Boot 템플릿은 다음과 같은 특징을 가진다.

  • 외부 Tomcat에 배포하지 않아도 된다.
  • 애플리케이션 내부에 내장 Tomcat이 포함된다.
  • main() 메서드가 애플리케이션의 시작점이다.
  • web.xml이 없다.
  • XML 설정보다 Java Config와 application.properties 중심이다.
  • 화면은 Thymeleaf 기반이다.
  • Maven 또는 Gradle로 빌드하면 실행 가능한 JAR 파일이 생성된다.

 

🔍 eGovFrame Web 템플릿 구조

eGovFrame VSCode Initializr에서 Web 템플릿을 선택해 프로젝트를 생성하면 대략 다음과 같은 구조가 만들어진다.

egov-web/
├── pom.xml
├── src/main/
│   ├── java/egovframework/example/
│   │   ├── cmmn/
│   │   └── sample/
│   │       ├── service/
│   │       │   ├── EgovSampleService.java
│   │       │   ├── SampleVO.java
│   │       │   ├── SampleDefaultVO.java
│   │       │   └── impl/
│   │       │       ├── EgovSampleServiceImpl.java
│   │       │       └── SampleMapper.java
│   │       └── web/
│   │           └── EgovSampleController.java
│   │
│   ├── resources/
│   │   └── egovframework/
│   │       ├── spring/
│   │       │   ├── context-common.xml
│   │       │   ├── context-datasource.xml
│   │       │   ├── context-mapper.xml
│   │       │   ├── context-transaction.xml
│   │       │   └── context-properties.xml
│   │       └── sqlmap/example/
│   │           └── mappers/
│   │               └── EgovSample_Sample_SQL.xml
│   │
│   └── webapp/
│       ├── WEB-INF/
│       │   ├── web.xml
│       │   ├── config/egovframework/springmvc/
│       │   │   └── dispatcher-servlet.xml
│       │   └── jsp/egovframework/example/sample/
│       │       ├── egovSampleList.jsp
│       │       └── egovSampleRegister.jsp
│       ├── index.jsp
│       ├── css/
│       ├── js/
│       ├── fonts/
│       └── img/
└── target/

처음 보면 파일이 많아서 복잡해 보이지만 역할별로 나누면 꽤 명확하다.

 

🔀 Web 템플릿의 요청 처리 흐름

Web 템플릿에서 사용자가 브라우저로 접근하면 요청은 다음 흐름으로 처리된다.

  1. 사용자가 브라우저에서 URL 요청
  2. Tomcat이 요청 수신
  3. web.xml의 설정에 따라 DispatcherServlet으로 요청 전달
  4. DispatcherServlet이 Controller 탐색
  5. EgovSampleController 실행
  6. EgovSampleService 호출
  7. EgovSampleServiceImpl 실행
  8. SampleMapper 호출
  9. MyBatis가 EgovSample_Sample_SQL.xml의 SQL 실행
  10. HSQLDB에서 데이터 조회
  11. 결과를 Model에 담아 JSP로 전달
  12. JSP가 HTML을 렌더링
  13. 브라우저에 응답

 

이 흐름에서 중요한 점은 Tomcat이 먼저 요청을 받고, 애플리케이션은 Tomcat 내부에서 실행된다는 것이다.

 

🔨 Web 템플릿 빌드와 배포

WAR 방식 프로젝트는 Maven으로 빌드할 수 있다. 프로젝트 루트에서 다음 명령어를 실행한다.

mvn clean package

여기서 clean은 이전 빌드 결과물인 target 폴더를 정리하는 단계이고, package는 프로젝트를 컴파일하고 배포 가능한 파일로 묶는 단계다.

 

빌드가 성공하면 target 폴더 아래에 다음과 같은 WAR 파일이 생성된다.

target/egovweb-1.0.0.war

이 파일이 바로 Tomcat에 배포할 수 있는 결과물이다.

 

Tomcat이 실행 중이라면, 생성된 WAR 파일을 Tomcat의 webapps 폴더에 복사한다.

Tomcat은 webapps 폴더에 들어온 WAR 파일을 감지하고 자동으로 압축을 해제한다. 그리고 WAR 파일 이름을 기준으로 컨텍스트 경로를 만든다.

예를 들어 파일 이름이 egovweb-1.0.0.war이라면 http://localhost:8080/egovweb-1.0.0/ 경로로 접속해야 한다.

여기서 egovweb-1.0.0 부분을 컨텍스트 패스(Context Path)라고 한다. 만약 운영 환경에서 / 경로로 바로 접근하고 싶다면 WAR 파일 이름을 ROOT.war로 변경하거나 Tomcat 설정을 수정할 수 있다.

 

🔍 eGovFrame Boot 템플릿 구조

Boot 템플릿은 Spring Boot 기반 프로젝트다. 가장 큰 차이는 외부 Tomcat에 배포하지 않아도 된다는 점이다.

Boot 템플릿을 생성하면 대략 다음과 같은 구조를 볼 수 있다.

boot-web/
├── pom.xml
├── src/main/
│   ├── java/egovframework/example/
│   │   ├── EgovBootApplication.java
│   │   ├── config/
│   │   │   ├── EgovConfigDatasource.java
│   │   │   ├── EgovConfigMapper.java
│   │   │   ├── EgovConfigTransaction.java
│   │   │   └── EgovConfigWeb.java
│   │   └── sample/
│   │       ├── service/
│   │       └── web/
│   │
│   └── resources/
│       ├── application.properties
│       ├── static/
│       │   ├── css/
│       │   ├── js/
│       │   ├── fonts/
│       │   └── img/
│       └── templates/
│           └── egovframework/example/sample/
│               ├── egovSampleList.html
│               └── egovSampleRegister.html
└── target/

 

Web 템플릿과 비교해보면 몇 가지 차이가 바로 보인다.

  1. src/main/webapp이 중심이 아니다.
  2. 정적 리소스는 src/main/resources/static에 있다.
  3. 동적 화면 템플릿은 src/main/resources/templates에 있다.
  4. web.xml이 없다.
  5. XML 설정보다 Java Config가 많다.
  6. JSP 대신 Thymeleaf를 사용한다.

즉, Web 템플릿이 XML 설정 중심이라면, Boot 템플릿은 Java 클래스와 application.properties 중심이다.

 

❓ EgovBootApplication.java의 의미

Boot 템플릿에서 가장 중요한 파일은 EgovBootApplication.java다.

@SpringBootApplication
public class EgovBootApplication {

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

이 파일은 애플리케이션의 시작점이다.

WAR 방식에서는 Tomcat이 먼저 실행되고, Tomcat이 web.xml을 읽어 애플리케이션을 로딩했다. 하지만 Boot 방식에서는 main() 메서드가 직접 실행된다.

그리고 SpringApplication.run()이 Spring 컨텍스트를 만들고 내장 Tomcat을 실행한다.

즉, 실행 주도권이 외부 Tomcat에서 애플리케이션 내부로 이동한다. 이 차이가 WAR와 JAR 방식의 가장 핵심적인 차이다.

 

🔀 Boot 템플릿의 요청 처리 흐름

Boot 템플릿에서는 외부 Tomcat이 먼저 요청을 받지 않는다. 애플리케이션 내부에서 내장 Tomcat이 실행되고, 그 내장 Tomcat이 요청을 처리한다.

흐름을 그림처럼 표현하면 다음과 같다.

[사용자 브라우저]
      ↓
[Spring Boot JAR 실행 프로세스]
      ↓
[내장 Tomcat]
     ↓
[DispatcherServlet]
      ↓
[Controller]
    ↓
[Service]
    ↓
[Mapper]
    ↓
[Database]
     ↓
[Thymeleaf View]
       ↓
[사용자 브라우저]

WAR 방식과 비교하면 외부 Tomcat이 Spring Boot JAR 실행 프로세스 내부의 내장 Tomcat으로 바뀐 것이라고 생각하면 된다.

 

▶️ Boot 템플릿 실행하기

앞서 말했다시피 Boot 템플릿은 외부 Tomcat에 배포할 필요가 없다. 개발 중에는 다음 명령어로 실행할 수 있다.

mvn spring-boot:run

또는 Gradle 프로젝트라면 다음 명령어를 사용할 수 있다.

./gradlew bootRun

 

빌드 후 실행하려면 다음 흐름을 사용한다.

mvn clean package
java -jar target/boot-web-1.0.0.jar

이 방식은 배포가 단순하다. 서버에 JAR 파일 하나를 올리고 그냥 java -jar로 실행하면 된다. 외부 Tomcat을 따로 설치하고 WAR를 복사하는 등과 같은 복잡한 과정이 필요 없다.

 

💥 WAR 방식과 JAR 방식의 핵심 차이

WAR 방식과 JAR 방식의 차이는 단순히 확장자가 다르다는 정도로 이해하면 부족하다.

가장 중요한 차이는 실행 주체인데, WAR 방식은 외부 Tomcat이 애플리케이션을 실행하고, JAR 방식은 애플리케이션이 내장 Tomcat을 포함하고 직접 실행된다는 점을 반드시 기억하자.

비교 항목WAR 방식JAR 방식
파일 의미Web Application ArchiveJava Archive
주로 사용되는 형태전통적인 Java 웹 애플리케이션Spring Boot 실행 애플리케이션
실행 주체외부 Tomcat/WAS애플리케이션 자체
서버 포함 여부포함하지 않음내장 Tomcat 포함
실행 명령Tomcat에 배포 후 실행java -jar app.jar
배포 방식WAR 파일을 webapps에 복사JAR 파일을 서버에서 직접 실행
설정 중심web.xml, XML 설정application.properties, Java Config
화면 기술 예시JSPThymeleaf
환경 의존성외부 WAS 설정에 영향 받음애플리케이션이 실행 환경을 많이 포함
운영 방식하나의 WAS에 여러 WAR 배포 가능하나의 프로세스가 하나의 앱을 실행하는 구조에 적합
어울리는 환경전통적인 공공/기업 WAS 운영 환경클라우드, 컨테이너, MSA, CI/CD 환경

 

👍 WAR 방식이 어울리는 경우

WAR 방식은 다음과 같은 상황에서 자연스럽다.

  • 이미 조직에서 표준 Tomcat/WAS를 운영하고 있는 경우
  • 여러 웹 애플리케이션을 하나의 WAS에서 함께 관리하는 경우
  • 기존 공공 SI 또는 레거시 Spring MVC 구조를 유지해야 하는 경우
  • web.xml, JSP, 외부 WAS 배포 방식에 익숙한 조직인 경우

 

👍 JAR 방식이 어울리는 경우

JAR 방식은 다음과 같은 상황에서 유리하다.

  • 애플리케이션을 독립 실행하고 싶은 경우
  • Docker 컨테이너로 배포하고 싶은 경우
  • 서버마다 Tomcat을 따로 설치하고 관리하고 싶지 않은 경우
  • CI/CD 파이프라인에서 빌드 산출물을 단순하게 관리하고 싶은 경우
  • Spring Boot 자동 설정과 내장 서버 구조를 적극 활용하고 싶은 경우

 

🎏 JSP와 Thymeleaf의 차이(참고)

Web 템플릿과 Boot 템플릿은 화면 기술에서도 차이가 있다. Web 템플릿은 JSP를 사용하고, Boot 템플릿은 Thymeleaf를 사용한다.

  1. JSP: 오래된 Java 웹 화면 기술이다. JSP 파일은 바로 HTML로 실행되는 것이 아니라, Tomcat 내부에서 Java Servlet 코드로 변환되고 컴파일된 뒤 실행된다. JSP는 전통적인 Java 웹 프로젝트에서 많이 사용되었고, JSTL 같은 태그 라이브러리를 통해 반복문, 조건문, 메시지 출력 등을 처리할 수 있다. 하지만 HTML 안에 서버 전용 문법이 많이 들어가면 프론트엔드 개발자가 단독으로 화면을 확인하기 어려울 수 있다.

 

  1. Thymeleaf: Spring Boot에서 많이 사용하는 서버 사이드 템플릿 엔진이다. 가장 큰 특징은 HTML 파일 자체가 자연스럽게 유지된다는 점이다. 예를 들어 <td th:text="${sample.name}">샘플 이름</td>와 같이 작성할 수 있다. 브라우저는 th:text라는 속성을 몰라도 무시하고, 안에 있는 “샘플 이름” 텍스트를 보여준다. 반면 Spring Boot가 실행될 때는 Thymeleaf가 th:text를 해석해서 실제 데이터로 치환한다. 이런 방식을 Natural Template이라고 한다. 덕분에 Thymeleaf는 서버를 실행하지 않아도 HTML 구조를 어느 정도 확인할 수 있고, 디자이너나 프론트엔드 담당자와 협업하기 편하다.

0개의 댓글