2013-02-05 89 views

回答

0

這樣做的一個簡單方法是訪問類的構造函數的字節碼並記錄第一個構造函數調用指令,即調用您可以找到的invokespecial。這應該會給你當前感興趣的課程名稱super

+1

維傑你好,謝謝你的幫助..我這樣做以下列方式。可以嗎? –

+0

嘿@RameshSubramanian ...我認爲你的解決方案應該可以工作。我沒有運行它或任何東西,但使用ClassReader應該工作得很好。我不想想這個更簡單的解決方案是愚蠢的。對此表示讚賞。 – vijay

0

這有點棘手,因爲類文件只包含直接的超類。因此,你必須遞歸讀取所有的超類。

您可以通過使用帶有重寫訪問(int版本,int訪問,字符串名稱,字符串簽名,String superName,String [] interfaces)方法來讀取超類名稱的ClassVisitor來處理每個類。

僞代碼:

List<String> getSuperClasses(className){ 
    superClass=getSuperClass(className) 
    return superClass+getSuperClasses(superClass) 
} 

String getSuperClass(className) { 
    cw=new ClassWriter() 
    v=new SuperClassReadingClassVisitor(cw) 
    new ClassReader(className).accept(v) 
    return v.superClass 
} 

class SuperClassReadingClassVisitor{ 
    String superClass 
    @Override 
    visit(int version, int access, String name, String signature, String superName, String[] interfaces) { 
    superClass=superName 
    super.visit(version, access, name, ...) 
} 
+0

嗨ruediste,非常感謝你,讓我試試這個在我的字節碼注入 –

+0

嗨rudiste,謝謝你的答..我按照以下方式。可以嗎?或者有沒有簡單的方法來獲得所有超類名? –

2
package com.eg.agent; 

import java.lang.instrument.ClassFileTransformer; 
import java.lang.instrument.IllegalClassFormatException; 
import java.lang.instrument.Instrumentation; 
import java.security.ProtectionDomain; 

import java.io.IOException; 
import java.io.InputStream; 
import java.util.ArrayList; 

import org.objectweb.asm.ClassReader; 

public class EgClassFileTransformer implements ClassFileTransformer { 

    protected String agentArgString = ""; 
    protected Instrumentation instrumentation; 

    public EgClassFileTransformer(String agentArgs, Instrumentation inst){ 
     agentArgString = agentArgs; 
     instrumentation = inst; 
     instrumentation.addTransformer(this); 
    } 

    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, 
      ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException 
     { 
      //System.out.println("ClassName :"+className); 
      InputStream in = loader.getResourceAsStream(className.replace('.', '/') + ".class"); 
      try{ 
       ClassReader classReader=new ClassReader(in); 
       String superClassName = classReader.getSuperName(); 
       String[] interfaces = classReader.getInterfaces(); 
       if(interfaces!=null && interfaces.length > 0){ 
        for(int k=0;k<interfaces.length;k++){ 
         String inface = interfaces[k]; 
         System.out.println(" \t interface :"+inface); 
        } 
       } 
       //System.out.println("superClassName :"+superClassName); 
       ArrayList thisList = new ArrayList(); 
       thisList.add(superClassName); 
       ArrayList superList = printSuperClassNames(superClassName , thisList); 
       System.out.println("className :"+className +" ==>"+ " superList :"+superList); 
      } catch (IOException e) { 
       //e.printStackTrace(); 
       System.out.println("[EXECEPTION] ..."+className); 
      } 
      return null; 
     } 

    public static ArrayList printSuperClassNames(String className, ArrayList list) 
    { 
     ClassReader cr=null; 
     try { 
      cr = new ClassReader(className); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     String superName = cr.getSuperName(); 
     //System.out.println("[superName]"+superName); 
     if(superName!=null && !superName.equals("java/lang/Object")) 
     { 
      list.add(superName); 
      String superClass = superName.replace('.', '/'); 
      printSuperClassNames(superClass, list); 
     } 
     return list; 
    } 
}