jarファイルとMANIFEST.MF

eclipseJavaの開発しているとボタンぽちぽちするだけで勝手にコンパイルして実行してくれたりするので、中で何が動いているのか全く分からない。しかし何故動いてるのか分からないまま使ってるのも非常に気持ち悪い。
以前jar関係で少しハマったので少しだけjarファイルについて調べてみたので結果を残しておく。

jarとは何か

jarファイルとは、classファイルなどの必要なリソースをzip圧縮したものだ。これを配布してアプリケーションやライブラリとして使ってもらうことができる。
jarコマンドを使うと指定したファイルやフォルダをzip圧縮し、jarファイルを作成できる。以下のようなTest.javaを作ってjarファイルを作ってみよう。

package test;

public class Test
{
    public void	hoge()
    {
        System.out.println("hoge");
    }
}

そして、以下のコマンドを実行する。testフォルダにTest.classを格納し、それをjarファイル化する。

$ javac Test.java
$ mkdir test
$ mv Test.class test
$ jar cvf test.jar test

jarの中身の情報を表すMANIFEST.MF

MANIFEST.MFというのはjarのバージョン情報やクラスパスの情報が格納されたファイルだ。jarコマンドで明示的にMANIFEST.MFを指定しなかった場合、自動的に追加される。unzipコマンドで解凍して確認してみよう。

$ unzip test.jar
Manifest-Version: 1.0
Created-By: 1.6.0_41 (Apple Inc.)

なお、jarコマンドでMANIFEST.MFを指定してアーカイブ化する場合、mオプションを使用する。

jar cvfm test.jar MANIFEST.MF Test.class

jar内のファイルの構造

jarファイル内部の構造もパッケージと同一にする必要がある。例えば、testパッケージに所属するTestというクラスがあった場合、/test/Test.classの構造をフォルダごとjarファイルに入れておく。おそらくこのjarの構造がそのままロードされる。

javaコマンド実行時のjarファイルのクラスパス指定方法

フォルダ配下がclassファイルであれば、クラスパスはフォルダを指定するだけで良い。testフォルダにTest.classが入っている場合は以下のコマンドで実行できる。

$ java -cp .:hoge Sample

しかしjarファイルを指定する場合は注意が必要だ。java6未満の場合はフォルダは指定出来ない為、"lib/test.jar"のように個別のjarを指定する。Java6以上であればワイルドカードが使える為、"lib/*"のように指定すれば良い。

$ java -cp .:lib/* Sample