假设我们有一组项目“p1.jar”、“p2.jar”等,它们都使用库“foo-1.0.0.jar”。
假设创建了一个新版本“foo-1.0.1.jar”。作为附加检查,所有项目 p1、p2、...都使用新的 foo-1.0.1.jar 重新编译。没有出现编译错误。
现在,在生产环境中,foo-1.0.0.jar 被替换为 foo-1.0.1.jar。没有完成 p1.jar、p2.jar 等更新。不幸的是,一切都崩溃了。
是否可以做一些其他检查以 100% 确定新库可以替换旧库?
显然,我们不是在谈论检查新库中引入的代码错误或功能更改(例如,如果在新版本中函数“sum”执行减法而不是加法)。但至少要检查参数、结果、可用类等方面的变化。
一个例子是,foo-1.0.0.jar 包含方法:
int m1() {
// some code
return 0; // always return 0, and ignored by the users
}
在 foo-1.0.1 中它被更改为:
void m1() {
// some code
}
不幸的是,该方法的结果是 Java 中名称重整的一部分(不是 C 中的),并且 p1.jar 在查找“int m1()”时将失败并出现“NoSuchMethod”异常。
最佳答案
您可能会使用 japicmp比较新旧库存档以了解 API 更改。
但是仍然存在您检查的库的依赖项不会被检测到的风险。
在下面找到一个示例来演示可能未检测到的更改。
ApiClass1.java
class ApiClass {
public static final int FOO = 23;
public static void version() {
System.out.println("version 1 FOO: " + FOO);
}
}
ApiClass2.java
class ApiClass {
public static final int FOO = 42;
public static void version() {
System.out.println("version 2 FOO: " + FOO);
}
}
ApiDemo.java
class ApiDemo {
public static void main(String...args) {
ApiClass.version();
System.out.println("ApiClass.FOO: " + ApiClass.FOO);
}
}
为 API 版本 1 编译和构建库
javac ApiClass1.java jar cf api_v1.jar ApiClass.class
为 API 版本 2 编译和构建库
javac ApiClass2.java jar cf api_v2.jar ApiClass.class
使用 API v1 编译、构建和运行您的代码
javac -cp api_v1.jar ApiDemo.java java -cp api_v1.jar:. ApiDemo
输出
version 1 FOO: 23 ApiClass.FOO: 23
使用 API v2 运行您的代码,无需重新编译
java -cp api_v2.jar:. ApiDemo version 2 FOO: 42 ApiClass.FOO: 23
唯一可靠的方法是针对新版本编译代码,运行所有单元/集成测试并检查它们是否通过。
关于java:检查 jar 版本之间的兼容性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40589431/