根据文档,GraalVM项目中的本机图像编译器对动态代理有一些限制。由于Hibernate广泛使用代理,因此它可以在预先编译的项目中正常工作吗?
Quarkus项目似乎表明可以,但是我的理解主要是基于Reddit post的说法
即使编译为GraalVM本机映像,Hibernate ORM现在也可以工作-只需确保您使用Quarkus来构建应用程序即可。
如果我不想(或不能)使用Quarkus怎么办?是否可以使用使用Hibernate的GraalVM(和SubstrateVM)来编译本机图像应用程序?
Quarkus 实际上要做什么来启用/支持Hibernate?
答案 0 :(得分:3)
(免责声明:我是通过创建Quarkus Extensions使Hibernate ORM在GraalVM本地映像上工作的人之一。我还领导Hibernate研发团队。)
感谢您有机会写下一些历史:)
最初我们不使用Quarkus,因为它还不存在。
我最初的原型只是修补Hibernate ORM并堆积了许多编译器开关,这些开关将传递给使用bash脚本进行硬编码的本机图像工具,直到使演示应用程序正常工作为止。
该方法的问题在于,许多这样的标志实际上依赖,它们依赖于Hibernate ORM的内部知识,域模型的详细信息,配置详细信息等等。
我开始记录这些事情,但是它变得越来越繁琐。至少不同方面相互依赖;同样,我的演示应用程序非常简单,实际应用程序注定会变得更加复杂...我认为我们无法编写出既好又“容易理解”的好文档。
对于最终用户来说,使事情保持简单的另一种方法是“在可能使用它们时对所有这些类进行反射”,但是我有点优化上的怪异,比只包含应用程序真正需要的所有内容时,创建的二进制文件要大得多且肿。
因此,我们的团队决定编写一种工具来代替这些细节的自动化..它变成了一个构建工具,可以对您的应用程序进行分析,以找出要使用的最佳开关。而不是只关注Hibernate ORM,我们创建了“扩展”的概念,该概念也知道如何为其他库提供相同的技巧,以便您可以使用支持的库组合从更复杂的应用程序中获得高度优化的二进制文件,而不仅仅是休眠。
显然很必要,因为不同的库可能有相互冲突的需求,并且每个库的编译器标志与最终用户代码的组合需要组合在一组一致的兼容标志中。
这就是Quarkus成为事物的方式:)
要查看其工作原理的详细信息,我建议阅读指南和源代码:
我还简要介绍了它在公开演讲中的工作方式; Devoxx UK录制的很好
我的演讲专门讨论了Hibernate ORM;我没有太多时间详细介绍它所做的所有事情,但是在阅读实际代码以了解细节之前,它应该是一个很好的介绍。
如果我不想(或不能)使用Quarkus怎么办?是否可以使用使用Hibernate的GraalVM(和SubstrateVM)来编译本机图像应用程序?
这是一个公平的问题-当然可以,但是Quarkus团队很想知道为什么?
Quarkus所做的所有工作大部分仅是构建时;可以肯定的是,由于这是一个很年轻的项目,它在现阶段可能会受到限制,但是如果您需要其他任何支持,那么对它的核心(或对它的扩展)的贡献应该比对构建脚本中的复杂编译器标志进行硬编码要容易得多。尤其重要的是,Quarkus社区正在成为讨论如何解决Graal限制可能遇到的任何障碍的好地方。
Hibernate ORM的所有最复杂的补丁已合并到Hibernate上游存储库中,因此所有重要的补丁都包含在任何最新发行版中。
假设您想保持对Quarkus的了解(我不建议这样做,但是假设您想学习...),您仍然需要修改反射规则,事实上Quarkus限制了某些功能,最明显的是一些细节仍在“进行中”,或者我们不认为人们应该再使用的东西:)
具体地说,我和我的队友都不是线程绑定会话的忠实拥护者。除非有人对此提供充分的理由,否则我不会实施对此的支持:请打开功能请求,或者最好是为它提供良好的理由和补丁?
答案 1 :(得分:0)
如果您想知道Quarkus是做什么工作来启用本机图像的,请与创建者一起阅读抄本(或观看视频):https://www.infoq.com/presentations/quarkus-graalvm-sao-paulo-2019/
我记得:
这将启用“热代码重载”,实际上是在“眨眼之间”的时间内重新启动整个应用程序。它使用更少的内存和其他好东西。
PS:这里是Quarkus的小介绍:https://www.infoq.com/news/2019/03/redhat-release-quarkus/