如何静态识别 JAR 中缺少的方法(二进制兼容性)
-
19-09-2019 - |
题
我想验证 2 个 JAR 之间的二进制兼容性。
按照本中的建议 回答 我用了 jboss 告密者 但它只能找到缺失的类。
如何查找是否缺少方法?有可能吗?
例如。
“取决于”类 Foo 依赖于 Bar(像许多其他中产阶级工人一样)
import org.overlyusedclassnames.Bar
public class Foo{
public void someMethod(){
Bar tender = new Bar();
tender.getJohnnyRedLabel();
tender.getJohnnyBlueLabel(); //this method is new in the Bar class
}
}
“编译时”类
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);
}
}
现在想象一个 老的 Bar jar 意外地替换了编译时间 bar:
“运行时”类
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 个答案与主题完全无关。
解决方案
japi 合规性检查器 - 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
其他提示
克利尔 - 检查 Java 库与旧版本的二进制和源代码兼容性:
java -jar clirr-core-0.6-uber.jar -o OLD.jar -n NEW.jar
瑞瓦皮 也能完成这项工作。将它合并到 Maven 构建中很容易,这显然不是您的情况,但其他人可能会感兴趣。
它还可以使用其独立模式检查任意的 jar 集。
japicmp 是另一个检查二进制兼容性的工具。它可以作为独立的命令行工具或 Maven 插件使用。
有一个工具叫 动物嗅探器 允许您提取 API 的签名。然后,它可以静态验证 API 的用户是否遵守签名,并且可以静态验证 API 的实现者是否已实现所有内容。我认为这会很好地解决你的问题。
您可以从 codehaus maven 存储库下载 Animal Sniffer 的 jar:http://repo1.maven.org/maven2/org/codehaus/mojo/animal-sniffer/
您是否需要一个来检查特定类或用于比较 jar 的通用工具?如果是 1 个类,只需在自定义类加载器中加载该类,然后使用反射检查方法签名即可。如果您需要许多 JAR/类,这将是太多的工作。