用于查找方法签名/字段中不兼容性的工具
我希望能够比较类/库的两个版本,以确定是否存在任何可能破坏调用它的代码的更改。例如,考虑一些 Foo 类,它在版本 a 中有一个方法:
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 的输出来做到这一点,但是似乎应该有一个现有的工具(最好是非商业的)。所以我想看看是否有人可以推荐一些东西,以免我犯下不必要的自己动手/重新发明轮子的错误。
I would like to be able to compare two versions of a class / library to determine whether there have been any changes that might break code that calls it. For example consider some class Foo that has a method in version a:
public String readWidget(Object widget, Object helper);
and in version b the method becomes:
public String readWidget(Object widget); //removed unnecessary helper object
or something similar in the case of a field:
version a: public static Object sharedFoo;
version b: static Object sharedFoo; //moved to package private for version b
I would like a tool that will flag these changes as potential incompatibilities (but ideally not the reverse i.e. increasing the visibility of a method). Now I know that I can do this via reflections, or by analyzing the output from javap, however it seems like there should be an existing tool (preferably non-commercial). So I wanted to see if anyone can recommend something before I make the mistake of rolling my own / reinventing the wheel unnecessarily.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我可能不理解这个问题,但是编译器不是解决这个问题的确切工具吗?
如果存在任何不兼容的情况,针对新版本的
Foo
重新编译使用Foo
的类将会很快发现问题。I might not be understanding the question, but isn't the compiler the exact tool that would solve this problem?
Re-compiling the classes that use
Foo
against the new version ofFoo
will illuminate very quickly if there are any incompatibilities.Guava 使用 JDiff 报告 版本更改,也许你也觉得它有用?
Guava uses JDiff to report version changes, maybe you can find it useful, too?
这是您不想要的答案,但我认为这是一个有效的答案:
仅重新编译所有客户端代码的第一问题是,它可能不会可能的。该代码可能不属于您;它可能是您的一位客户编写的自定义代码,但您无法使用。
仅重新编译客户端代码的第二个问题是,有时您甚至不会收到编译错误,因为不需要更改调用代码。我曾经遇到过这样的问题。我有一个像这样的 API 方法:
带有与其链接的代码。我想把它改成这样:
所以我这样做了并重新编译。没有错误,因为调用第一个版本的
doSomething()
的代码默默地重新链接到新版本(丢弃返回值,这在 Java 中是有效的)。然而,我几乎不知道,当我重新编译时,它确实改变了外部类的字节码。我们开始收到 API 已更新但使用它的代码未重新编译的错误。因此,我不应该寻找错误,而应该查看哪些外部文件的字节码因此发生了更改。那时,我想说您应该仅使用单元测试来实现此目的,因为无论如何您都应该编写它们。
Here's the answer you didn't want, but I think it's a valid answer:
The first problem with just recompiling all client code is that it might not be possible. The code might not belong to you; it might be custom code that one of your customers has written and is not available to you.
The second problem with just recompiling client code is that sometimes, you won't even get a compilation error because the calling code doesn't need to be changed. I ran into a problem like this once. I had an API method like this:
with code that linked against it. I wanted to change it to this:
So I did so and recompiled. There were no errors, because the code that called the first version of
doSomething()
silently relinked to the new version (discarding the return value, which is valid in Java). Little did I know, however, that it did change the bytecode of the external class when I recompiled. We started to get errors where the API was updated but the code using it wasn't recompiled.So instead of looking for errors, I should have also been looking at which external files had their bytecode changed as a result. At that point, I'd say you should just be using unit tests for this purpose since you should be writing them anyhow.