【问题标题】:Application wide custom ClassLoader应用范围的自定义 ClassLoader
【发布时间】:2014-10-05 19:43:01
【问题描述】:

我有一个自定义 URLClassLoader,它从正常类路径之外的 jar 文件加载几个类。到目前为止,一切顺利。

我的问题是,当我需要由我的 ClassLoader 加载的类时,我不能每次都调用这个 ClassLoader,因为这些类可能被第三方库使用。出于这个原因,我通过反射将类添加到当前的 Thread ClassLoader:

    ProtectionDomain pd = getClass().getProtectionDomain();
    final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    final java.lang.reflect.Method clM = ClassLoader.class.getDeclaredMethod("defineClass", Class.class);         
    clM.invoke(classLoader, className, byteContent, 0, byteContent.length, pd);

但是当调用该线程类加载器中的 findClass 并且我还没有添加所请求的类时,我得到了 NoClassDefFoundException。当然。

我现在的问题是,有没有办法将我的 ClassLoader 放入我的应用程序的全局类加载链中?无法为系统 ClassLoader 使用 Java 选项,因为我的 ClassLoader 可以包含在 Web 应用程序中并部署为 war 文件。我也尝试过使用Thread.currentThread().setContextClassLoader(),但是一旦创建了一个新线程,它当然没有我的 ClassLoader 设置。

我在网上搜索了几天,但找不到任何解决方案。

感谢您的帮助和任何建议。

最好的问候, 格里

【问题讨论】:

  • 您可以将自定义类加载器的父类加载器设置为系统类加载器。这将使它成为类加载器层次结构的一部分。我已经实现了类似的东西;但我不确定你是否准确地解释了你的问题

标签: java multithreading classloader


【解决方案1】:

并非如此,特别是如果您希望它与作为 Web 应用程序运行兼容。

您需要在这里解决多个问题。允许 Web 容器在安全管理器下运行您,这将使您的代码无法工作(即,它们可以禁止访问文件系统和/或禁止创建类加载器)。 Java 旨在允许安全加载移动代码(它最初的目标是有线机顶盒),因此您可以想象应用程序动态修改系统类加载器的能力并不是其中的一部分架构。

对于应用程序,您应该做的是 (1) 将用于加载这些类的 JAR 文件放入系统类路径中,或者 (2) 加载您的 应用程序在自定义类加载器中,然后让该自定义类加载器加载您的类(基本上与您现在的方式相同)。在同一个类加载器中加载第三方库。现在你会没事的,不管你所说的“可能被第三方库使用”是什么意思(这让我很困惑,我不确定他们可能使用什么技术,这很重要)。

对于 web 应用程序,您应该在 web 应用程序中捆绑所需的类。通过尝试从其他地方加载类,您正在挫败 Web 应用程序设计; Web 应用程序和 .war 的想法是让这些东西自成一体。

所以你这样做是错误的。如果您坚持以错误的方式进行操作,则可能会开始使用各种非便携式黑客,以使您的代码在特定情况下正常工作,但是我现在只写一个答案,看看您是什么思考。 :)

【讨论】:

  • 感谢您的回答。这不是我想听到的答案,而是我期待的答案。我想我会重新思考我的类加载概念。
猜你喜欢
  • 2010-12-03
  • 1970-01-01
  • 2021-10-24
  • 2011-05-05
  • 1970-01-01
  • 1970-01-01
  • 2015-07-07
  • 1970-01-01
  • 2017-09-13
相关资源
最近更新 更多