8

我希望能够比较一个类/库的两个版本,以确定是否有任何更改可能会破坏调用它的代码。例如,考虑一些在版本 a 中具有方法的类 Foo:

public String readWidget(Object widget, Object helper);

在版本 b 中,该方法变为:

public String readWidget(Object widget); //removed unnecessary helper object

或在字段的情况下类似的东西:

version a: public static Object sharedFoo;
version b: static Object sharedFoo; //moved to package private for version b

我想要一个将这些更改标记为潜在不兼容性的工具(但理想情况下不是相反,即增加方法的可见性)。现在我知道我可以通过反射或分析 javap 的输出来做到这一点,但是似乎应该有一个现有的工具(最好是非商业的)。所以我想看看是否有人可以推荐一些东西,然后再犯下自己动手/不必要地重新发明轮子的错误。

4

3 回答 3

3

我可能不理解这个问题,但编译器不是解决这个问题的确切工具吗?

如果有任何不兼容,重新编译使用Foo新版本的类Foo将很快阐明。

于 2011-03-24T13:44:07.873 回答
2

Guava 使用JDiff报告版本变化,也许你也觉得它有用?

于 2011-03-24T13:49:47.710 回答
2

这是您不想要的答案,但我认为这是一个有效的答案:

  1. 编写一套单元测试来调用你的 API 的每一个方法(你已经有了这个,对吧?:-))。
  2. 当您进行 API 更改时,重新编译 API 的新版本,而不是单元测试。
  3. 针对“新鲜”API 运行“陈旧”的单元测试集。这套陈旧的测试变成了金丝雀,模仿了 API 客户端所处的情况。

仅重新编译所有客户端代码第一个问题是它可能是不可能的。该代码可能不属于您;它可能是您的一位客户编写的自定义代码,您无法使用。

仅重新编译客户端代码的第二个问题是,有时您甚至不会收到编译错误,因为不需要更改调用代码。我曾经遇到过这样的问题。我有一个这样的 API 方法:

public void doSomething(){
}

与链接到它的代码。我想把它改成这样:

public boolean doSomething() {
}

所以我这样做并重新编译。没有错误,因为调用第一个版本的代码doSomething()默默地重新链接到新版本(丢弃返回值,这在 Java 中有效)。然而,我几乎不知道,当我重新编译时,它确实改变了外部类的字节码。我们开始在 API 更新但使用它的代码没有重新编译时遇到错误。

因此,与其寻找错误,我还应该查看哪些外部文件的字节码因此而改变。那时,我会说您应该为此目的使用单元测试,因为无论如何您都应该编写它们。

于 2011-03-24T15:25:50.290 回答