2013-10-03 56 views
2

我正在嘗試編寫一個程序,該程序需要.class文件並收集.class文件的所有方法以及每個方法的內容。這裏是我的代碼ASM:輸出java字節碼和操作碼

public class ClassReaderTest1 { 

    public static void main(String[] args) throws Exception{ 
     InputStream in = new FileInputStream("*.class"); 
     ClassReader reader = new ClassReader(in); 
     ClassNode classNode = new ClassNode(); 
     reader.accept(classNode,0); 
     @SuppressWarnings("unchecked") 
     final List<MethodNode> methods = classNode.methods; 

     for(MethodNode m: methods){ 
      InsnList inList = m.instructions; 
      System.out.println(m.name); 
      for(int i = 0; i< inList.size(); i++){ 
       System.out.println("  " +  Integer.toHexString(inList.get(i).getOpcode())); 
      } 
     } 
    } 
} 

,這裏是我的輸出

init> 
    ffffffff 
    ffffffff 
    19 
    b7 
    b1 
    ffffffff 
main 
    ffffffff 
    ffffffff 
    b2 
    12 
    b6 
    ffffffff 
    ffffffff 
    3 
    36 
    ffffffff 
    ffffffff 
    b1 
    ffffffff 

最後,我不想打印這些價值觀,我只是希望能夠引用他們在我的節目(我試圖檢查我得到正確的值)。我正在按照預期方式獲得這些方法,但方法的內容對我來說沒有意義。正如我所看到的,這些不是操作碼;特別是「fffffff」不是一個java操作碼。我想要做的就是按照上面所做的打印出所有的方法,然後打印出現在的操作碼,然後打印出java字節碼,後面跟着幾個空格,然後打印操作碼。例如

main 
    bytecode ** 
    . 
    . 

,我加載到該程序的文件只包含一個主要方法,一個println語句,和一個int變量的初始化。

我的問題是我做錯了什麼,或者我只是不正確地解釋我的結果?另外,我怎樣才能得到字節碼?我一直無法找到解決辦法。當我使用Java字節碼輪廓插件進行eclipse時,我可以看到它,但我需要能夠在我的程序中引用它。

在此先感謝

回答

10

我能弄明白我自己。我發佈我的解決方案,以防其他人遇到同樣的問題。請注意,在我的實現中,我不打印操作碼(一個println語句就是所有需要添加的操作)。

import java.io.InputStream; 
import java.io.FileInputStream; 
import java.io.StringWriter; 
import java.io.PrintWriter; 
import java.util.List; 
import org.objectweb.asm.*; 
import org.objectweb.asm.tree.*; 
import org.objectweb.asm.util.*; 

public class ClassReaderTest1 { 

    public static void main(String[] args) throws Exception{ 
     InputStream in = new FileInputStream("*afile*"); 
     ClassReader reader = new ClassReader(in); 
     ClassNode classNode = new ClassNode(); 
     reader.accept(classNode,0); 
     @SuppressWarnings("unchecked") 
     final List<MethodNode> methods = classNode.methods; 
     for(MethodNode m: methods){ 
      InsnList inList = m.instructions; 
      System.out.println(m.name); 
      for(int i = 0; i< inList.size(); i++){ 
       System.out.print(insnToString(inList.get(i))); 
      } 
     } 
    } 

    public static String insnToString(AbstractInsnNode insn){ 
     insn.accept(mp); 
     StringWriter sw = new StringWriter(); 
     printer.print(new PrintWriter(sw)); 
     printer.getText().clear(); 
     return sw.toString(); 
    } 

    private static Printer printer = new Textifier(); 
    private static TraceMethodVisitor mp = new TraceMethodVisitor(printer); 

} 

這裏是生產

<init> 
    L0 
    LINENUMBER 1 L0 
    ALOAD 0 
    INVOKESPECIAL java/lang/Object.<init>()V 
    RETURN 
    L1 
main 
    L2 
    LINENUMBER 3 L2 
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream; 
    LDC "Hello World!!!" 
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V 
    L3 
    LINENUMBER 4 L3 
    ICONST_0 
    ISTORE 1 
    L4 
    LINENUMBER 5 L4 
    RETURN 
    L5 
+0

對於它的價值,在ClassReader魔術被http://asm.ow2.org/doc/faq.html我相信提供的輸出 – balupton