top / index / prev / next / target / source
日記形式でつづる いがぴょんコラム ウェブページです。
Apache Jakarta BCELに引き続き、こんどは Javassistを体験しました。
blanco Frameworkのサブプロジェクトである JUnit用テストケース・ソースコードからドキュメントを自動生成するツールの名称について、「blancoJUnit2Doc」で良いかどうかを検討中です。
私にネーミングのセンスが無いことが、あらためて実感される今日この頃です。
2006.01.14追記 結局 プロジェクト名は blancoJUnit に落ち着きました。
関連する日記
Apache Jakarta BCEL以外のツールを用いたバイトコード解析についても少し調べてみました。バイトコード解析ということで DI/AOPツールをまずざっくりと見させていただきました。
Seasar2はJavassistを用いている模様です。
Spring Frameworkは 雰囲気的には CGLIBを用いている模様でした。(ウラを取っていません)
Seasar2が採用していることもあり、Javassistを ざっくり見させていただきました。
ライセンスはMozilla Public License 1.1
JBoss Sponsored Open Source Projectsに含まるという位置づけである模様。(JBossプロジェクトサイトからダウンロードしました)
また、はぶさんの日記経由で Javassistチュートリアルに到達しました。勉強になります。
先日に引き続き、こんどは Javassist を用いたクラスファイル(バイトコード)の解析を体験しました。
Javassist-3.1 RC2をもちいて確認しました。 JavassistSample.java
``` /**
import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.FileInputStream; import java.io.IOException; import java.util.List;
import javassist.bytecode.BadBytecode; import javassist.bytecode.ClassFile; import javassist.bytecode.CodeAttribute; import javassist.bytecode.CodeIterator; import javassist.bytecode.MethodInfo; import javassist.bytecode.Opcode;
/** * Javassistを用いたクラスファイル(バイトコード)解析サンプル * * @author IGA Tosiki / public class JavassistSample { /* * 解析を行いたいクラスファイル名を指定します。 */ private static final String CLASS_MODULE = "./bin/JavassistSample.class";
public static void main(String[] args) {
try {
new JavassistSample().process();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void process() throws IOException, BadBytecode {
final BufferedInputStream fin = new BufferedInputStream(
new FileInputStream(CLASS_MODULE));
try {
final ClassFile cf = new ClassFile(new DataInputStream(fin));
final List listMethod = cf.getMethods();
for (int index = 0; index < listMethod.size(); index++) {
final MethodInfo methodInfo = (MethodInfo) listMethod
.get(index);
System.out.println("メソッド:" + methodInfo.getName());
final CodeAttribute ca = methodInfo.getCodeAttribute();
final byte[] codes = ca.getCode();
for (final CodeIterator ci = ca.iterator(); ci.hasNext();) {
final int line = ci.next();
System.out.println(line + ":");
int opcode = codes[line];
if (opcode < 0) {
opcode += 0x100;
}
switch (opcode) {
case Opcode.ALOAD:
System.out.println(" ALOAD");
break;
case Opcode.ALOAD_0:
System.out.println(" ALOAD_0");
break;
case Opcode.ALOAD_1:
System.out.println(" ALOAD_1");
break;
case Opcode.ALOAD_2:
System.out.println(" ALOAD_2");
break;
case Opcode.ALOAD_3:
System.out.println(" ALOAD_3");
break;
case Opcode.ILOAD:
System.out.println(" ILOAD");
break;
case Opcode.ILOAD_0:
System.out.println(" ILOAD_0");
break;
case Opcode.ILOAD_1:
System.out.println(" ILOAD_1");
break;
case Opcode.ILOAD_2:
System.out.println(" ILOAD_2");
break;
case Opcode.ILOAD_3:
System.out.println(" ILOAD_3");
break;
case Opcode.ASTORE:
System.out.println(" ASTORE");
break;
case Opcode.ASTORE_0:
System.out.println(" ASTORE_0");
break;
case Opcode.ASTORE_1:
System.out.println(" ASTORE_1");
break;
case Opcode.ASTORE_2:
System.out.println(" ASTORE_2");
break;
case Opcode.ASTORE_3:
System.out.println(" ASTORE_3");
break;
case Opcode.ISTORE:
System.out.println(" ISTORE");
break;
case Opcode.ISTORE_0:
System.out.println(" ISTORE_0");
break;
case Opcode.ISTORE_1:
System.out.println(" ISTORE_1");
break;
case Opcode.ISTORE_2:
System.out.println(" ISTORE_2");
break;
case Opcode.ISTORE_3:
System.out.println(" ISTORE_3");
break;
case Opcode.ICONST_0:
System.out.println(" ICONST_0");
break;
case Opcode.ICONST_1:
System.out.println(" ICONST_1");
break;
case Opcode.ICONST_2:
System.out.println(" ICONST_2");
break;
case Opcode.ICONST_3:
System.out.println(" ICONST_3");
break;
case Opcode.ATHROW:
System.out.println(" ATHROW");
break;
case Opcode.LDC:
System.out.println(" LDC");
break;
case Opcode.LXOR:
System.out.println(" LXOR");
break;
case Opcode.GOTO:
System.out.println(" GOTO");
break;
case Opcode.IFEQ:
System.out.println(" IFEQ");
break;
case Opcode.IFGE:
System.out.println(" IFGE");
break;
case Opcode.IFGT:
System.out.println(" IFGT");
break;
case Opcode.IFLE:
System.out.println(" IFLE");
break;
case Opcode.IFLT:
System.out.println(" IFLT");
break;
case Opcode.IFNE:
System.out.println(" IFNE");
break;
case Opcode.IF_ACMPNE:
System.out.println(" IF_ACMPNE");
break;
case Opcode.IF_ICMPNE:
System.out.println(" IF_ICMPNE");
break;
case Opcode.IF_ICMPLT:
System.out.println(" IF_ICMPLT");
break;
case Opcode.IINC:
System.out.println(" IINC");
break;
case Opcode.INVOKEINTERFACE:
System.out.println(" INVOKEINTERFACE");
break;
case Opcode.INVOKESPECIAL:
System.out.println(" INVOKESPECIAL");
break;
case Opcode.INVOKEVIRTUAL:
System.out.println(" INVOKEVIRTUAL");
break;
case Opcode.INVOKESTATIC:
System.out.println(" INVOKESTATIC");
break;
case Opcode.NEW:
System.out.println(" NEW");
break;
case Opcode.DUP:
System.out.println(" DUP");
break;
case Opcode.PUTFIELD:
System.out.println(" PUTFIELD");
break;
case Opcode.RET:
System.out.println(" RET");
break;
case Opcode.RETURN:
System.out.println(" RETURN");
break;
case Opcode.ARETURN:
System.out.println(" ARETURN");
break;
case Opcode.MONITOREXIT:
System.out.println(" MONITOREXIT");
break;
case Opcode.MONITORENTER:
System.out.println(" MONITORENTER");
break;
case Opcode.BALOAD:
System.out.println(" BALOAD");
break;
case Opcode.BASTORE:
System.out.println(" BASTORE");
break;
case Opcode.TABLESWITCH:
System.out.println(" TABLESWITCH");
break;
case Opcode.WIDE:
System.out.println(" WIDE");
break;
case Opcode.JSR:
System.out.println(" JSR");
break;
case Opcode.ARRAYLENGTH:
System.out.println(" ARRAYLENGTH");
break;
case Opcode.CHECKCAST:
System.out.println(" CHECKCAST");
break;
case Opcode.GETSTATIC:
System.out.println(" GETSTATIC");
break;
case Opcode.LOOKUPSWITCH:
System.out.println(" LOOKUPSWITCH");
break;
default:
System.out.println(" このサンプルでは未対応のコードです:" + opcode
+ "(" + Integer.toHexString(opcode) + ")");
break;
}
}
}
} finally {
fin.close();
}
}
} ```
関連する日記
検討した結果、blanco Frameworkのバイトコード解析のためのライブラリには Apache Jakarta BCELを採用することにしました。というのも、blanco Frameworkではclassファイルの読み出しが主たる目的であり、しかもBCELの特定の機能に依存するのが良いようなので、トータル的には BCELの利用が望ましいと判断します。これは総合的な機能などの判断によるものではなく、たまたま私が持っているニーズに対してBCELの機能やライセンスが最もフィットするものと判断したのに過ぎません。