【问题标题】:How can we progrmatically find if a java class has been modified?我们如何以编程方式查找 java 类是否已被修改?
【发布时间】:2020-04-25 13:57:08
【问题描述】:

除了反射之外,有没有一种方法可以识别java类是否被修改(字段)。我们的应用程序中有数千个类。我们需要进行一些测试,以检测 Java 类是否已被开发人员修改 - 在添加字段或更改访问修饰符或更改类型等方面。

反射不起作用,因为我们有 100 多个要跟踪的类?

鉴于我们将 java 类文件作为 bytea 类型的 postgres 存储在 db 中,是否有可靠的方法可以可靠地计算某种哈希?

【问题讨论】:

  • 如何检查源代码管理中相关文件的更改?
  • 等等...您正在数据库中存储已编译 Java 类的二进制图像?这是一种常见的做法吗?
  • @JimMischel 这完全是一个不同的讨论:-) 让我们不要讨论它。我更感兴趣的是,鉴于我可以访问源 java 文件的点类文件,我需要从点类文件中找出源 java 文件被更改的情况。我假设 java 源文件中的任何更改都会导致点类文件被更改。现在,我如何使用我的 dot 类文件来检测是否发生了更改
  • @M.Shashanka 现在是您的问题:对 java 源代码的更改是否总是会导致不同的字节码?我几乎可以肯定已经有一个问题和答案了。
  • @khelwood 该选项对我们来说不可行。我们想构建一些自动化功能,在将更改签入存储库之前检测更改

标签: java hash md5 checksum crc


【解决方案1】:

反射假设您可以加载类;即它们的依赖项可用。

另一种方法是使用 Apache BCEL (http://commons.apache.org/proper/commons-bcel/) 或 ASM (https://asm.ow2.io/) 库。除了检查字段和方法签名之外,这些还允许您检查甚至修改方法的字节码。

最后,解析javap 的输出是可行的,尽管这种方法很脆弱。未指定javap 输出格式,它可以从一个Java 版本更改为下一个Java 版本。


我刚刚意识到我的要求发生了变化——我需要检测我的 java 类中方法内部的任何业务逻辑变化。

检测逻辑更改的唯一方法是比较方法的字节码(或字节码的哈希值)。这将对所使用的字节码编译器敏感,并且还会对许多不影响方法语义的代码更改给出误报。做得比这更好可能是不可行的......除非你愿意在这个问题上花费很多人年。

【讨论】:

  • 谢谢斯蒂芬!我刚刚意识到我的要求已经改变了——我基本上需要检测我的 java 类中的方法内的任何业务逻辑更改,而不仅仅是字段、accessmodifiers——请注意,我不能依赖源 java 文件来检测更改。本质上,它就像 java 文件中的任何更改都可以更改输出。
  • 您似乎别无选择,只能使用数据库中类的二进制表示形式的校验和(例如 SHA 哈希)。这就是诸如 Git 之类的源代码控制软件的工作方式:它计算校验和和差异。话虽如此,您的问题主要是由于架构不好。变更管理通常在源代码级别完成,而不是针对二进制工件。下一个“询问”将是真正找到差异,这就是你会碰壁的地方:两个类文件的二进制差异对于普通人来说没有多大意义。
  • @anttix 这些二进制表示的类(本质上是点类文件)是否对 java 编译器版本敏感?换句话说,对于给定的源 java 文件,当使用不同的 jdk 版本运行时,我们是否可以有不同的二进制表示形式 - 如果是这种情况,校验和在这里可能没有帮助..
  • 这是一个完全不同的问题。是的,他们是:stackoverflow.com/questions/14984984/… 这是我说的墙。任何比仅仅检测字节码是否改变更高级的东西都需要一种从二进制文件中重建源代码的方法。对不起,兄弟,但源代码管理没有替代品。如果您需要确定 source 是否已更改,则需要跟踪 source 的更改。简单!
猜你喜欢
  • 1970-01-01
  • 2013-04-21
  • 1970-01-01
  • 2023-04-06
  • 2010-12-08
  • 1970-01-01
  • 2013-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多