top / index / prev / next / target / source

2006-01-10 diary: Javassist を用いたクラスファイル(バイトコード)解析サンプル , blancoJUnit2Docが妥当な名称であるかどうかを検討中

いがぴょんの日記 日記形式でつづる いがぴょんコラム ウェブページです。

old-v2

Javassist を用いたクラスファイル(バイトコード)解析サンプル , blancoJUnit2Docが妥当な名称であるかどうかを検討中

Apache Jakarta BCELに引き続き、こんどは Javassistを体験しました。

blanco Framework: blancoJUnit2Docで良いかどうか名前を検討中…

blanco Frameworkのサブプロジェクトである JUnit用テストケース・ソースコードからドキュメントを自動生成するツールの名称について、「blancoJUnit2Doc」で良いかどうかを検討中です。

私にネーミングのセンスが無いことが、あらためて実感される今日この頃です。

2006.01.14追記 結局 プロジェクト名は blancoJUnit に落ち着きました。

関連する日記

BCEL以外のバイトコード解析ツールをざっくり調べてみました

Apache Jakarta BCEL以外のツールを用いたバイトコード解析についても少し調べてみました。バイトコード解析ということで DI/AOPツールをまずざっくりと見させていただきました。

Seasar2はJavassistを用いている模様です。

Spring Frameworkは 雰囲気的には CGLIBを用いている模様でした。(ウラを取っていません)

Javassist をざっくり調べました

Seasar2が採用していることもあり、Javassistを ざっくり見させていただきました。

また、はぶさんの日記経由で Javassistチュートリアルに到達しました。勉強になります。

Javassist を用いたクラスファイル(バイトコード)解析サンプル

先日に引き続き、こんどは Javassist を用いたクラスファイル(バイトコード)の解析を体験しました。

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のバイトコード解析のためのライブラリには Apache Jakarta BCELを採用することにしました。というのも、blanco Frameworkではclassファイルの読み出しが主たる目的であり、しかもBCELの特定の機能に依存するのが良いようなので、トータル的には BCELの利用が望ましいと判断します。これは総合的な機能などの判断によるものではなく、たまたま私が持っているニーズに対してBCELの機能やライセンスが最もフィットするものと判断したのに過ぎません。


この日記について