【问题标题】:How to dynamically load a Java class without using a class loader?如何在不使用类加载器的情况下动态加载 Java 类?
【发布时间】:2014-07-23 20:00:00
【问题描述】:

我最近看到了 JRebel 的在线演示,他们在其中解释了他们的产品做什么,在其中一张幻灯片中他们提到他们不使用类加载器(见下面的屏幕截图)。

我在一些项目中使用类加载器在运行时动态加载类,例如依赖注入(例如在我开发的Maker Factory 框架中)。我认为在 Java 中加载类的唯一方法是使用类加载器。

【问题讨论】:

  • 仔细检查引用,他们可能已经编写了自己的实现并且有点掩饰了..“我们不使用 jre 类加载器”
  • 实际上,我读到的是他们的一名员工(试图说服我使用/购买产品)发给我的 pdf 文件,但也可以在幻灯片中找到:slideshare.net/boothdavid/… 8号,我也会尝试添加我拥有的pdf的截图

标签: java classloader jrebel


【解决方案1】:

他们不使用任何新的类加载器;他们扩展了默认的。

https://www.jrebel.com/learn/how-does-jrebel-work

【讨论】:

  • @ZhekaKozlov спасибo.
【解决方案2】:

免责声明:我参与了 JRebel 的开发

从技术上讲,可以使用一些 Unsafe 魔法绕过类加载器,而 JVM 在创建运行时匿名类(在 Java 8 中)时利用 lambdas 来利用它。

然而,JRebel 实际上与现有的类加载器集成,并没有创建新的类加载器——这就是幻灯片的意思。当 JRebel 必须重新加载一个类时,它不会删除现有的类加载器。相反,它会在现有的类加载器中加载和版本化类。

【讨论】:

  • 所以它确实使用了类加载器?
  • 当然,它使用现有的类加载器。否则,Java 应用程序将如何执行:)
  • 是的,所以回答“如何在不使用类加载器的情况下动态加载 Java 类?”是“你不能,但你可以……”。这很酷,只是想澄清一下
【解决方案3】:

他们提到他们不使用类加载器。

每个类都使用一个 ClassLoader(原语除外)。但是,库不必创建额外的 ClassLoader。

即使是“Hello World”程序也会有两个类加载器(一个用于提升)

我认为在 Java 中加载类的唯一方法是使用类加载器。

是的,但您可以强制现有的类加载器加载您的类,这是 hack 但可能更易于使用。

(更正)如果您使用null 作为类加载器,Unsafe.defineClass() 将默认为调用者的类加载器。

【讨论】:

    【解决方案4】:

    所以这个问题的答案可能是:没有第一次使用类加载器就没有办法动态加载Java类。但是可以通过检测类加载器来部分地重新加载类。

    根据 Dave Newton 的回答链接,从 JRebel 常见问题中提取重要的东西:

    他们使用Instrumentation API 来检测容器/服务器类加载器,这样他们就可以动态监控和控制加载过程。他们将扫描类路径以搜索与加载的类对应的 .class 文件,并使用文件时间戳来检测其上的更改。当检测到更改时,它们将通过检测的类加载器传播该更改。它将保留类的现有实例,但不会重新运行构造函数,这意味着不会初始化新添加的字段。

    【讨论】:

      【解决方案5】:

      确实,加载类的唯一方法是通过类加载器。

      JRebel 的人可能是想说不要使用类加载器重新定义类。可以通过其他方式重新定义类,例如通过JVMTI

      【讨论】:

        【解决方案6】:

        您当然可以自己将类文件读入内存。但是要使该类在您的代码中可用,您仍然需要使用ClassLoader#defineClass

        一般来说,程序中使用的任何类都必须由类加载器定义,否则getClass().getClassLoader()应该返回什么?

        【讨论】:

          【解决方案7】:

          为了完整起见,我想提一下在 Java 9 中引入的新方法 Lookup.defineClass()。它允许动态定义新类,而不会遇到类加载器的所有痛苦。该方法的使用非常简单:您只需传递一个字节数组,您就会立即得到一个Class<?> 对象。但它有一个限制:该类必须与调用者类在同一个包中。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-12-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-01-22
            • 2011-11-05
            • 1970-01-01
            • 2011-02-19
            相关资源
            最近更新 更多