ソフトウェアエンジニアリングシンポジウム 2015
IPSJ/SIGSE Software Engineering Symposium (SES2015)

SOBA: Java バイトコード解析ツールキット
石尾 隆1,a)

秦野 智臣1,b)

井上 克郎1,c)

概要：Java を対象としたプログラム解析の研究では，制御フローグラフやそれに基づく依存関係，メソッドの呼出し関係がしばしば必要になる．本稿で紹介する SOBA (Simple Objects for Bytecode Analysis)
は，それらの情報に迅速にアクセスできるようにするクラスライブラリである．

1. はじめにAnalysis (VTA) [5] の実装を提供している．実装としては
ASM *1 のラッパーであり，論文執筆時点で JDK 1.8 まで

プログラム解析は，開発されたソフトウェア製品から有のバイトコードの解析が可能である．SOBA 自体のライセ

益な情報を抽出し，開発者に提供するための重要な基盤技

ンスとしては MIT ライセンスを採用し，ソースコードを術である．たとえば製品のソースコードから得られる行数

OSDN にて公開している *2 ．Soot と比べると実装されたや複雑度といった特徴量は品質管理の基本情報として知ら

解析アルゴリズムの数は少ないが，詳細な事前知識なしでれている．また，プログラム中での呼び出し関係やクラス利用できるものを提供している．の継承関係といった情報は，プログラムの構造を理解するために役立つ情報として，統合開発環境などを通じて開発

2. SOBA の設計方針とプログラム例者に提供されている．

SOBA は，コンパイルされた Java プログラムの解析をプログラム解析を実現する基本的な方法の 1 つは，コンJava で記述するためのツールキットである．プログラム

パイラと同様にソースコードを対象とした構文解析を実行に含まれるクラスやメソッドの一覧，メソッドの呼び出しし，抽出した構文木や記号表の情報を用いるというもので関係やクラス階層といった基本的な情報に，プログラム解ある．既存研究で開発されたツールとしては MASU [1] や析を初めて行う人でも手軽にアクセスできるようにするこUNICOEN [2] があり，いずれも複数のプログラミング言とを目的としている．

語の解析に対応するための工夫が凝らされている．

SOBA では，利用者の習得を容易にするという観点かプログラム解析のもう 1 つの方法が，コンパイルされたら，プログラムを「読み込む」指示を行うだけで，以下のバイナリの解析である．Java のバイナリ表現であるバイトような階層的なデータ構造を構築するようになっている．

コードの場合，ソースコードの行数のような情報は正確に• プログラム全体を表現する JavaProgram オブジェクトは得られないが，参照するクラスのパッケージ名やメソッ• プログラム中の各クラスを表現する ClassInfo オブドの引数の型情報など，ソースコードには直接出現しないコンパイラによって追加された情報を解析に利用できる．

ジェクト• クラス中の各メソッドを表現する MethodInfo オブ

このアプローチは Soot [3] などに採用されている．

ジェクト

SOBA は，我々の研究グループで開発した，Java のバイ利用者はプログラム例などを参考にして JavaProgram オ

トコードに対する基本的な解析機能を提供するツールキッブジェクトの作成さえできれば，そこから getClasses()，トである．メソッド内部の命令の実行順序を取得する制御

getMethods() といった get メソッドを呼び出していくだ

フロー解析，その情報を用いた制御依存関係解析とデータけで，クラス，メソッドの基本情報や，メソッドの制御フ

依存関係解析，クラス階層を使用して動的束縛を解決す

ローグラフなどの解析に必要なオブジェクトを取得するこる Class Hierarchy Analysis (CHA) [4] と Variable Typeとができる．

1a)b)c)

大阪大学
Osaka University, Suita, Osaka 565-0871, Japanishio@ist.osaka-u.ac.jp
t-hatano@ist.osaka-u.ac.jp
inoue@ist.osaka-u.ac.jp

c 2015 Information Processing Society of Japan⃝SOBA を使用したプログラムの一例として，Java プログラムからメソッド呼出し関係を抽出する方法を図 1 に示
*1*2

http://asm.ow2.org/
http://osdn.jp/projects/soba/210

ソフトウェアエンジニアリングシンポジウム 2015IPSJ/SIGSE Software Engineering Symposium (SES2015)
public static void main(String[] args) {// (1) 引数で指定されたディレクトリ/zip の内容を読み込む
JavaProgram program = new JavaProgram(ClasspathUtil.getClassList(args));

リ内部の呼び出し関係は出力しないといった特別扱いをしたい場合は，(1) の段階でライブラリであることを明示的に指定し，ClassInfo，MethodInfo クラスの isLibraryメソッドを使用してコードを記述することになる．

// (2) クラス階層情報を取得する
ClassHierarchy ch = program.getClassHierarchy();// (3) 全クラスの全メソッドの呼び出し命令を列挙する
for (ClassInfo c: program.getClasses()) {for (MethodInfo m: c.getMethods()) {System.out.println(m.toLongString());
for (CallSite cs: m.getCallSites()) {// (4) 動的束縛を解決し，結果を出力する
MethodInfo[] callees = ch.resolveCall(cs);if (callees.length > 0) {for (MethodInfo callee: callees) {System.out.println(" [inside] " +callee.toLongString());}} else {System.out.println(" [outside] " +cs.toString());} } } } }図 1 プログラム内部でメソッド呼び出し関係を列挙する例

動的束縛の解決に VTA [5] を使用する場合は Class-Hierarchy クラスを CallResolver クラスに入れ替えるだけでよい．このコード例と VTA の利用例は，いずれもSOBA のリポジトリに収録されている．
なお，バイトコード解析は，ソースコード解析に比べて高速な解析を実現しやすい．たとえば，Eclipse IDE for Java

Developers 4.4.1 と Oracle JDK 1.8.0 の合計 99,770 クラス，774,261 メソッドからすべてのメソッド呼び出し関係を抽出すると，その処理時間は Intel Xeon E5-2620 2.0GHzの 1 スレッドで約 42 分，1 メソッドあたりで 3.2 ミリ秒となる（ただし結果を文字列として書き出す時間を除く）．

3. 開発の状況
SOBA は，我々の既存研究（たとえば [6]）で使用しており，多くの解析の基盤となるような基本機能を備えていると考えているが，習得容易な API を目指すという点でます．このプログラムの先頭部分 (1) では，解析したい Javaだ発展途上にある．プログラム解析を必要とする研究者，のバイトコードが格納されたディレクトリや jar ファイル

技術者に利用していただき，フィードバックがいただけるがコマンドライン引数として指定されると想定して，そのと幸いである．

内容をもとに JavaProgram オブジェクトを作成している．
動的束縛の解決には Java のクラス階層情報が必要であ

謝辞 本研究は JSPS 科研費 No.26280021 の助成を受けたものです．

るが，これも JavaProgram オブジェクトから取得できる．
図 1 における (2) で取得している ClassHierarchy クラス

参考文献が，クラス階層と Java 言語仕様に従って呼び出しうるメ[1]

ソッドを列挙する CHA [4] の実装である．

Java プログラムからその内部のメソッド呼び出し関係を取得する場合，全クラスの全メソッドについて，すべて[2]のメソッド呼び出しを列挙し，その呼び出し先を（動的束縛を解決して）出力すればよい．プログラムを表現した階層的なオブジェクト構造を先に述べたような手順で訪問す[3]る処理が図 1 における (3) のループ構造である．
メソッドを表現する MethodInfo クラスには，内部で呼び出すメソッドの一覧や，制御フローグラフや制御依存関係，データ依存関係などを取得する様々な get メソッドが[4]用意されている．getCallSites はメソッド呼び出し命令の位置とその内容を取り出すメソッドであり，(4) の部分で動的束縛の解決を行って，実際の呼び出し先の情報を取得[5]し，文字列として書き出している．これは，リフレクションの利用による呼び出し関係を含まない，一般的なコールグラフの情報に対応する．
動的束縛の解決には，ライブラリを含むすべてのクラスの情報が必要である．ライブラリもバイナリの一種である
ため，解析時に引数としてライブラリのファイルも合わせて指定するだけで解析を実行することができる．ライブラc 2015 Information Processing Society of Japan⃝[6]

三宅達也，肥後芳樹，楠本真二，井上克郎：多言語対応メ
トリクス計測プラグイン開発基盤 MASU の開発，電子情報通信学会論文誌 D，Vol. J92-D, No. 9, pp. 1518–1531(2009).
坂 本 一 憲 ，大 橋 昭 ，太 田 大 地 ，鷲 崎 弘 宜 ，深 澤 良 彰：UNICOEN: 複数プログラミング言語対応のソースコード
処理フレームワーク，情報処理学会論文誌，Vol. 54, No. 2,pp. 1234–1249 (2013).
Vallée-Rai, R., Co, P., Gagnon, E., Hendren, L., Lam, P.
and Sundaresan, V.: Soot - a Java Bytecode Optimization
Framework, Proceedings of the 1999 Conference of theCentre for Advanced Studies on Collaborative Research,p. 13 (1999).
Dean, J., Grove, D. and Chambers, C.: Optimization of
Object-Oriented Programs Using Static Class Hierarchy
Analysis, Proceedings of the 9th European Conference on
Object-Oriented Programming, pp. 77–101 (1995).
Sundaresan, V., Hendren, L., Razafimahefa, C., ValléeRai, R., Lam, P., Gagnon, E. and Godin, C.: Practical
Virtual Method Call Resolution for Java, Proceedings ofthe 15th ACM SIGPLAN Conference on Object-Oriented
Programming, Systems, Languages, and Applications,pp. 264–280 (2000).
Hatano, T., Ishio, T., Okada, J., Sakata, Y. and Inoue,K.: Extraction of Conditional Statements for Understanding Business Rules, Proceedings of the 6th International
Workshop on Empirical Software Engineering in Practice, pp. 25–30 (2014).

211