むにえる牧場

毎日むにえるをつくっています

.jarファイルをdecompileして中身を見る

概要

業務中に hoge.jar という形でパッケージ化されたコードの中身が見たくてどうしようもない状況に陥ったのでやりました。
既に初期の開発メンバーがいなくてライブラリを把握してる人がいないとか、聞ける人がいないとか……
ポジティブに考えるならば、デバッグのためとか勉強目的として利用すると良いかもしれません。

jarファイルを解凍する

terminalにて unzip hoge.jar と打てばjarファイルの解凍が出来ます。
出力結果はこんな感じに

$ unzip hoge.jar
Archive: hoge.jar
inflating: META-INF/MANIFEST.MF
inflating: fuga.class
inflating: piyo.class
inflating: poyo.class
inflating: hage.class
...

classファイルをdecompileする

カレントディレクトリ直下にjarファイルを解凍した結果得られたclassファイルの大群がいます。
そのclassファイルをdecompileします。

decompileに使うコマンドはこちら

javap

参考
javap

javapコマンドは、1つ以上のクラス・ファイルを逆アセンブルします。出力は指定するオプションにより異なります。オプションを使用しない場合、javapコマンドは、そのパッケージ、渡されたクラスのprotectedおよびpublicのフィールドとメソッドを出力します。javapコマンドは、その出力をstdoutに表示します。

javap hoge.class

といった感じでclassファイルへのpathを渡せば標準出力でdecompile後のコードが出てきます。

複数の.classファイルを一括でdecompileする

今回は拡張子が .class になっているものだけ対象としたいので、 find コマンドを利用して一括でdecompileします。

find [ディレクトリ名] -name "*.class"

上記のコマンドで拡張子が .class になっているものが一覧で取れます。
この結果を javap コマンドに投げることで一括decompileします。

find [ディレクトリ名] -name "*.class" | xargs javap

xargs を利用して javap に投げ込んでいく形にしました。
結果こんな形の出力が得られます。

Compiled from "hoge.java"
public class hoge extends hogeBase {
public hoge();
public boolean isHoge();
}
Compiled from "fuga.java"
public class fuga extends fugaBase {
public fuga();
public boolean isFuga();
}
...

javap コマンドのみだと細かい命令文までは出力されないので、細かい部分まで見たい場合は -c コマンドをつけてください。
(invokeとかldcといったレベルで出てくるのでぱっと見では難しかったです……)

まとめ

unzipjavap を組み合わせることによって、 .jar ファイルをdecompileすることができました。
いざというときには便利です。
そもそも .jar ファイルの中を見なければいけない状況に陥りたくない。