在大型java项目中,您使用什么工具来查找未使用的/死亡的代码?我们的产品已经开发了几年,手动检测不再使用的代码变得非常困难。但是,我们会尽量删除未使用的代码。
对于一般策略/技术(而不是特定工具)的建议也很感激。
编辑:注意,我们已经使用代码覆盖工具(Clover, IntelliJ),但这些帮助不大。死代码仍然有单元测试,并显示为已覆盖。我想理想的工具应该是识别那些依赖于它的其他代码很少的代码集群,从而允许手动检查文档。
Eclipse可以显示/突出显示无法访问的代码。JUnit可以向您显示代码覆盖率,但是您需要进行一些测试,并且必须决定是否缺少相关的测试,或者代码确实没有使用过。
有一些工具可以分析代码并提供代码覆盖率数据。这可以让您看到(当代码运行时)调用了多少代码。您可以使用任何这些工具来找出您有多少孤立代码。
理论上,您无法确定地找到未使用的代码。这有一个数学证明(好吧,这是一个更普遍的定理的特殊情况)。如果你很好奇,可以查一下《停止问题》。
这可以在Java代码中以多种方式表现出来:
也就是说,我使用IDEA IntelliJ作为我的IDE选择,它有广泛的分析工具,可以发现模块、未使用的方法、未使用的成员、未使用的类等之间的依赖关系。它也很智能,就像一个没有被调用的私有方法被标记为未使用,但一个公共方法需要更广泛的分析。
我们已经开始使用找到错误来帮助识别代码库中目标丰富的重构环境中的一些缺陷。我还会考虑结构101来识别代码库架构中过于复杂的地方,这样你就知道真正的沼泽在哪里。
我会让运行中的系统保持代码使用的日志,然后开始检查几个月或几年没有使用的代码。
例如,如果您对未使用的类感兴趣,那么所有的类都可以在创建实例时记录日志。然后,一个小脚本可以将这些日志与完整的类列表进行比较,以找到未使用的类。
当然,如果在方法级别上,您应该牢记性能。例如,这些方法只能记录它们的第一次使用。我不知道如何在Java中最好地做到这一点。我们已经在Smalltalk中实现了这一点,它是一种动态语言,因此允许在运行时修改代码。我们用一个日志调用来检测所有方法,并在方法第一次被记录后卸载日志代码,这样一段时间后就不会再出现性能损失。也许类似的事情可以在Java中使用静态布尔标记完成……
一个工作得相当不错的Eclipse插件是未使用代码检测器。
它处理整个项目或特定文件,并显示各种未使用/死亡的代码方法,以及建议可见性更改(即可以保护或私有的公共方法)。
用户覆盖工具,例如EMMA。但它不是静态工具(也就是说,它需要通过回归测试实际运行应用程序,并通过所有可能的错误情况,这是不可能的:))
尽管如此,EMMA还是非常有用的。
使用测试覆盖工具来检测代码库,然后运行应用程序本身,而不是测试。
艾玛和Eclemma将为您提供良好的报告,说明在任何给定的代码运行中,哪些类运行的百分比。
代码覆盖工具,如Emma、Cobertura和Clover,将检测您的代码,并记录通过运行一组测试调用代码的哪些部分。这是非常有用的,并且应该是开发过程中不可分割的一部分。它将帮助您确定测试套件对代码的覆盖程度。
然而,这与识别真正的死代码是不同的。它只识别被测试覆盖(或未被测试覆盖)的代码。这可能会给您带来假阳性(如果您的测试没有覆盖所有场景)和假阴性(如果您的测试访问了实际上从未在真实场景中使用过的代码)。
我认为真正识别死代码的最好方法是在实时运行的环境中使用覆盖工具,并在一段较长的时间内分析代码覆盖率。
如果您在负载平衡的冗余环境中运行(如果不是,为什么不呢?),那么我认为只检测应用程序的一个实例并配置负载均衡器,以便随机但少量的用户在检测的实例上运行是有意义的。如果您在一段较长的时间内这样做(以确保您已经覆盖了所有真实世界的使用场景——例如季节性变化),那么您应该能够准确地看到在真实世界的使用中访问了代码的哪些部分,哪些部分实际上从未访问过,因此是死代码。
我个人从来没有见过这样做,也不知道如何使用上述工具来检测和分析没有通过测试套件调用的代码——但我相信它们可以做到。
然而,两者都不能在工作空间中找到未使用的公共静态方法。如果有人知道这样的工具,那么请让我知道。
我在Eclipse中对单个类所做的一件事是,将它的所有方法都更改为private,然后看看我得到了什么抱怨。对于所使用的方法,这将引起错误,我将它们返回到尽可能低的访问级别。对于未使用的方法,这将引发关于未使用方法的警告,然后可以删除这些方法。作为奖励,您经常会发现一些公共方法可以而且应该被私有。
但这是非常手工的。
IntelliJ有代码分析工具,用于检测未使用的代码。你应该试着让尽可能多的字段/方法/类成为非公共的,这样会显示出更多未使用的方法/字段/类
我还会尝试找到重复的代码,作为减少代码量的一种方式。
我的最后一个建议是,尽量找到开放源代码,如果使用,会使您的代码更简单。
Structure101 片的角度来看将给出与“主”集群没有依赖关系的类或包的“孤儿”或“孤儿组”的列表(和依赖关系图)。
CodePro最近由谷歌随Eclipse项目发布。它是免费的,而且非常有效。该插件有一个带有一个或多个入口点的'查找死代码'特性。效果很好。
我很惊讶这里没有提到混淆器。这是目前最成熟的产品之一。
混淆器是一个免费的Java类文件收缩器,优化器,模糊器, 和预先验证。它检测并删除未使用的类,字段, 方法和属性。它优化字节码并删除未使用的字节码 指令。它重命名其余的类、字段和方法 使用简短而无意义的名字。最后,它预验证已处理的结果 . code for java6或javamicro Edition ProGuard的一些用途是: 创建更紧凑的代码,以获得更小的代码存档、更快的网络传输、更快的加载和更小的内存 李脚印。< / > 使程序和库更难进行逆向工程。 列出死代码,这样就可以从源代码中删除它。 为Java 6或更高版本重新定位和预验证现有的类文件,以充分利用它们更快的类加载。
ProGuard的一些用途是:
下面是列表死代码的例子:https://www.guardsquare.com/en/products/proguard/manual/examples#deadcode
我发现三叶草覆盖工具,仪器代码和突出显示的代码是使用和未使用的。不像谷歌CodePro分析,它也适用于WebApplications(根据我的经验,我可能是不正确的谷歌CodePro)。
我注意到的唯一缺点是它没有考虑Java接口。
DCD不是某些IDE的插件,但可以从ant或独立运行。它看起来像一个静态工具和它可以做PMD和FindBugs不能做的事情。我会试试的。
附注:正如下面的评论中提到的,项目现在存在于GitHub中。
有一个Java项目——死代码检测器 (DCD)。对于源代码,它似乎工作得不太好,但对于.jar文件-它真的很好。另外,您可以通过类和方法进行过滤。
在Eclipse Goto Windows >首选项> Java >编译器>错误/警告 把它们都改成错误。修复所有错误。这是最简单的方法。美妙之处在于,这将允许您在编写时清理代码
截图Eclipse代码:
Netbeans是Netbeans 死码检测器的插件。
如果它可以链接到并突出显示未使用的代码,那就更好了。你可以在这里投票和评论:Bug 181458 -找到未使用的公共类,方法,字段
我使用Doxygen开发了一个方法调用映射来定位从未调用过的方法。在图中,您将发现没有调用者的方法集群孤岛。这对库不起作用,因为您总是需要从一些主要入口点开始。