ASM Java Byte Code を使用してクラスのすべてのスーパークラスを取得する方法は?
1921 次
3 に答える
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;
}
}
于 2013-02-13T08:30:59.440 に答える
0
クラスファイルには直接のスーパークラスしか含まれていないため、これは少し注意が必要です。したがって、すべてのスーパー クラスを再帰的に読み取る必要があります。
これを行うには、オーバーライドされた visit(int version, int access, String name, String signature, 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, ...)
}
于 2013-02-06T06:48:48.423 に答える
0
これを行う簡単な方法の 1 つは、クラスのコンストラクターのバイトコードにアクセスし、最初のコンストラクター呼び出し命令 (つまり、invokespecial
見つけた呼び出し) を記録することです。super
これにより、現在関心のあるクラスに属するクラスの名前が得られるはずです。
于 2013-02-05T10:37:12.027 に答える