【问题标题】:What is an isolated classloader in Java?什么是 Java 中的隔离类加载器?
【发布时间】:2012-03-06 00:26:38
【问题描述】:

在尝试解决this problem的时候,遇到了一些文章等提到“孤立”的ClassLoaders。我无法通过 Google 搜索找到 isolated classloader 的定义,因此该术语可能不是广为人知的行话,并且在不同的上下文中可能具有不同的含义。

无论如何,Maven 的 surefire 插件可以使用隔离的 ClassLoader:http://maven.apache.org/plugins/maven-surefire-plugin/examples/class-loading.html

下面的答案之一也是参考an article explaining how to create an "isolated" ClassLoader

以上参考都没有给出隔离类加载器的定义;他们似乎假设读者知道这意味着什么或可以查找它。但是,第二个链接确实包含关于“孤立”的含义的提示:

引导程序可让您在不污染系统类路径的情况下运行容器。这允许您以未污染的系统类路径作为其父级来运行已部署的应用程序。 您已实现类加载器隔离。

但我不太清楚本段或文章其余部分的内容和方式是什么。我看到他正在加载一个类的一个版本而没有覆盖/覆盖另一个版本——也许一个类加载器与另一个类加载器是不同的实例,而一个是另一个的父级?我不知道。

我特别渴望包含明确包含答案的链接的 Google 或 SO 搜索链接。直接链接到答案也有效。 :)

【问题讨论】:

  • 请提供一个链接或引用来说明您的问题。 (顺便说一句,贪婪不是罪吗?:-))
  • @Stephen:如果你进来时把你的宗教狂热留在外面,我们将不胜感激。
  • 嗯,我们从 Larry Wall 那里知道,程序员的三大美德是懒惰、急躁和狂妄,既然贪婪不是美德,那它一定是一种罪过。所以你去。
  • @MattiVirkkunen - 我可以建议你查一下“:-)”是什么意思。也许您需要拒绝自己的反宗教狂热设置。
  • @StephenC 我用上下文更新了我的问题。

标签: java classloader


【解决方案1】:

作者使用术语“隔离”基本上是指 JVM 的引导类加载器(“主”类加载器)中没有任何额外的 jars/类(只有一个简单的类反过来设置子类加载器)。这篇文章并不清楚为什么这是“孤立的”,因为它只设置了一个子类加载器。当您设置多个子类加载器时,“隔离”一词变得更加明显。这些孩子将彼此隔离,因为它们不会共享任何类(核心 JRE 类除外)。因此,您可以做一些事情,比如让每个孩子使用同一个 jar 的不同版本。

【讨论】:

  • 例如:classloader1 = new URLClassLoader(oneUrl, parent); classloader2 = new URLClassLoader(anotherUrl, parent);将创建 2 个与 ea 隔离的类加载器。其他,每个都可以拥有给定类的不同版本(并且可能有其他用途),对吗?
  • @apollodude217 - 是的,这是正确的。不过,关键是 oneUrl 和 anotherUrl 都不应引用由父类加载器加载的类(因此该示例运行主类加载器而没有额外的 jar)。
【解决方案2】:

这里是how to create an isolated classloader,您可以随时创建一个未污染的系统类路径,这对于引导 Java 程序很有用。

【讨论】:

  • 这实际上是我在尝试查找什么是隔离类加载器时阅读的文章之一,从上下文中我不清楚它是什么。我看到作者在做什么,但我不知道是哪一部分让他的类加载器“孤立”。
【解决方案3】:

根据我对您链接到的文章的理解,隔离类加载器是与主系统类加载器分开的类加载器。也就是说,由独立类加载器加载的类不会对 JRE 中的每个类都可用(只有独立类加载器自身加载的类[以及由任何子类加载器加载的任何类])。

这可能很有用,因为您的两个依赖项可能需要运行同一库的不同版本。也就是说,您的依赖项可能希望在库中看到同一类的不同实例化。因此,给他们两个独立的隔离类加载器将允许他们加载他们需要的类并且不会相互干扰。

【讨论】:

    【解决方案4】:

    默认情况下,类加载器以系统类加载器为根形成一棵树。默认情况下,新的子类加载器会先询问其父类是否可以加载该类,如果不能,则从他们自己的源加载。

    隔离类加载器的目标是将自己与父类加载器隔离开来,首先检查您自己的源,然后检查您的父类加载器,因此颠倒顺序。这允许您创建一个新的类加载上下文,您可以在其中控制首先查看的位置。您仍然希望回退到父链,以便加载 jdk 等内容。

    您还需要注意隔离类加载器返回父类加载器中定义的接口实例,否则您将遇到 LinkageErrors 或其他问题。

    这是我在 2006 年写的一篇文章,但它仍然相当相关(它在资源加载方面并不完整,并且这些年来 API 发生了一些变化):

    http://tech.puredanger.com/2006/11/09/classloader/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-08
      • 1970-01-01
      • 2021-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多