【问题标题】:Replace jar and redirect import statements替换 jar 并重定向导入语句
【发布时间】:2020-05-12 20:47:25
【问题描述】:

我们有一个依赖于特定库的 Java 程序。我们创建了第二个库,其 API 与第一个库非常相似,但是,这个库是内部制作的,我们已准备好开始对其进行测试。

为了测试,我们想用我们新库的 jar 替换 Java 程序中的 jar。问题是新库没有完全相同的命名空间,因此导入语句不会对齐。例如,

Java 程序

import someLibrary.x.y.Foo;

public class Main {
    public static void main(String[] args){
        new Foo().bar();   
    }
}

新库具有相同的 API 但不同的命名空间

anotherLibrary.x.y.Foo;

问题:如何使用类加载器或其他工具来运行 Java 程序但替换依赖项并将导入语句重定向到另一个命名空间?

[编辑] - 我们无权访问 Java 程序的源代码。我们可以更改此程序以使用我们的新库,但在彻底测试之前我们不想这样做。

【问题讨论】:

  • 如果您创建了第二个库,而您只需要其中一个,那么将您自己的库的包重命名为正确的包名不是更容易吗?
  • 编写一个程序/脚本,可以扫描所有文件并用新文件替换旧文件。

标签: java api jar classloader


【解决方案1】:

我能想到的唯一解决方案是编写一个自定义ClassLoader,它会更改字节码以更改方法引用和字段引用以更改类名。

【讨论】:

    【解决方案2】:

    直接的解决方案怎么样:

    1. 创建主程序的分支(在 git 或您使用的任何源代码控制工具中):
    2. 应用使用新库所需的所有更改(更改所有导入)
    3. 在测试环境中部署并广泛测试
    4. 当您有足够的信心时,合并回大师

    另一种解决方案可能是:

    1. 从新库中创建一个分支
    2. 更改导入,使其看起来与旧版本完全相同(包含所有软件包)
    3. 在您的应用程序中用新库替换旧库
    4. 在测试环境中部署并广泛测试
    5. 当您准备好将新库部署到生产环境并在一个月的宽限期内继续在生产环境中工作(直到您真正有信心为止)
    6. 在一个月内改回所有导入(基本上从具有“旧”导入的分支转移到在库和应用程序中具有真正导入的分支。

    更新

    如果您使用 maven,也可以自动重新定位您的库版本的包。

    Maven shade 插件具有relocate 目标,可用于“重新定位”您的库的包,就像现有库的包一样。见shade plugin's documentation

    【讨论】:

    • 解决方案 1 不起作用,因为我们无权访问 Java 程序的源代码。解决方案 2 可行,但我们希望避免这种情况。
    • 我没有意识到您无权访问应用程序的源代码,抱歉。我已经用一个也可以为您工作的附加选项更新了答案。
    猜你喜欢
    • 2022-10-22
    • 2019-08-31
    • 1970-01-01
    • 2017-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多