Java代码使用检查器

时间:2009-04-20 00:26:47

标签: java code-coverage static-analysis

我正在开发一个库,我们想要确定我们使用了多少库。 I.E.我们想知道我们的库中有多少方法是公开的,但从未被调用过。

目标: 静态分析 确定在当前项目中调用包A中的每个公共方法的代码行数。如果调用次数为零,则应按此方式报告该方法。

10 个答案:

答案 0 :(得分:9)

我相信你正在寻找这个eclipse插件 - > UCDetector

从文档(付费通知到第二个要点)

  • 不必要的(死的)代码
  • 可见性可以更改为受保护,默认或的代码 私人
  • 字段的方法,可以是最终的

在较大规模上,如果要进行对象级静态分析,请查看IBM的这个工具 - > Structural Analysis for Java。它对于库,API等的对象分析非常有用。

答案 1 :(得分:3)

不完全是您要找的,但是:

使用代码覆盖工具(如Cobertura)可以完成类似的工作。他们不对源代码进行静态检查,而是检测字节码以在运行时收集度量。当然,您需要以运行所有使用模式的方式驱动应用程序,并且可能会错过罕见的代码路径。

在静态分析方面,也许这些工具可以帮助你(Apache项目使用它们来检查新版本的API兼容性,看起来这个任务与你想要做的事情有些相关):

  • Clirr是一个检查Java库以获得与旧版本的二进制和源兼容性的工具。基本上你给它两组jar文件,Clirr转储出公共api中的变化列表。
  • JDiff是一个Javadoc doclet,它生成一个HTML报告,其中包含两个API都已删除,添加或更改的所有包,类,构造函数,方法和字段,包括文档。相比较。

答案 2 :(得分:3)

客户使用反射调用是静态分析中需要考虑的一个漏洞。因为没有办法确定某个特定方法是不是通过一些奇怪的反射方案来调用的。因此,运行和静态分析的组合可能是最好的。

答案 3 :(得分:1)

我认为你无法衡量一个类或一个功能需要“经常”的程度 有一些简单的问题:

  • 如果您的游戏库的使用统计信息是“正常”还是“异常值”,则定义了什么?经常在游戏中自杀是不对的?您可以更频繁地使用“killScreen”类,就像一个优秀的游戏玩家一样。
  • 什么定义“多”?时间或使用量? POJO将消耗极少的时间,但经常使用。

结论:
我不知道你想要完成什么 如果要显示代码依赖关系,可以使用其他tools来执行此操作。如果您正在尝试测量代码执行,那么Java有profiler or benchmarks。如果您是统计极客,您会对RapidMiner;)

感到满意

祝你好运!

答案 4 :(得分:1)

我建议JDepend向您展示包和类之间的依赖关系,非常适合查找循环依赖关系! http://clarkware.com/software/JDepend.html (它有一个eclipse插件:http://andrei.gmxhome.de/jdepend4eclipse/

以及其他指标的PMD http://pmd.sourceforge.net/

答案 5 :(得分:1)

IntelliJ有一个工具来检测可以有更多限制修饰符的方法,字段,类。它还可以快速修复应用这些更改,这也可以为您节省大量工作。如果您不想为此付费,您可以获得30天的eval许可证,这足以让您更改代码,这不是您经常需要做的事情。

BTW:IntelliJ有大约650次代码检查以提高代码质量,大约一半有自动修复,所以我建议花几天时间使用它来重构/整理你的代码。

答案 6 :(得分:1)

请查看Dead Code Detector。它声称可以满足您的需求:使用静态分析查找未使用的代码。

答案 7 :(得分:0)

以下是一些Java代码覆盖工具列表。我个人没有使用过这些,但它可能会让你开始:

答案 8 :(得分:0)

Proguard也可以是一个选项(http://proguard.sourceforge.net/):

“ProGuard的一些用途是:

  • ...
  • 列出死代码,因此可以从源代码中删除。
  • ......“

另见http://proguard.sourceforge.net/manual/examples.html#deadcode

答案 9 :(得分:0)

您可以使用ASM字节码分析库(http://asm.ow2.org)为此编写自己的实用程序(在阅读本文后的一个小时内)。您需要实现ClassVisitor和MethodVisitor。您将使用ClassReader来解析库中的类文件。

  • 将为每个声明的方法调用ClassVisitor的visitMethod(..)。
  • 将为每个被调用的方法调用MethodVisitor的visitMethodInsn(..)。

维护地图进行计数。键代表方法(见下文)。这是一些代码:

class MyClassVisitor {
    // ...
    public void visit(int version, int access, String name, ...) {
        this.className = name;
    }
    public MethodVisitor visitMethod(int access, String name, String desc, ...):
        String key = className + "." + name + "#" + desc;
        if (!map.containsKey() {
            map.put(key, 0);
        }
        return new MyMethodVisitor(map);
    }
    // ...
}

void class MyMethodVisitor {
    // ...
    public visitMethodInsn(int opcode, String name, String owner, String desc, ...) {
        String key = owner + "." + name + "#" + desc;
        if (!map.containsKey() {
            map.put(key, 0);
        }
        map.put(key, map.get(key) + 1);
    }
    // ...
}

基本上就是这样。你正在以这样的方式开始表演:

Map<String,Integer> map = new HashMap<String,Integer>();
for (File classFile : my library) {
    InputStream input = new FileInputStream(classFile);
    new ClassReader(input).accept(new MyClassVisitor(map), 0);
    input.close();
}
for (Map.Entry<String,Integer> entry : map.entrySet()) {
    if (entry.getValue() == 0) {
        System.out.println("Unused method: " + entry.getKey());
    }
}

享受!