Java Tips/Jar
読み込みの実験
JAR ファイルを読み込み、 JAR ファイルの情報や、格納されているファイルの色々な情報を取得してみます。
JAR ファイルの読み込み
java.util.jar.JarInputStream クラスで任意の入力ストリームから JAR ファイルを読み込むことができます。コンストラクタは以下のようになります。
public JarInputStream(InputStream in) throws IOException
in 引数には FileInputStream インスタンスでも指定すればいいでしょう。従って、 JarInputStream インスタンスを生成するコードは以下のようになります。
JarInputStream in = new JarInputStream(new FileInputStream(filename));
マニフェストの読み込み
JarInputStream#getManifest() メソッドで、マニフェストを表す java.util.jar.Manifest クラスのインスタンスを取得することができます。この Manifest インスタンスからマニフェストの情報を色々と読み込むことができます。詳細は JavaDoc を参照してください。
エントリ、及びバイナリ データの読み込み
JarInputStream クラスは InputStream クラスを継承しているので read() メソッドでバイナリ データを読み込むことができますが、 JarInputStream#read() メソッドは現在のエントリのバイナリ データを読み込みます。なので、まずはエントリを読み込みます。
JarInputStream#getNextJarEntry() メソッドの呼び出しで、エントリを表す java.util.jar.JarEntry クラスのインスタンスを取得することができます。 null 参照が返ったら最後のエントリまで読み込まれたと言うことです。エントリを読み込むまでのコードを示します。
while (true) { // エントリを読み込みます。 JarEntry entry = in.getNextJarEntry(); if (entry == null) { break; } }
エントリの名前 (ファイル名) は JarEntry#getName() メソッドの呼び出しで取得することができます。エントリがディレクトリであるかどうかを判断するには JarEntry#isDirectory() メソッドを呼び出します。
String name = entry.getName(); boolean isDir = entry.isDirectory();
JarInputStream#getNextJarEntry() メソッドの呼び出しのあとで JarInputStream#read() メソッドを呼び出すと、そのエントリのバイナリ データを読み込むことができます。エントリのバイナリ データを読み込むまでのコードを示します。
// バイナリ データを読み込みます。 ByteArrayOutputStream out = new ByteArrayOutputStream(); while (true) { byte[] buffer = new byte[1024]; int len = in.read(buffer); if (len <= 0) { break; } out.write(buffer, 0, len); } byte[] entryData = out.toByteArray();
URLConnection.guessContentTypeFromStream() メソッドを呼び出すと、バイナリ データのコンテント タイプを取得することができます。 URLConnection.guessContentTypeFromStream() メソッドは入力ストリームを引数にとります。バイナリ データのコンテント タイプを取得するコードを示します。
InputStream in = new ByteArrayInputStream(entryData); String type = URLConnection.guessContentTypeFromStream(in); in.close();
.class ファイルは application/java-vm 、 application/x-java-vm というコンテント タイプのようです。
JAR ファイルに格納されている JAR ファイルの読み込み
JAR ファイルに格納されているエントリからバイナリ データを読み込む方法を示しました。ということは、 JAR ファイルに格納されている JAR ファイルを更に読み込むこともできるわけです。 JAR ファイルを表すエントリのバイナリ データを読み込んだら、それを ByteArrayInputStream クラスに渡して更に新しい JarInputStream クラスを生成すればいいのです。
JarInputStream in = new JarInputStream(new ByteArrayInputStream(entryData));
これで、例えば WAR ファイル中の /WEB-INF/lib ディレクトリに格納されている JAR ファイルを読み込むということもできます。
2005年12月07日(水) 11:53:05 Modified by uguuxp