Dev Study
← 解説「ソースから起動まで: 全体の流れ」に戻る

サンプルコードで身につける: ソースから起動まで: 全体の流れ

解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。

1NestJS との対応を1つずつ並べる

ビルドと起動に関わるものを、Java( 4.1.1)と NestJS で1項目ずつ並べた表です。名前が違うだけでほぼ対応するものと、対応しないものがあります。対応しないのは、コンパイラの出力がであること、依存の置き場所がプロジェクトの外であること、に依存を同梱することの3点です。

Java / Spring Boot と NestJS の対応(実測したプロジェクトの値)表
依存の宣言
Java : pom.xml(ビルドの手順の定義も兼ねる)
NestJS : package.json
 
依存の実体の置き場所
Java : プロジェクトの外。~/.m2/repository/ を全プロジェクトで共有
NestJS : プロジェクトの中。node_modules/
 
コンパイラ
Java : javac(Maven が呼ぶ)。出力はバイトコード(.class)
NestJS : tsc(nest build が呼ぶ)。出力は JavaScript のソース(.js)
 
コンパイル結果の置き場所
Java : target/classes/
NestJS : dist/
 
配る成果物
Java : target/demo-0.0.1-SNAPSHOT.jar 1個(依存の JAR 34本入り、約 19.9 MB)
NestJS : dist/(9ファイル 3,916 B)と node_modules(本番依存 98パッケージ)
 
起動
Java : java -jar demo-0.0.1-SNAPSHOT.jar
NestJS : node dist/main.js
 
ビルドツール自体の入手
Java : ./mvnw が Maven を取ってくる(Maven は JDK に入っていない)
NestJS : 対応するものは無い

2./mvnw package の1回で進む5つの段

ビルドのログから、段の見出しと主な行だけを抜いたものです。設定ファイルのコピー、 によるコンパイル、テスト、 作り、Spring Boot のによる作り替え、の順に進みます。Total time は依存のダウンロードを含む1回だけの値で、ビルドの速さの目安にはなりません。

$ ./mvnw -B -ntp package(空行・ダウンロードの行・テストの詳細を除いた抜粋)コマンド出力
[INFO] Building demo 0.0.1-SNAPSHOT
[INFO] --- resources:3.5.0:resources (default-resources) @ demo ---
[INFO] Copying 1 resource from src/main/resources to target/classes
[INFO] --- compiler:3.15.0:compile (default-compile) @ demo ---
[INFO] Compiling 2 source files with javac [debug parameters release 25] to target/classes
[INFO] --- resources:3.5.0:testResources (default-testResources) @ demo ---
[INFO] --- compiler:3.15.0:testCompile (default-testCompile) @ demo ---
[INFO] Compiling 1 source file with javac [debug parameters release 25] to target/test-classes
[INFO] --- surefire:3.5.6:test (default-test) @ demo ---
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] --- jar:3.5.1:jar (default-jar) @ demo ---
[INFO] Building jar: /w/target/demo-0.0.1-SNAPSHOT.jar
[INFO] --- spring-boot:4.1.1:repackage (repackage) @ demo ---
[INFO] Replacing main artifact /w/target/demo-0.0.1-SNAPSHOT.jar with repackaged archive, adding nested dependencies in BOOT-INF/.
[INFO] BUILD SUCCESS
[INFO] Total time: 15.508 s

3ビルドの後の target/ の中

ビルドが出力するものはすべて に入ります。NestJS の dist/ に当たる場所ですが、コンパイル結果の classes/ のほかに、テストの結果やの作業用ファイルも並びます。配る成果物は demo-0.0.1-SNAPSHOT.jar の1個で、 は依存を入れる前の JAR です。

target/ の tree(ビルド後)コマンド出力
target
├── classes
│ ├── application.properties
│ └── com
│ └── example
│ └── demo
│ ├── DemoApplication.class
│ └── HelloController.class
├── demo-0.0.1-SNAPSHOT.jar
├── demo-0.0.1-SNAPSHOT.jar.original
├── generated-sources
│ └── annotations
├── generated-test-sources
│ └── test-annotations
├── maven-archiver
│ └── pom.properties
├── maven-status
│ └── maven-compiler-plugin
│ ├── compile
│ │ └── default-compile
│ │ ├── createdFiles.lst
│ │ └── inputFiles.lst
│ └── testCompile
│ └── default-testCompile
│ ├── createdFiles.lst
│ └── inputFiles.lst
├── surefire-reports
│ ├── TEST-com.example.demo.DemoApplicationTests.xml
│ └── com.example.demo.DemoApplicationTests.txt
└── test-classes
└── com
└── example
└── demo
└── DemoApplicationTests.class
 
20 directories, 13 files

4java -jar で起動して curl で呼ぶ

成果物の JAR を に渡すと、ログに started on port 8080 と出て、HTTP を受け付け始めます。Tomcat を別に入れて起動しているのではなく、JAR の中に入っていたものが動いています。Started ... in 0.657 seconds は1回だけの値です。

$ java -jar target/demo-0.0.1-SNAPSHOT.jar と $ curl -i(ログの行は左を ... で省略)コマンド出力
$ java -jar target/demo-0.0.1-SNAPSHOT.jar
:: Spring Boot :: (v4.1.1)
... INFO 1 --- [demo] [main] com.example.demo.DemoApplication : Starting DemoApplication v0.0.1-SNAPSHOT using Java 25.0.4.1 with PID 1
... INFO 1 --- [demo] [main] o.s.boot.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
... INFO 1 --- [demo] [main] o.s.boot.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/'
... INFO 1 --- [demo] [main] com.example.demo.DemoApplication : Started DemoApplication in 0.657 seconds (process running for 0.891)
 
$ curl -i http://localhost:8080/hello
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 22
 
Hello from Spring Boot

5依存を入れる前と後の JAR を比べる

同じビルドでできた2つの JAR の中身です。.jar.original には自分の2個と設定だけが入っていて、3,176 B です。Spring Boot のプラグインが作り替えた JAR は、自分のクラスを に、 34本を に入れていて、約 19.9 MB になります。素の が作るのは前者の形で、依存は成果物に入りません。

$ jar tf(JAR の中のファイル一覧。# の行は補足)コマンド出力
# 依存を入れる前: demo-0.0.1-SNAPSHOT.jar.original(3,176 B)
$ jar tf target/demo-0.0.1-SNAPSHOT.jar.original
META-INF/
META-INF/MANIFEST.MF
com/
com/example/
com/example/demo/
META-INF/maven/
META-INF/maven/com.example/
META-INF/maven/com.example/demo/
com/example/demo/DemoApplication.class
com/example/demo/HelloController.class
application.properties
META-INF/maven/com.example/demo/pom.xml
META-INF/maven/com.example/demo/pom.properties
 
# 依存を入れた後: demo-0.0.1-SNAPSHOT.jar(BOOT-INF/lib/ の中身と起動用のローダのクラスは除いて表示)
$ jar tf target/demo-0.0.1-SNAPSHOT.jar | grep -v BOOT-INF/lib/. | grep -v org/springframework/boot/loader/.
META-INF/
META-INF/MANIFEST.MF
META-INF/services/
META-INF/services/java.nio.file.spi.FileSystemProvider
org/
org/springframework/
org/springframework/boot/
org/springframework/boot/loader/
BOOT-INF/
BOOT-INF/classes/
BOOT-INF/classes/com/
BOOT-INF/classes/com/example/
BOOT-INF/classes/com/example/demo/
META-INF/maven/
META-INF/maven/com.example/
META-INF/maven/com.example/demo/
BOOT-INF/classes/com/example/demo/DemoApplication.class
BOOT-INF/classes/com/example/demo/HelloController.class
BOOT-INF/classes/application.properties
META-INF/maven/com.example/demo/pom.xml
META-INF/maven/com.example/demo/pom.properties
BOOT-INF/lib/
BOOT-INF/classpath.idx
BOOT-INF/layers.idx
$ jar tf ... | grep -c BOOT-INF/lib/.*jar
34

図やコードに出てくる用語(タップで説明)