java - ASM 方法访问者可以与接口(interface)一起使用吗?

标签 java assembly static-analysis java-bytecode-asm

我需要编写一个工具来列出调用指定接口(interface)方法的类。它将用作由许多模块组成的大型 Java 应用程序的构建过程的一部分。目标是自动记录某些 java 模块之间的依赖关系。

我找到了几个用于依赖分析的工具,但它们在方法级别上不起作用,仅适用于包或 jar。最后我找到了 ASM,它似乎可以满足我的需要。

以下代码打印给定目录中所有类文件的方法依赖关系:

import java.io.*;
import java.util.*;

import org.objectweb.asm.ClassReader;

public class Test {

    public static void main(String[] args) throws Exception {

        File dir = new File(args[0]);

        List<File> classFiles = new LinkedList<File>();
        findClassFiles(classFiles, dir);

        for (File classFile : classFiles) {
            InputStream input = new FileInputStream(classFile);
            new ClassReader(input).accept(new MyClassVisitor(), 0);
            input.close();
        }
    }

    private static void findClassFiles(List<File> list, File dir) {
        for (File file : dir.listFiles()) {
            if (file.isDirectory()) {
                findClassFiles(list, file);
            } else if (file.getName().endsWith(".class")) {
                list.add(file);
            }
        }
    }
}

import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.commons.EmptyVisitor;

public class MyClassVisitor extends EmptyVisitor {

    private String className;

    @Override
    public void visit(int version, int access, String name, String signature,
            String superName, String[] interfaces) {
        this.className = name;
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String desc,
            String signature, String[] exceptions) {

        System.out.println(className + "." + name);
        return new MyMethodVisitor();
    }
}

import org.objectweb.asm.commons.EmptyVisitor;

public class MyMethodVisitor extends EmptyVisitor {

    @Override
    public void visitMethodInsn(int opcode, String owner, String name,
            String desc) {

        String key = owner + "." + name;
        System.out.println("  " + key);
    }
}

问题:

该代码仅适用于常规类(class)!如果类文件包含接口(interface),则会调用 visitMethod,但不会调用 visitMethodInsn。我没有获得有关接口(interface)方法调用者的任何信息。

有什么想法吗?

最佳答案

我认为这是因为接口(interface)方法没有方法体。尝试编写一个空方法作为“普通”类的一部分,并查看是否调用了 visitMethodInsn。

顺便问一下,您是否考虑过使用 java.lang.instrument 来发现在运行时加载的类并以这种方式进行检测,而不是从磁盘读取类文件?

关于java - ASM 方法访问者可以与接口(interface)一起使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2866805/

相关文章:

c - 如何在没有wmi的情况下用C或asm获取硬盘序列号

c - 采用 Frama-C 和 Eva 的动态阵列

c# - 检查解决方案中的二进制引用

java - 将 Double 舍入到小数点后 1 位 kotlin : from 0. 044999 到 0.1

assembly - 错误 : A1163E Unknown Opcode R0, 期望操作码或宏指令位于左列

java - 如何将 Jpeg2000 (.jp2) 渲染到 ImageView?

c++ - SSE 双线性插值

c++ - 如何正确设置SonarQube cfamil.gcov?

java - Java 中的不可变集合

java - SQL WHERE 中的多个条件 AND