Java 如何静态地识别JAR中缺少的方法(二进制兼容性)

Java 如何静态地识别JAR中缺少的方法(二进制兼容性),java,jar,static-analysis,bytecode,binary-compatibility,Java,Jar,Static Analysis,Bytecode,Binary Compatibility,我想验证两个JAR之间的二进制兼容性 按照本文中的建议,我使用了,但它只能找到缺少的类 如何查找是否缺少方法?有可能吗 例如 “依赖于”阶级Foo依赖于酒吧(和许多其他中产阶级工人一样) 编译时类 package org.overlyusedclassnames; /** * @Since 1992 * Changes: added blue and gold Johnny Walker labels */ public class Bar { public Drink ge

我想验证两个JAR之间的二进制兼容性

按照本文中的建议,我使用了,但它只能找到缺少的类

如何查找是否缺少方法?有可能吗

例如

“依赖于”阶级Foo依赖于酒吧(和许多其他中产阶级工人一样)

编译时类

package org.overlyusedclassnames;

/** 
 * @Since 1992
 * Changes: added blue and gold Johnny Walker labels
 */

public class Bar {
    public Drink getJohnnyRedLabel(){
         return new JohnyWalkerFactory.get(RedLabel.class);
    }

    public Drink getJohnnyBlackLabel(){
         return new JohnyWalkerFactory.get(BlackLabel.class);
    }

    public Drink getJohnnyGoldLabel(){
         return new JohnyWalkerFactory.get(GoldLabel.class);
    }

    public Drink getJohnnyBlueLabel(){
         return new JohnyWalkerFactory.get(BlueLabel.class);
    }

}
package org.overlyusedclassnames;

/** 
 * @Since 1909
 * Changes: added red and black Johnny Walker labels
 */

public class Bar {
    public Drink getJohnnyRedLabel(){
         return new JohnyWalkerFactory.get(RedLabel.class);
    }

    public Drink getJohnnyBlackLabel(){
         return new JohnyWalkerFactory.get(BlackLabel.class);
    }
}
现在想象一个旧的条jar正在不断地替换编译好的时间条:

“运行时”类

package org.overlyusedclassnames;

/** 
 * @Since 1992
 * Changes: added blue and gold Johnny Walker labels
 */

public class Bar {
    public Drink getJohnnyRedLabel(){
         return new JohnyWalkerFactory.get(RedLabel.class);
    }

    public Drink getJohnnyBlackLabel(){
         return new JohnyWalkerFactory.get(BlackLabel.class);
    }

    public Drink getJohnnyGoldLabel(){
         return new JohnyWalkerFactory.get(GoldLabel.class);
    }

    public Drink getJohnnyBlueLabel(){
         return new JohnyWalkerFactory.get(BlueLabel.class);
    }

}
package org.overlyusedclassnames;

/** 
 * @Since 1909
 * Changes: added red and black Johnny Walker labels
 */

public class Bar {
    public Drink getJohnnyRedLabel(){
         return new JohnyWalkerFactory.get(RedLabel.class);
    }

    public Drink getJohnnyBlackLabel(){
         return new JohnyWalkerFactory.get(BlackLabel.class);
    }
}
是否有一种方法可以识别缺少的方法,而无需运行它并获取
NoSuchMethodError



免责声明:这是我自己的一次重大改写,不可否认。我选择问一个新问题,因为重新措辞会使当前的2个答案与主题完全无关。

有一个名为的工具,允许您提取API的签名。然后,它可以静态地验证API的用户是否坚持签名,并且可以静态地验证API的实现者是否实现了所有内容。我想这会很好地解决你的问题

您可以从codehaus maven存储库下载动物嗅探器的jar:

您需要检查特定类或通用工具来比较jar吗? 如果是一个类,只需在自定义类装入器中装入该类,使用反射检查方法签名,就可以了。如果许多JAR/类都需要它,这将是一项非常繁重的工作。

-检查Java库与旧版本的二进制和源代码兼容性:

java -jar clirr-core-0.6-uber.jar -o OLD.jar -n NEW.jar java-jar-clirr-core-0.6-uber.jar-o OLD.jar-n NEW.jar-java库的向后API/ABI兼容性检查器:

japi-compliance-checker -lib NAME -old OLD.jar -new NEW.jar

-Oracle的SigTest签名测试和API一致性工具

-测试Java API之间的兼容性

-在二进制级别工作的java API向后兼容性检查器

-API分析和变更跟踪工具

或者手动使用javap反编译器:

javap OLD.class > OLD.txt javap NEW.class > NEW.txt diff -rNau OLD.txt NEW.txt > CHANGES.txt javap OLD.class>OLD.txt javap NEW.class>NEW.txt diff-rNau OLD.txt NEW.txt>CHANGES.txt 我也能做这项工作。很容易将其合并到maven构建中,这显然不是您的情况,但其他人可能会感兴趣


它还可以使用独立模式检查任意JAR集。

是检查二进制兼容性的另一个工具。它可以作为独立的命令行工具或maven插件提供。

您可以对另一个问题发表意见,认为它应该关闭,超级用户可以关闭它以供使用you@Yoni-已经做到了“不运行它”==“静态地”(在问题的标题中)@developer您是否要求编辑该问题?“不运行它”对我来说似乎很清楚。@Michael-不,我只是想提醒问题作者和读者注意这个词的流行同义词,以便将来更高效地进行谷歌搜索。@Michael-你找到下载链接了吗?它隐藏在哪里?该工具是由Maven人员编写的,所以我认为他们只是使用各种Maven存储库,这在Maven中很容易。不幸的是,在“ant”中不太容易。我还没有测试过它,但这是目前为止最好的答案,我会在尝试后添加一条评论。谢谢,顺便问一下,为什么有两个不同的答案?@EranMedan Hm,不记得原因=)你好!伙计们,我可以举一个小例子。i、 在哪个基础上进行比较。如何在屏幕中获取所有调试详细信息?@野餐4U-使用
japi compliance checker
工具的附加
--debug
选项生成中间javap输出到
debug/
子目录。非常感谢,现在我已经获得了1.1.2版本的所有详细信息。别忘了透露您与项目或项目的关联你在帖子中提到的博客。请添加适当的信息以披露此类答案的数量。此外,如果你推荐一个工具或库,那么你应该展示如何应用它。该项目没有任何“可下载内容”-或者,我在他们的主要网站上找不到链接。下载部分现在位于改进后的网站上: