인프런 김영한 강사님 강의를 듣고 정리한 내용입니다.
Web Application Archive
WAR는 WAS(Web Application Server)에 배포할 때 사용하는 압축 파일이다. WAS 위에서 동작하고, HTML과 같은 정적 리소스와 클래스 파일을 모두 포함한다. 그리고 JAR에 비해서 구조가 더 복잡하다.
jar -xvf 파일명.war
로 압축을 풀어서 구조를 확인할 수 있다.
라이브러리 모음에서 외부 라이브러리를 jar 형식으로 포함시킬 수 있다.
프로젝트 폴더에서
./gradlew clean build
명령어로 빌드한다.
프로젝트 폴더 경로/build/libs 하위에 .war 형식의 파일이 생성된다.
생성된 war 파일을 배포하려면 복사한 후,
톰캣 설치 경로/webapps 하위에 붙여넣는다.
그리고 파일명을 ROOT
로 변경한다. (ROOT.war 형식)
그리고 톰캣 서버를 실행하면, war 파일이 실행된다.
해결 방법
=> 톰캣을 내장시키자! 라이브러리처럼
라이브러리처럼 WAS를 내장시켜 사용하려면, WAR를 사용할 수 없다. 이후에 설명할 실행가능한 JAR
로 톰캣을 내장시켜서 사용할 수 있다.
Java Archive
압출 파일로, 여러 클래스 리소스의 묶음이다.
JAR 내부의 META-INF/MANIFEST.MF
파일에서 Main-Class에 실행할 main() 메서드의 클래스를 지정해줘야 한다. jar 파일의 실행 시에 지정해둔 클래스의 main() 메서드가 실행된다.
다음과 같이 Main-Class
에 클래스를 지정한다.
Main-Class: hello.embed.EmbedTomcatSpringMain
역시 jar -xvf 파일명.jar
로 압축을 풀어서 구조를 확인할 수 있다.
외부 라이브러리를 포함하지 않은 클래스 코드들만이 압축되어 저장된다.
프로젝트 폴더에서
./gradlew clean buildJar
명령어로 빌드한다.
{프로젝트 폴더 경로}/build/libs 하위에 .jar 형식의 파일이 생성된다.
외부 라이브러리를 사용하는 경우에는 IDE에서 jar 파일을 돌리는 게 아니고서야 파일 안에 라이브러리들을 포함시켜야만 한다.(빌드-배포의 경우)
하지만 자바 표준에서는 jar 파일 안에 다른 jar 파일들을 포함시키는 것이 불가능하다.
기존의 jar에서 외부 라이브러리 없이 실행이 불가능한 문제를 해결하고자 처음에 Fatjar를 사용했다.
Fatjar를 사용하면 외부 라이브러리의 jar 파일들을 모두 class로 풀어서 저장한다.
프로젝트 폴더에서
./gradlew clean buildFatJar
명령어로 빌드한다.
{프로젝트 폴더 경로}/build/libs 하위에 .jar 형식의 파일이 생성된다.
하지만 이 방법에도 여전히 문제가 있다.
Executable JAR는 실행가능한 jar 라는 의미이다. 자바 표준에서 정의된 것은 아니고, 에서 새롭게 정의한 것이다.
특징은 JAR 파일 내부에 다른 JAR 파일들을 포함시킬 수 있다는 것이다.
자바 표준에서 JAR 내부에 다른 JAR를 넣는 것은 불가능하지만, 실행가능한 jar는 다음과 같은 방식으로 이를 가능케 한다.
META-INF/MANIFEST.MF
파일에서 Main-Class에 실제 main()이 있는 클래스가 아니라 Jar Launcher가 지정된다.
Jar Launcher
에서는 JAR 안에 JAR를 넣고 읽을 수 있도록 하는 기능을 정의해두었다. 그래서 JAR 파일 실행 시에 먼저 Jar Launcher가 실행되어 내부에 JAR를 넣을 수 있도록 처리한 후, 실제 main()을 실행한다.
Main-Class
에는 Jar Launcher
지정,
Start-Class
에 main()이 있는 클래스
지정
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: hello.ExternalApplication
프로젝트 폴더에서
./gradlew clean buildFatJar
명령어로 빌드한다.
{프로젝트 폴더 경로}/build/libs 하위에 .jar 형식의 파일이 생성된다.
https://start.spring.io/ 에서 빠른 설정으로 프로젝트를 생성할 수 있다.
Spring Boot는 괄호가 붙지 않는 가장 최신 버전을 선택하고, 패키징을 Jar로 설정한다.
Dependencies에서 Spring Web
을 추가하면 내장 톰캣을 사용할 수 있다.
혹은 이미 만들어진 프로젝트에서 내장 톰캣을 사용하고 싶다면, build.gradle
에서 다음과 같이 설정한다.
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.3'
id 'io.spring.dependency-management' version '1.1.0'
}
group = 'hello'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
dependencies {
// 추가
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
내장 톰캣을 사용하기 위해서 dependencies에
implementation 'org.springframework.boot:spring-boot-starter-web'
를 추가하면 된다.
이제 WAS를 따로 설치할 필요없이 라이브러리처럼 내장 톰캣을 사용할 수 있게 되었다!
이는 모두 스프링 부트의 Executable Jar 덕분이다.