在方法签名/字段中查找不兼容性的工具

时间:2011-03-24 12:44:57

标签: java field compatibility method-signature

我希望能够比较类/库的两个版本,以确定是否有任何可能会破坏调用它的代码的更改。例如,考虑一下在版本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的输出来做到这一点,但是看起来应该有一个现有的工具(最好是非商业的)。所以我想看看是否有人可以推荐一些东西,然后再犯了我自己的错误/不必要地重新发明轮子。

3 个答案:

答案 0 :(得分:3)

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

如果存在任何不兼容性,则会针对新版本的Foo重新编译使用Foo的类会很快显示。

答案 1 :(得分:2)

Guava使用JDiff报告version changes,也许你会觉得它很有用?

答案 2 :(得分:2)

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

  1. 编写一套单元测试来调用API的每一种方法(你已经有了这个,对吧?: - )。)
  2. 进行API更改时,请重新编译新版API,而不是单元测试。
  3. 针对“新鲜”API运行“陈旧”单元测试集。这套陈旧的测试变成了一个金丝雀,模仿了API客户端的情况。
  4. 重新编译所有客户端代码第一个问题是它可能无法实现。代码可能不属于您;它可能是您的一位客户已编写但无法使用的自定义代码。

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

    public void doSomething(){
    }
    

    使用与之关联的代码。我想把它改成这个:

    public boolean doSomething() {
    }
    

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

    因此,我不应该查找错误,而应该查看哪些外部文件的字节码因此而更改。那时,我会说你应该只是为了这个目的使用单元测试,因为无论如何你应该写它们。