1JAR の中身を一覧する
コマンドで作った app.jar を、jar と の両方で開いたものです。入っているのは と だけで、unzip でそのまま読めます。は jar コマンドが自動で作り、入口の名が の行に書かれています。
$ jar tf dist/app.jarMETA-INF/META-INF/MANIFEST.MFapp/app/Main.classapp/Util.class$ unzip -l dist/app.jarLength Date Time Name--------- ---------- ----- ----0 2026-10-01 13:20 META-INF/88 2026-10-01 13:20 META-INF/MANIFEST.MF0 2026-10-01 13:20 app/532 2026-10-01 13:20 app/Main.class347 2026-10-01 13:20 app/Util.class--------- -------967 5 files$ unzip -p dist/app.jar META-INF/MANIFEST.MFManifest-Version: 1.0Created-By: 25.0.4.1 (Eclipse Adoptium)Main-Class: app.Main
2クラスパスに無い名前を頼むとどうなるか
クラスの名前を文字列で渡して読み込みを頼む を使った例です。にある Main は見つかり、どこにも無い greet.Greeter は になります。このページの実行環境では、クラスパスは . (カレントディレクトリ)だけです。
Java
3依存の JAR が足りないまま起動する
app.Main は別の に入っている greet.Greeter を使います。その JAR を渡さずに起動すると、Main started までは進み、Greeter を初めて使う8行目で になりました。 dist/greet.jar dist/app.jar のように -cp を足しても、同じエラーのままでした。
Main startedException in thread "main" java.lang.NoClassDefFoundError: greet/Greeterat app.Main.main(Main.java:8)Caused by: java.lang.ClassNotFoundException: greet.Greeterat java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:580)at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:490)... 1 more
package app;
import greet.Greeter;
public class Main {
public static void main(String[] args) {
System.out.println("Main started");
System.out.println(new Greeter().greet("jar")); // 8行目
}
}
4依存を渡して動かす3通り
同じアプリが動いた起動方法です。-cp に2つの JAR を並べて入口のクラスを名前で指定する方法、dist/* でディレクトリ内の JAR をまとめて指す方法、マニフェストに を書いて java -jar だけで起動する方法の3つです。3つ目は greet.jar が同じディレクトリにファイルとして在ることが条件でした。
$ java -cp dist/app.jar:dist/greet.jar app.MainMain startedHello, jar$ java -cp 'dist/*' app.MainMain startedHello, jar$ unzip -p dist/app-cp.jar META-INF/MANIFEST.MFManifest-Version: 1.0Class-Path: greet.jarCreated-By: 25.0.4.1 (Eclipse Adoptium)Main-Class: app.Main$ java -jar dist/app-cp.jarMain startedHello, jar
5JAR の中に JAR を入れると読まれない
依存の greet.jar を app-nested.jar の中の に入れて起動すると、依存が無いときと同じエラーになりました。後半は入れ子の場所を指す URL を 標準の に渡した結果で、中の JAR をバイト列として読むことはできても、クラスは見つかりません。外に書き出したコピーを渡すと読み込めました。
$ jar tf dist/app-nested.jarMETA-INF/META-INF/MANIFEST.MFapp/app/Main.classapp/Util.classlib/lib/greet.jar$ java -jar dist/alone/app-nested.jarMain startedException in thread "main" java.lang.NoClassDefFoundError: greet/Greeterat app.Main.main(Main.java:8)Caused by: java.lang.ClassNotFoundException: greet.Greeter...$ java -cp build Nestednested entry readable as bytes: 931file:/w/dist/alone/app-nested.jar -> java.lang.ClassNotFoundException: greet.Greeterjar:file:/w/dist/alone/app-nested.jar!/lib/greet.jar -> java.lang.ClassNotFoundException: greet.Greeterjar:file:/w/dist/alone/app-nested.jar!/lib/greet.jar!/ -> java.lang.ClassNotFoundException: greet.Greeterextracted copy -> class greet.Greeter