【问题标题】:Extract a reference graph while compiling Java codebase?在编译 Java 代码库时提取参考图?
【发布时间】:2013-04-10 23:04:51
【问题描述】:

背景:

  • 我正在使用(对我而言)相当大的代码库(例如:我目前只检查了几个相关项目,以及超过 11000 个类)。
  • 构建是 ant,测试是 JUnit,CI 是 Jenkins。
  • 在签入前运行所有测试不是一个选项,它需要 Jenkins 几个小时。即使对于某些单独的应用,也可能需要 45 分钟。
  • 有些测试不引用基于反射的单个方法,在某些情况下甚至不直接引用被测方法的类,因为它们询问聚合器类,并且知道传递模式- 通过这里使用的方法。由于它是一个庞大的代码库,超过 10 个开发人员,而且我不是负责人,这是我目前无法更改的。

我想要的是能够在签入之前打印出与 git diff 列表中的任何类相距两度(Kevin-Bacon-wise)的所有测试类的列表。这样,当我错过的某些内容最终运行并出现错误时,我可以将它们全部运行并减少来自 Jenkins 的愤怒电子邮件。

我能想到的最简单的方法是自己用 Ruby 脚本或类似的脚本编写代码,这样我就可以解释我们正在使用的一些模式,但要做到这一点,我需要能够查询“哪些类引用类 X?”

我可以解析 .java 或(更简单的).class 文件来获取此信息,但我不想 :) 有没有办法让 Javac 在编译时以简单的格式导出它?

【问题讨论】:

  • 更多信息:我需要在我的工作站上运行它,以便在它们进入上游之前捕获我犯的错误,至少在我能够证明它有用之前。切换到 Git、Maven 并改进 Jenkins 流程会很好,但这不是我能做到的。
  • 有很多工具可以分析类之间的依赖关系。您可能可以使用具有文本输出的内容并构建依赖关系图。还要看看 Sonar,我对此一无所知,但它应该是任何源分析的好工具

标签: java ant javac


【解决方案1】:

有没有办法让 Javac 在编译时以简单的格式导出它?

AFAIK,不。

但是,还有其他方法可以获取依赖项列表:

(但请注意,您不太可能获得静态工具来提取由Class.forName() 等产生的依赖项。另请注意,由于“编译时间常量”的方式,您无法从字节码文件中推断出完整的依赖项集处理。)


我觉得这里有几个问题:

  • 这听起来像是您的构建,实际上您的项目结构是单一的。如果您可以将代码库重组为单独构建的大型模块(根据它们的依赖关系),并单独控制版本,那么您只需要进行完整的构建并在发生变化时运行所有单元测试.. . 在其他一切都依赖的模块中。 (我可以建议使用“Maven”这个词吗?它对于大型代码库确实很有帮助,而且 11,000 个类很大。)

  • 听起来您可能正遭受经典 VCS 系统的“分支难”问题。

  • 听起来您可能需要更强大的 CI 系统。如果你有更多的内核并且构建框架是正确的,你应该能够获得更快的 CI 构建。 (如果你模块化以便重建更少......)

我认为以这种方式解决缓慢的构建/测试周期可能比通过额外的(可能是定制的)工具进行依赖性分析更容易。

但我知道,这些决定可能不取决于您。

【讨论】:

  • 我正在尝试更好地捕捉错误它们到达 Jenkins。
  • 嗯……你有没有考虑过使用 Jenkins 来构建你的开发分支?可能需要更强大的 CI,但硬件比开发人员的时间更便宜,尤其是如果硬件由 10 个开发人员共享。
  • 另一点是你可以在你的桌面上进行并行 Maven 构建,假设它有一点咕噜声。 (这些天你可以以大约 1000 美元的价格买到一台 4 核 / 16Gb 机器……假设你在 A 的美国。)
  • 我实际上一直在考虑设置一组 POM,但我没有解决它,因为我知道当你不遵循它的要求时 mvn 会给你带来多大的麻烦 wrt 目录布局,以及什么时候寻找如何做到这一点的大多数答案往往是“f *** you, do it Maven's way”
  • 更好的描述是“不要让自己的生活变得地狱。按照 Maven 的方式去做”。代码库重组是一次性成本,如果您使用的是体面的 VCS,它不会破坏您的历史记录。是的,这都是额外的工作,但要考虑回报。
猜你喜欢
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-25
  • 1970-01-01
  • 2012-05-16
  • 1970-01-01
相关资源
最近更新 更多