gpt4 book ai didi

java - 确保每个 JAR 首先看到自己的类路径资源

转载 作者:行者123 更新时间:2023-12-01 12:48:42 25 4
gpt4 key购买 nike

假设我的类路径上有 2 个 jar

JAR1:

Class1.class
resource.xml

JAR2:

Class2.class
resource.xml

类Class1和Class2使用类路径资源(每个JAR提供自己的resource.xml并想要读取它)。

在我的应用程序中,我使用这两个 jar,并且当加载 Class1 或 Class2 时,加载的 resources.xml 是随机的(两者之一)。

是否有可能 Class1 始终加载其 resources.xml 而 Class2 始终加载其自己的资源?

最佳答案

我认为不可能完全按照你的意愿去做。

<小时/>

让我们从一些关于类加载器和资源加载如何工作的事实开始

  1. 当您调用 Class.getResource() 时,它会变成对 Class.getClassloader().getResource() 的调用。

    <
  2. 每个类都有一个类加载器。

  3. 每个类加载器只有一个父类加载器。

  4. 类加载器的构造方式确保类加载器形成严格的树,所谓的引导类加载器位于树的根部。

  5. 类加载器可以使用两种策略之一来查找内容:

    • 先询问父类加载器,然后检查该类加载器的资源,
    • 首先检查该类加载器的资源,然后询问父类加载器。

现在,为了便于讨论,让我们考虑这个例子:

JAR1:

Class1.class
resource.xml
resource1.xml

JAR2:

Class2.class
resource.xml
resource2.xml

所以让我们考虑如何将它们组合在一起:

  • 如果 JAR1 和 JAR2 具有相同的类加载器,则该类加载器无法知道应首先搜索哪个 JAR。类加载器上的 getResource() 调用不知道原始类是什么。

  • 假设 JAR1 和 JAR2 有不同的类加载器:

    • 如果 JAR2 的类加载器是 JAR1 的父类加载器,那么它可以委托(delegate)给 JAR2,但 JAR2 的类加载器不能委托(delegate)给 JAR1。如果我们调用 Class2.class.getResource("resource1.xml"),Class2 的类加载器将无法委托(delegate)给了解“resource1.xml”的类加载器,并且加载将会失败。

    • 如果你翻转它并使 JAR1 的类加载器成为 JAR2 的父类加载器,那么我们会发现 Class1.class.getResource("resource2.xml") 将会失败。

  • 假设我们创建了 2 个类加载器,它们都知道 JAR1 和 JAR2,并且没有委托(delegate)给对方。第一个类加载器可以在 JAR1、JAR2、父级中查找资源,第二个类加载器可以在 JAR2、JAR1、父级中查找资源。

    到目前为止还好。但是类加载呢?在这里我们必须非常小心。我们不能允许出现 Class1.class 可能被两个类加载器加载的情况。因为如果发生这种情况,您最终会得到两个具有相同完全限定名称和不同类加载器的加载类型。但 Java 类型系统表示,这给了我们两种不同类型……并且这很容易导致意外的ClassCastExceptions。因此,我们必须确保两个各自的类加载器不会都加载同一个类。

    但这会导致另一个问题。如果要求第一个类加载器查找只有另一个类加载器可以加载的类,那么它就无法委托(delegate)给它......最终结果将是您将收到“找不到类”错误或异常。

<小时/>

总之,我认为我已经涵盖了所有合理的类加载器结构……但它们都不适用于我提出的示例。

也许可以“打破规则”并建立一个有效的非树结构类加载器委托(delegate)网络;例如通过使用后门来告诉两个类加载器彼此的信息。但是,存在最终出现委托(delegate)循环的风险……这将导致“无限”递归。即使这有效,也存在其他潜在风险;例如Java 沙箱安全模型也依赖于类加载器的工作。

别去那里。寻找另一种方法来做到这一点;例如对两个版本的“resource.xml”使用不同的名称。

关于java - 确保每个 JAR 首先看到自己的类路径资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24427816/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com