Java:JarFileクラスの使い方

2019年8月17日

Jarファイルをオープンして調査するためにJarFileクラスを使ってみるのだが、意外にわかりにくいのでまとめてみる。

もちろん、JarFileはZipFileの派生クラスなのでマニフェストの調査以外の機能はZipFileと同一だ。

Manifestオブジェクトの取得

以下のようにオープンして、Manifestオブジェクトを取得する

File someJarFile = ....
try (JarFile file = new JarFile(someJarFile)) {
  Manifest man = file.getManifest();
  ....
}

マニフェストの構造

実際のマニフェストはJarファイル中で以下の場所にあり、

+ META-INF
|  +-- MANIFEST.MF
+ 他のエントリ

中身は以下のように、属性(Attribute)が並んでいる。これは、jaybird-jdk18-3.0.4.jarのものになる。

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.7
Created-By: 25.172-b11 (Oracle Corporation)
Specification-Title: JSR 221 JDBC API
Specification-Version: 4.2
Specification-Vendor: Oracle Corporation
Implementation-Title: Jaybird
Implementation-URL: https://www.firebirdsql.org
Implementation-Version: 3.0.4-JDK_1.8 (build: tag=v3.0.4 date=20180505
 1309)
Implementation-Vendor: Firebird project
Implementation-Vendor-Id: https://www.firebirdsql.org
Automatic-Module-Name: org.firebirdsql.jaybird

属性値の取得

これらの属性値一覧は「MainAttributes」というものになるらしい。

      Attributes attrs = man.getMainAttributes();
      attrs.entrySet().stream().forEach(System.out::println);    

で、以下が表示される。

Ant-Version=Apache Ant 1.9.7
Implementation-Title=Jaybird
Automatic-Module-Name=org.firebirdsql.jaybird
Implementation-Version=3.0.4-JDK_1.8 (build: tag=v3.0.4 date=201805051309)
Specification-Vendor=Oracle Corporation
Specification-Title=JSR 221 JDBC API
Implementation-Vendor-Id=https://www.firebirdsql.org
Created-By=25.172-b11 (Oracle Corporation)
Specification-Version=4.2
Implementation-URL=https://www.firebirdsql.org
Manifest-Version=1.0
Implementation-Vendor=Firebird project

特定の属性値を取得したい場合はgetValue()を使う。大文字小文字は無視されるらしい。

      System.out.println(attrs.get("Automatic-Module-Name")); --> null
      System.out.println(attrs.getValue("Automatic-Module-Name")); --> org.firebirdsql.jaybird
      System.out.println(attrs.getValue("automatic-module-name")); --> org.firebirdsql.jaybird

なぜか、Manifestオブジェクト自体にもgetAttributes()というメソッドがあるのだが、これを使うとnullが返される。
たしかにメソッドの説明書きには「MainAttributesを返すものではない」との説明があるのだが、しかし何に使うのか不明。

 man.getAttributes("Automatic-Module-Name") --> null

まとめ

Jarファイル中のマニフェストファイル(META-INF/MANIFEST.MF)中の属性を見たい場合は以下とする。

File someJarFile = ....
try (JarFile file = new JarFile(someJarFile)) {
  Manifest man = file.getManifest();      
  Attributes attrs = man.getMainAttributes();
  System.out.println(attrs.getValue("Automatic-Module-Name"));
}