← 解説「JAR・WAR・マニフェスト・実行可能 JAR」に戻る
サンプルコードで身につける: JAR・WAR・マニフェスト・実行可能 JAR
解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。
1用語早見表: JAR・WAR とその中のフォルダ名
このレッスンの用語の早見表です。、、 はどれも zip 形式の入れ物で、違いは中の決まったフォルダと、何に渡して動かすかです。WAR と EAR は、アプリをサーバ製品に渡すための形で、Node には近いものがありません。
用語 | 一言で手元では: 何として見えるか近いもの: Node / NestJS で近いものJAR(Java Archive)| .class や設定ファイルをまとめた zip手元では: app.jar。jar tf で中を一覧できる近いもの: npm パッケージ(当たらない点は5本目)マニフェスト | JAR の中の説明書き手元では: META-INF/MANIFEST.MF の Main-Class の行近いもの: 無いMETA-INF | JAR の中の説明用のフォルダ手元では: jar tf の先頭に出る META-INF/近いもの: 無いWAR(Web ARchive)| Web アプリをサーバに渡すための形手元では: demo.war。Tomcat の webapps/ に置く近いもの: 無いWEB-INF | WAR の中の、外から直接は見えない部分手元では: WEB-INF/classes、WEB-INF/lib、WEB-INF/web.xml近いもの: 無い実行可能 JAR | 依存の JAR も入れ、java -jar だけで動く JAR手元では: Spring Boot が作る JAR近いもの: dist/ と node_modules を一緒に運ぶことfat JAR / uber JAR | 実行可能 JAR がこう呼ばれることがある手元では: Spring Boot のリファレンスにも出てくる語近いもの: dist/ と node_modules を一緒に運ぶことEAR(Enterprise ARchive)| 複数の WAR や JAR をまとめる形手元では: このコースでは名前だけ近いもの: 無い
2JAR の中を一覧し、マニフェストを読む
2つのを コマンドで JAR にまとめ、中を一覧した記録です。 は名どおりのフォルダに入り、jar コマンドが を足しています。の の行が の入口です。この JAR は 1,800 バイトでした。
$ jar --create --file app.jar --main-class com.example.app.Main -C out .$ jar tf app.jarMETA-INF/META-INF/MANIFEST.MFcom/com/example/com/example/app/com/example/app/Main.classcom/example/greet/com/example/greet/Greeter.class# 中の META-INF/MANIFEST.MF を取り出して表示したものManifest-Version: 1.0Created-By: 25.0.4.1 (Eclipse Adoptium)Main-Class: com.example.app.Main$ java -jar app.jarHello, world!
3WAR の中を一覧し、Tomcat に置く
HTTP に応答するクラス(。後のレッスンで扱います)を1つだけ入れた最小の WAR です。自分の .class は の下に入ります。この WAR は依存が無いので はありません。 の に置くと /demo/hello で応答し、 の中を直接取りに行くと 404 でした。
$ jar --list --file /work/out/demo.warMETA-INF/META-INF/MANIFEST.MFWEB-INF/WEB-INF/classes/WEB-INF/classes/hello/WEB-INF/classes/hello/HelloServlet.classWEB-INF/web.xml# demo.war を Tomcat の webapps/ に置いて起動した後$ curl -si http://localhost:18080/demo/helloHTTP/1.1 200Content-Type: text/plain;charset=UTF-8...hello from servlet...$ curl -si http://localhost:18080/demo/WEB-INF/web.xml | head -1HTTP/1.1 404
4Spring Boot の実行可能 JAR の中
4.1.1 の最小の Web アプリをビルドしてできた JAR の中です。自分の .class は に、 は に 34 本入っています。マニフェストの Main-Class は Spring Boot の起動用のクラスで、自分の を持つクラスは に書かれています。仕組みは後のレッスンで扱います。
META-INF/META-INF/MANIFEST.MF...org/springframework/boot/loader/BOOT-INF/BOOT-INF/classes/...BOOT-INF/classes/com/example/demo/DemoApplication.classBOOT-INF/classes/com/example/demo/HelloController.classBOOT-INF/classes/application.properties...BOOT-INF/lib/...# BOOT-INF/lib/ の下の JAR は 34 本# マニフェスト(META-INF/MANIFEST.MF)のうち2行Main-Class: org.springframework.boot.loader.launch.JarLauncherStart-Class: com.example.demo.DemoApplication
5たとえが当たらない点: 普通の JAR は依存を持たない
外部のライブラリ()を使うアプリを、jar コマンドで JAR にした記録です。JAR の中に依存は入らず、依存の一覧もありません。java -jar では、そのライブラリを使う行で失敗しました。なら中の package.json に依存が書いてありますが、JAR では依存の JAR の場所を自分でに書きます。 は、この手間を無くすための形です。
$ jar tf app.jarMETA-INF/META-INF/MANIFEST.MFcom/com/example/com/example/app/com/example/app/Main.classcom/example/greet/com/example/greet/Greeter.class$ java -jar app.jarException in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtilsat com.example.greet.Greeter.greet(Greeter.java:7)at com.example.app.Main.main(Main.java:7)Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang3.StringUtils...$ java -cp app.jar:lib/commons-lang3-3.21.0.jar com.example.app.MainHello, World!