← Spring コース
56. 実行可能 JAR の中身
4.1.1 の最小アプリで を実行すると、19,905,070 バイトの が1つできます。中身は、自分の(2つで計1,504バイト)、 34本、それを読むためのローダのクラス99個です。これが最終的なで、動かすには JAR の外に (Java の実行環境)が要ります。
「と JAR」の回のとおり、JAR の中の JAR を Java 標準のは読みません。そこで Boot は の を自前の にし、自分のクラス名は に書きます。 が最初に呼ぶのは のローダで、入れ子の JAR を読める形を整えてから自分の を呼びます。
NestJS の dist は9ファイルで計3,916バイトと小さく、依存は成果物の外の node_modules にあります。Rust は依存を結合した1つの実行ファイル(1,979,160バイト)でした。違いは何を成果物に入れたかです。なお、ここでのサイズと本数は webmvc だけの値で、Rust も libc などの共有ライブラリは外から借りています。
点線の付いた語はタップすると説明が出ます。用語集を開く →
java -jar demo-0.0.1-SNAPSHOT.jarJRE は JAR の外に要る
MANIFEST の Main-Class を呼ぶ
org/springframework/boot/loader/ローダのクラス 99個(JarLauncher など)
これだけは JAR の直下に展開して入っている入れ子の JAR を読めるクラスローダを用意する
BOOT-INF/lib/依存 JAR 34本(JAR のまま・無圧縮)
BOOT-INF/classes/自分のクラス2つと application.properties
MANIFEST の Start-Class を呼ぶ
DemoApplication.main自分のコード
- ・大きい順に tomcat-embed-core 3.6MB、spring-web 2.2MB、spring-core 2.0MB。自分の2クラスは計1,504バイトでした
- ・入れ子の JAR 34本はすべて無圧縮で入っています。リファレンスは、中身へ直接たどり着けるようにするためと説明しています
- ・Gradle の bootJar でも同じ構造でした(19,903,503 バイト)
サンプルコード(フレームワーク環境が必要なため表示のみ)
// このセクションを通して使う最小アプリ(Spring Boot 4.1.1 / JDK 25)。ソースはこの2ファイルだけ
// DemoApplication.java
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
// HelloController.java
@RestController
public class HelloController {
@GetMapping("/hello")
public Map<String, String> hello() {
return Map.of("message", "hello");
}
}
// $ ./mvnw package のあと、target/ にできたもの
// demo-0.0.1-SNAPSHOT.jar 19,905,070 バイト … 配る成果物
// demo-0.0.1-SNAPSHOT.jar.original 3,269 バイト … 包み直す前の、自分のクラスだけの JAR
//
// 成果物の MANIFEST.MF(抜粋)
// Main-Class: org.springframework.boot.loader.launch.JarLauncher ← java -jar が最初に呼ぶ
// Start-Class: com.example.demo.DemoApplication ← ローダがあとから呼ぶ
//
// 上の main は「最初に動くメソッド」ではなく、JarLauncher から呼ばれる側にいる
図やコードに出てくる用語(タップで説明)
サンプルコードで身につける(5本) →
学んだ概念を、素朴な例から実務寄りの例まで5つの具体例で確認します。
公式ドキュメントで詳しく ↗