Java アプリケーションを起動する java/javaw コマンドには、-jar というオプションがある。jar ファイルを指定するだけで起動できるという便利なオプションだが、クラスパスの柔軟な指定ができなくなる、という罠がある。
例えば
jar ファイルに
Manifest-Version: 1.0 Main-Class: my.app.Foo
というマニフェストを入れておけば、
java -jar foo.jar
とするだけで my.app.Foo クラス (の main メソッド) を起動することができる。Windows とかの環境で jar ファイルをダブルクリックするだけで起動できるのも、このオプションのおかげ。
ところが、
java -classpath bar.jar -jar foo.jar
のようにして別の jar ファイルを利用することは、できそうだけどできない。-classpath での指定は無視されてしまう。また、環境変数 CLASSPATH の指定も無視される。
なぜなら
そういう仕様だから、ということみたいで。JDK のドキュメンテーションを調べると、以下のような記述がある。
このオプションを使用すると、指定された JAR ファイルは、すべてのユーザクラスのソースになり、ほかのユーザクラスパス設定は無視されます。
java - Java アプリケーション起動コマンド
-jar オプションで指定された JAR アーカイブ。 他のすべての値を無効にする。このオプションを使用すると、すべてのユーザクラスは指定されたアーカイブから検索される
クラスの検索方法
ここでいう「指定されたアーカイブ」というのは、-jar で指定した jar ファイル自体 (と、その jar ファイル内のマニフェストの Class-Path で指定されている jar ファイル) を指す。他の jar ファイルを参照したければマニフェストで指定しろ、と。
うーん
なんでこういう仕様なんだろう……。
回避策については下記ページの「クラスパスの設定が必要なJARファイルの実行」で説明されているが、どれも当初の意図通りではない。
Sun の Bug Database にも改善要望が上がってるけど、放置状態だなぁ。
- Bug ID: 4459663 Using executable jars erases CLASSPATH
- http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4459663