4

根据文档,GraalVM 项目中的本机图像编译器对动态代理有一些限制。由于 Hibernate 大量使用了代理,它是否可以在提前编译好的项目中正常工作?

Quarkus项目似乎表明可以,但我的理解主要是基于Reddit 的一篇帖子

Hibernate ORM 现在即使编译为 GraalVM 原生镜像也可以工作 - 只需确保使用 Quarkus 构建应用程序。

如果我不想(或不能)使用 Quarkus 怎么办?是否可以使用使用 Hibernate 的 GraalVM(和 SubstrateVM)编译本机映像应用程序?

Quarkus 实际上了什么来启用/支持 Hibernate?

4

2 回答 2

5

免责声明:我是通过创建 Quarkus 扩展使 Hibernate ORM 在 GraalVM 原生映像上工作的人之一。我还领导着 Hibernate 研发团队。

感谢您有机会写下一些历史:)

最初我们没有使用 Quarkus,因为它还不存在。

我最初的原型只是修补 Hibernate ORM 并堆积了许多编译器开关以传递给 native-image 工具,在 bash 脚本中硬编码,直到我的演示应用程序工作。

这种方法的问题在于,许多这样的标志实际上取决于Hibernate ORM 的内部知识、域模型的细节、配置细节等的组合。

我开始记录这些事情,但它变得复杂而多毛;尤其是不同的方面相互依赖;此外,我的演示应用程序相当简单,而实际应用程序必然会变得更加复杂……我认为我们无法编写一个既透彻又“易于理解”的好文档。

为最终用户保持简单的另一种方法是“启用对所有这些类的反射,因为你可能会使用它们”,但我有点优化怪胎,这将创建更大和臃肿的二进制文件,而不是仅并且专门包括您的应用程序真正需要的所有东西。

所以我们的团队决定编写一个工具来自动化这些细节。它变成了一个构建工具,可以分析你的应用程序以找出最好的开关。而不是只关注 Hibernate ORM,我们创建了“扩展”的概念,它也知道如何为其他库提取相同的技巧,这样您就可以从使用支持库的组合的更复杂的应用程序中受益于高度优化的二进制文件,而不仅仅是休眠。

显然这是必要的,因为不同的库可能有相​​互冲突的需求,并且每个其他库和最终用户代码的编译器标志的组合需要组合在一组一致的兼容标志中。

所以这就是 Quarkus 成为一件事的方式:)

要查看其工作原理的详细信息,我建议阅读指南和源代码:

我还对它在公开演讲中的运作方式进行了一些高级概述;Devoxx UK 的录音很好

我的演讲专门讨论了 Hibernate ORM;我没有太多时间详细介绍它所做的所有事情,但在阅读实际代码以了解详细信息之前,它应该作为一个很好的介绍。

如果我不想(或不能)使用 Quarkus 怎么办?是否可以使用使用 Hibernate 的 GraalVM(和 SubstrateVM)编译本机映像应用程序?

这是一个公平的问题——当然有可能,但 Quarkus 团队很想知道为什么?

Quarkus 所做的所有工作大多只是构建时的。当然它在这个阶段可能会受到限制,因为它是一个非常年轻的项目,但是如果您需要对其他任何东西的支持,那么为它的核心(或它的扩展)做出贡献应该比在构建脚本中硬编码复杂的编译器标志更容易。尤其重要的是,Quarkus 社区正在成为讨论如何解决 Graal 限制可能遇到的任何障碍的好地方。

Hibernate ORM 的所有最复杂的补丁都已合并到 Hibernate 上游存储库中,因此所有重要的补丁都包含在任何最新版本中。

假设您想远离 Quarkus(我不建议这样做,但假设您想学习......),您仍然需要修改反射规则,而且 Quarkus 确实限制了一些功能,最值得注意的是一些细节是仍然“正在进行中”,或者我们认为人们不应该再使用的东西:)

具体来说,我和我的队友都不是线程绑定会话的忠实粉丝。除非有人为它提出一个很好的理由,否则我不会实现对它的支持:请打开一个功能请求,或者理想情况下帮助为它和一个补丁提供一个很好的理由?

于 2019-07-30T11:42:12.620 回答
0

如果您想知道,Quarkus 究竟做了什么来构建原生镜像,与创建者一起阅读脚本(或观看视频):https ://www.infoq.com/presentations/quarkus-graalvm-sao-paulo-2019 /

我记得:

  • 在编译时解决所有注释查找和实体解析
  • 准备一些带有“静态”初始化字段的实例。准备好的实例存储在映像中,并准备在启动时仅在堆上分配
  • 如果需要,在编译时生成“代理”
  • 基本上 Quarkus(作为 gralvm 的“插件”)确实“将您的应用程序启动到实际连接到数据库的时间点”。比它拍摄内存快照并将其嵌入到 jar/native 文件中
  • Quarkus 也确实触及了其他一些库,它们会做“禁止”的事情(封闭世界假设)

这将启用“热代码重新加载”,这实际上会在“眨眼”时间内重新启动整个应用程序。它使用更少的内存和其他好东西。

PS:Quarkus 的小介绍在这里:https ://www.infoq.com/news/2019/03/redhat-release-quarkus/

于 2019-09-20T13:26:28.843 回答