読者です 読者をやめる 読者になる 読者になる

Apache BCEL でクラスファイルの情報を取得してみる

Apache Commons BCEL を使ってクラスファイルの情報を取得してみる簡単なサンプル書いてみたので、メモしておきます。

Apache Commons BCEL™ -
https://commons.apache.org/proper/commons-bcel/index.html

BCEL ( Byte Code Engineering Library ) はその名の通り、クラスファイルの解析 / 生成 / 操作なんかができるライブラリということらしいです。

BCEL のサンプルの前に対象のクラスファイルを用意する。今回は以下の簡単なクラスを用意。

■ TestClass.java

package test;

public class TestClass extends ParentClass implements TestInterface {
  
  private String testField = "testField";
  
  public String testMethod(String s) {
    return testField + s;
  }
}


BCEL で情報を取得するサンプルが以下になります。簡単にフィールド / メソッド / 親クラス / インターフェイスの情報を取得してみました。

■ Test.java

package test;

import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.Field;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;

public class Test {
  public static void main(String[] args) throws Exception {
    ClassParser cp = new ClassParser("C:\\workspace44_2\\BCELTest\\bin\\test\\TestClass.class");
    JavaClass jc = cp.parse();
    // Repository#lookupClass でも取得できるらしく
    // JavaClass jc = Repository.lookupClass("test.TestClass");
    
    System.out.println("***** get field *****");
    Field[] fields = jc.getFields();
    for(Field f : fields) {
      System.out.println("Name:" + f.getName());
      System.out.println("Signature:" + f.getSignature());
    }
    
    System.out.println("***** get method *****");
    Method[] methods = jc.getMethods();
    for(Method m : methods) {
      System.out.println("Name:" + m.getName());
      System.out.println("Signature:" + m.getSignature());
    }
    
    System.out.println("***** get ParentClass *****");
    System.out.println(jc.getSuperclassName());
    
    System.out.println("***** get Interface *****");
    JavaClass[] interfaces = jc.getAllInterfaces();
    for(JavaClass i : interfaces) {
      System.out.println(i.getClassName());
    }
  }
}

■ 実行結果

***** get field *****
Name:testField
Signature:Ljava/lang/String;
***** get method *****
Name:<init>
Signature:()V
Name:testMethod
Signature:(Ljava/lang/String;)Ljava/lang/String;
***** get ParentClass *****
test.ParentClass
***** get Interface *****
test.TestInterface


ドキュメントに書いてありますが、ClassParser から JavaClass を生成して、JavaClass のメソッドでゴニョゴニョするって感じです。

Apache Commons BCEL™ - Byte Code Engineering Library (BCEL)

  • 3.1 JavaClass

https://commons.apache.org/proper/commons-bcel/manual.html#a3.1_JavaClass


簡単ですが、今日のところは以上です。

[ 環境情報 ]
Java SE 8 Update 25
Apache Commons BCEL 5.2