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

发布于 2024-10-26 08:18:43 字数 604 浏览 2 评论 0原文

我希望能够比较类/库的两个版本,以确定是否存在任何可能破坏调用它的代码的更改。例如,考虑一些 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

西瓜 2024-11-02 08:18:43

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

如果存在任何不兼容的情况,针对新版本的 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 of Foo will illuminate very quickly if there are any incompatibilities.

死开点丶别碍眼 2024-11-02 08:18:43

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

Guava uses JDiff to report version changes, maybe you can find it useful, too?

寂寞美少年 2024-11-02 08:18:43

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

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

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

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

public void doSomething(){
}

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

public boolean doSomething() {
}

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

因此,我不应该寻找错误,而应该查看哪些外部文件的字节码因此发生了更改。那时,我想说您应该仅使用单元测试来实现此目的,因为无论如何您都应该编写它们。

Here's the answer you didn't want, but I think it's a valid answer:

  1. Write a suite of unit tests that invoke every single method of your API (you already have this, right? :-)).
  2. When you make an API change, recompile the new version of your API but not the unit tests.
  3. Run the "stale" set of unit tests against the "fresh" API. This stale set of tests become a canary, mimicking the situation that clients of your API would be in.

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:

public void doSomething(){
}

with code that linked against it. I wanted to change it to this:

public boolean doSomething() {
}

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文