Spring Boot 앱의 JAR 파일 구조

2025. 12. 30. 21:16Docker

🚀 Spring Boot 실행 JAR 파일 구조

Spring Boot 애플리케이션은 단순한 JAR가 아닙니다.
java -jar demo.jar 한 줄로 실행 가능한 이유는 Spring Boot만의 JAR 구조 설계 덕분입니다.

이번 글에서는 실행 가능한 Spring Boot JAR(Executable JAR) 내부 구조에 대해 알아 보겠습니다.
👉 디렉터리 단위로
👉 역할 중심으로
👉 실행 흐름과 연결해서

📦 전체 구조 한눈에 보기

 

Spring Boot 실행 JAR의 기본 구조는 아래와 같습니다.

demo.jar
 ├─ META-INF/
 ├─ org/springframework/boot/loader/
 ├─ BOOT-INF/
 └─ (기타 보조 파일)

👉 이 구조는 규약(Convention) 입니다.

 

🧾 1. META-INF/ — 실행 정보의 출발점

📄 MANIFEST.MF (가장 중요!)

META-INF/MANIFEST.MFJAR 실행의 진입점입니다.

Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.example.MyApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/

🔍 핵심 포인트

  • Main-Class
    • 실제 JVM이 실행하는 클래스
    • 👉 JarLauncher (Spring Boot 제공)
  • Start-Class
    • 여러분이 만든 @SpringBootApplication 클래스
  • ✅ Classes / Lib 위치 정보
    • Boot Loader가 어디를 classpath로 볼지 결정

📌 중요한 사실

Spring Boot 앱의 main()은 JVM이 직접 실행하지 않습니다.
👉 반드시 Boot Loader를 거쳐서 실행됩니다.

 

⚙️ 2. org/springframework/boot/loader/ — 실행 엔진

이 디렉터리는 Spring Boot의 심장입니다 ❤️

🔧 들어 있는 것들

  • JarLauncher, WarLauncher
  • LaunchedURLClassLoader
  • Archive, JarFileArchive

🧠 역할 요약

  • 📦 JAR 내부의 JAR(BOOT-INF/lib/*.jar)를 인식
  • 🧩 이를 가상의 classpath로 구성
  • 🚀 Start-Class를 로딩해 애플리케이션 실행

📌 즉,

“JAR 안에 또 다른 JAR를 넣고 실행한다”
이 마법은 전부 여기서 일어납니다.

 

🧠 3. BOOT-INF/ — 진짜 애플리케이션 영역

이제부터가 실제 여러분의 애플리케이션 영역입니다.

BOOT-INF/
 ├─ classes/
 └─ lib/

 

📂 3-1. BOOT-INF/classes/ — 애플리케이션 코드 & 리소스

여기는 target/classes의 최종 목적지입니다.

📌 포함되는 것들

 

  • ✅ 컴파일된 클래스
  • com/example/demo/DemoApplication.class
  • ✅ 설정 파일
  • application.yml 또는 application.properties
  • ✅ 웹 리소스
  • static/ templates/

🎯 정리하면

“내가 작성한 모든 코드와 리소스”가 이곳에 있습니다.

 

📦 3-2. BOOT-INF/lib/ — 의존성 라이브러리 저장소

여기는 Gradle / Maven 의존성 JAR 창고입니다 🏬

BOOT-INF/lib/
 ├─ spring-boot-3.x.x.jar
 ├─ spring-webmvc-6.x.x.jar
 ├─ jackson-databind-2.x.x.jar
 ├─ tomcat-embed-core-10.x.x.jar
 └─ ...

🔥 특징

  • ❌ 압축 해제되지 않음
  • JAR 그대로 포함
  • ⚙️ Boot Loader가 직접 읽어서 로딩

📌 일반 Java 앱과의 차이

일반 Java Spring Boot
외부 classpath 내부 JAR 포함
실행 환경 의존 단일 JAR 배포
설정 복잡 java -jar

 

🧩 4. 루트에 존재할 수 있는 보조 파일들

상황에 따라 다음 파일들이 추가될 수 있습니다.

🗂 classpath.idx

  • 클래스패스 로딩 속도 최적화용

🧱 layers.idx

  • Layered JAR 사용 시 생성
  • Docker 이미지 레이어 최적화와 직결

📌 Docker에서:

의존성 레이어 ↔ 앱 레이어 분리 가능
빌드 속도 & 캐시 효율 극대화

 

🔄 5. 실행 흐름으로 이해하는 전체 구조

java -jar demo.jar
      ↓
MANIFEST.MF → Main-Class
      ↓
JarLauncher 실행
      ↓
BOOT-INF/classes + BOOT-INF/lib 스캔
      ↓
Start-Class 로딩
      ↓
SpringApplication.run()
      ↓
Spring Context Bootstrapping

🎯 구조와 실행이 완벽히 연결됩니다.

 

❓ 6. 왜 클래스가 루트가 아니라 BOOT-INF/classes 인가?

아주 중요한 질문입니다 👍

🚫 일반 JAR의 한계

  • JVM은 JAR 루트만 classpath로 인식
  • JAR 안의 JAR은 인식 불가

✅ Spring Boot의 해결책

  • 📦 로더 코드 분리
  • 📂 앱 코드 / 라이브러리 분리
  • ⚙️ 커스텀 ClassLoader로 통합 실행
[Loader]   → org/springframework/boot/loader/
[App]      → BOOT-INF/classes/
[Lib]      → BOOT-INF/lib/

📌 이 3단 분리 구조가 Spring Boot의 핵심 설계입니다.

 

✨ 마무리 요약

✔ Spring Boot JAR는 단순한 압축 파일이 아니다
실행 로더 + 앱 코드 + 라이브러리가 명확히 분리된 구조
✔ 이 구조 덕분에:

  • 단일 JAR 배포
  • Docker 친화적
  • 실행 환경 독립성 확보

'Docker' 카테고리의 다른 글

Docker Network  (0) 2025.12.31
Union File System & Overlay File System  (0) 2025.12.31
overlay2  (1) 2025.12.30
도커 이미지 레이어는 diff만 저장한다.  (0) 2025.12.30
Docker Layer  (0) 2025.12.30