Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:从JAR文件中的类文件中获取方法存根的简单方法?反射_Java_Reflection_Class_Jar_Methods - Fatal编程技术网

Java:从JAR文件中的类文件中获取方法存根的简单方法?反射

Java:从JAR文件中的类文件中获取方法存根的简单方法?反射,java,reflection,class,jar,methods,Java,Reflection,Class,Jar,Methods,我正在寻找一种方法来获取jar文件中所有类的方法存根列表。 我不知道从哪里开始。。。我可以使用反射、Javassist或其他一些我还没有听说过的工具吗!? 至少可以解包jar、反编译类文件并用行解析器扫描方法,但我认为这是最肮脏的方式;-) 有什么想法吗 我能想到的最好的方法是使用ASM字节码框架。这样,至少您不必使用行解析器进行一些反编译输出。事实上,获取方法存根应该类似于一个访问者接口的20行实现 我自己也用过它来重写字节码,它非常简单和直接(特别是如果你只是在读类文件的话) 在此基础上,您

我正在寻找一种方法来获取jar文件中所有类的方法存根列表。 我不知道从哪里开始。。。我可以使用反射、Javassist或其他一些我还没有听说过的工具吗!? 至少可以解包jar、反编译类文件并用行解析器扫描方法,但我认为这是最肮脏的方式;-)

有什么想法吗


我能想到的最好的方法是使用ASM字节码框架。这样,至少您不必使用行解析器进行一些反编译输出。事实上,获取方法存根应该类似于一个访问者接口的20行实现

我自己也用过它来重写字节码,它非常简单和直接(特别是如果你只是在读类文件的话)

在此基础上,您还可以使用ASM的树API(与其访问者API相反)来解析JAR文件中包含的类文件的内容。此外,还可以使用类读取JAR文件中包含的文件。下面是一个如何做到这一点的示例:

printMethodStubs
方法接受一个
JarFile
,并继续打印所有类文件中包含的所有方法的描述

public void printMethodStubs(JarFile jarFile) throws Exception {
    Enumeration<JarEntry> entries = jarFile.entries();
    while (entries.hasMoreElements()) {
        JarEntry entry = entries.nextElement();

        String entryName = entry.getName();
        if (entryName.endsWith(".class")) {
            ClassNode classNode = new ClassNode();

            InputStream classFileInputStream = jarFile.getInputStream(entry);
            try {
                ClassReader classReader = new ClassReader(classFileInputStream);
                classReader.accept(classNode, 0);
            } finally {
                classFileInputStream.close();
            }

            System.out.println(describeClass(classNode));
        }
    }
}
describeMethod
方法接受并返回描述方法签名的字符串:

public String describeMethod(MethodNode methodNode) {
    StringBuilder methodDescription = new StringBuilder();

    Type returnType = Type.getReturnType(methodNode.desc);
    Type[] argumentTypes = Type.getArgumentTypes(methodNode.desc);

    @SuppressWarnings("unchecked")
    List<String> thrownInternalClassNames = methodNode.exceptions;

    if ((methodNode.access & Opcodes.ACC_PUBLIC) != 0) {
        methodDescription.append("public ");
    }

    if ((methodNode.access & Opcodes.ACC_PRIVATE) != 0) {
        methodDescription.append("private ");
    }

    if ((methodNode.access & Opcodes.ACC_PROTECTED) != 0) {
        methodDescription.append("protected ");
    }

    if ((methodNode.access & Opcodes.ACC_STATIC) != 0) {
        methodDescription.append("static ");
    }

    if ((methodNode.access & Opcodes.ACC_ABSTRACT) != 0) {
        methodDescription.append("abstract ");
    }

    if ((methodNode.access & Opcodes.ACC_SYNCHRONIZED) != 0) {
        methodDescription.append("synchronized ");
    }

    methodDescription.append(returnType.getClassName());
    methodDescription.append(" ");
    methodDescription.append(methodNode.name);

    methodDescription.append("(");
    for (int i = 0; i < argumentTypes.length; i++) {
        Type argumentType = argumentTypes[i];
        if (i > 0) {
            methodDescription.append(", ");
        }
        methodDescription.append(argumentType.getClassName());
    }
    methodDescription.append(")");

    if (!thrownInternalClassNames.isEmpty()) {
        methodDescription.append(" throws ");
        int i = 0;
        for (String thrownInternalClassName : thrownInternalClassNames) {
            if (i > 0) {
                methodDescription.append(", ");
            }
            methodDescription.append(Type.getObjectType(thrownInternalClassName).getClassName());
            i++;
        }
    }

    return methodDescription.toString();
}
公共字符串描述方法(MethodNode MethodNode){
StringBuilder methodDescription=新建StringBuilder();
类型returnType=Type.getReturnType(methodNode.desc);
Type[]argumentTypes=Type.getArgumentTypes(methodNode.desc);
@抑制警告(“未选中”)
List thrownInternalClassNames=methodNode.exceptions;
if((methodNode.access&opcode.ACC_PUBLIC)!=0){
方法说明。附加(“公共”);
}
if((methodNode.access&opcode.ACC_PRIVATE)!=0){
方法描述。附加(“私有”);
}
if((methodNode.access&opcode.ACC_PROTECTED)!=0){
方法说明。附加(“受保护”);
}
if((methodNode.access&opcode.ACC_STATIC)!=0){
methodDescription.append(“静态”);
}
if((methodNode.access&opcode.ACC_ABSTRACT)!=0){
方法描述。追加(“摘要”);
}
if((methodNode.access&opcode.ACC_SYNCHRONIZED)!=0){
方法描述。追加(“同步”);
}
append(returnType.getClassName());
方法说明。追加(“”);
methodDescription.append(methodNode.name);
方法说明。追加(“”);
for(int i=0;i0){
方法说明。追加(“,”);
}
append(argumentType.getClassName());
}
方法说明。追加(“)”;
如果(!thrownInternalClassNames.isEmpty()){
方法描述。追加(“抛出”);
int i=0;
for(字符串thrownInternalClassName:thrownInternalClassName){
如果(i>0){
方法说明。追加(“,”);
}
append(Type.getObjectType(thrownInternalClassName.getClassName());
i++;
}
}
return methodDescription.toString();
}

这很好,完全符合我搜索的内容。谢谢你们!以下是使用此代码的所有导入:
import java.io.InputStream;导入java.util.Enumeration;导入java.util.List;导入java.util.jar.JarEntry;导入java.util.jar.jar文件;导入org.objectweb.asm.ClassReader;导入org.objectweb.asm.opcode;导入org.objectweb.asm.Type;导入org.objectweb.asm.tree.ClassNode;导入org.objectweb.asm.tree.MethodNode;导入xbn.lang.SimpleXbnObject我在网站上找不到好的jar导入。你能帮忙吗?非常感谢。是的,我知道以前的帖子,但问题很有趣。
public String describeMethod(MethodNode methodNode) {
    StringBuilder methodDescription = new StringBuilder();

    Type returnType = Type.getReturnType(methodNode.desc);
    Type[] argumentTypes = Type.getArgumentTypes(methodNode.desc);

    @SuppressWarnings("unchecked")
    List<String> thrownInternalClassNames = methodNode.exceptions;

    if ((methodNode.access & Opcodes.ACC_PUBLIC) != 0) {
        methodDescription.append("public ");
    }

    if ((methodNode.access & Opcodes.ACC_PRIVATE) != 0) {
        methodDescription.append("private ");
    }

    if ((methodNode.access & Opcodes.ACC_PROTECTED) != 0) {
        methodDescription.append("protected ");
    }

    if ((methodNode.access & Opcodes.ACC_STATIC) != 0) {
        methodDescription.append("static ");
    }

    if ((methodNode.access & Opcodes.ACC_ABSTRACT) != 0) {
        methodDescription.append("abstract ");
    }

    if ((methodNode.access & Opcodes.ACC_SYNCHRONIZED) != 0) {
        methodDescription.append("synchronized ");
    }

    methodDescription.append(returnType.getClassName());
    methodDescription.append(" ");
    methodDescription.append(methodNode.name);

    methodDescription.append("(");
    for (int i = 0; i < argumentTypes.length; i++) {
        Type argumentType = argumentTypes[i];
        if (i > 0) {
            methodDescription.append(", ");
        }
        methodDescription.append(argumentType.getClassName());
    }
    methodDescription.append(")");

    if (!thrownInternalClassNames.isEmpty()) {
        methodDescription.append(" throws ");
        int i = 0;
        for (String thrownInternalClassName : thrownInternalClassNames) {
            if (i > 0) {
                methodDescription.append(", ");
            }
            methodDescription.append(Type.getObjectType(thrownInternalClassName).getClassName());
            i++;
        }
    }

    return methodDescription.toString();
}