java:检查 jar 版本之间的兼容性

标签 java jar compatibility

假设我们有一组项目“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/

相关文章:

java - GWT 1.7 - 在 Jetty 中配置数据源(托管模式)

java - hibernate "IllegalArgumentException occurred calling getter"

java - 无法使用批处理文件执行java程序

java - 即使 JAR 包含在 list 类路径中,也会出现 NoClassDefFoundError

Java x86 与 Java ARM 兼容吗?

ios - XCode 8 位码兼容性

java - SmartGWT Img 设置应用程序外的路径

java - 王牌 :chart how to set xAxis tick with AxisType:DATE

java - 如何从打包到它自己的 .jar 中的 java 库访问资源

c++ - 在同一项目中混合使用 C++ 风格