首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对Java 9的Hibernate支持

对Java 9的Hibernate支持
EN

Stack Overflow用户
提问于 2017-04-06 14:57:55
回答 1查看 5.6K关注 0票数 14

Hibernate准备好使用Java 9的可用构建了吗?

我记得我已经试过了,但失败了。不幸的是我不记得具体原因了。

顺便说一句,Hibernate Validator 5.2.3已经可以使用Java 9了。

EN

回答 1

Stack Overflow用户

发布于 2017-04-07 15:37:24

我想知道同样的事情,并尝试在Java 9的早期访问版本下运行我的Hibernate应用程序。

我遇到的第一个问题是ClassNotFoundException for javax.xml.bind.JAXBException。JAXB自Java 6以来一直处于运行时类路径中,但在Java 9中,它不再默认发布。至少有两种方法可以解决这个问题:

  1. 当您在Java9JVM中运行您的程序时,包括命令行参数“--add java.se.ee”。这再次指示Java 9在类路径中包含JAXB (和其他库)。但请记住,Java 8 JVM将拒绝此论点;因此,如果允许用户在不止一个版本的Java下运行,则必须动态计算命令行,或要求用户手动编辑命令行。
  2. 在应用程序中包括JAXB库。如果您的Hibernate应用程序是注释驱动的,那么它可能实际上不需要JAXB的任何实现,在这种情况下,您只需要包含JAXB即可。下面是我添加到pom中的依赖项:

随着JAXB问题的解决,我运行了这个应用程序,并收到了几千行如下所示的堆栈跟踪:

代码语言:javascript
复制
java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @49f97198
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:337)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:281)
    at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:197)
    at java.base/java.lang.reflect.Method.setAccessible(Method.java:191)
    at javassist.util.proxy.SecurityActions.setAccessible(SecurityActions.java:103)
    at javassist.util.proxy.FactoryHelper.toClass2(FactoryHelper.java:181)
    at javassist.util.proxy.FactoryHelper.toClass(FactoryHelper.java:164)
    at javassist.util.proxy.ProxyFactory.createClass3(ProxyFactory.java:507)
    at javassist.util.proxy.ProxyFactory.createClass2(ProxyFactory.java:492)
    at javassist.util.proxy.ProxyFactory.createClass1(ProxyFactory.java:428)
    at javassist.util.proxy.ProxyFactory.createClass(ProxyFactory.java:400)
    at org.hibernate.proxy.pojo.javassist.JavassistProxyFactory.postInstantiate(JavassistProxyFactory.java:72)
    at org.hibernate.tuple.entity.PojoEntityTuplizer.buildProxyFactory(PojoEntityTuplizer.java:162)
    at org.hibernate.tuple.entity.AbstractEntityTuplizer.<init>(AbstractEntityTuplizer.java:163)
    at org.hibernate.tuple.entity.PojoEntityTuplizer.<init>(PojoEntityTuplizer.java:58)

在这些异常之后,您的应用程序可能会正常运行。但不要被愚弄:对象的延迟初始化已被禁用。因此,您可能会遇到严重的性能问题。

之所以出现这些错误,是因为Hibernate的运行时字节码增强被新模块系统中强大的封装规则所阻止。有关此问题的详细描述,请参阅这个堆叠溢出柱

正如在那篇文章中提到的,您可以通过在启动JVM时添加另一个命令行参数来消除这些错误。但这种方法只是一个解决办法,而不是一个好的长期解决方案。

经过多次尝试和错误之后,我发现了一个更好的解决方案:

  1. 使用Hibernate 5.0.0或更高版本(早期版本不能工作)
  2. 请求构建时字节码增强 (使用Gradle、Maven或Ant插件)。

这避免了Hibernate在运行时执行基于above的类修改的需要,从而消除了上面所示的堆栈跟踪。我用Hibernate 5.0.12.FINAL、5.1.5.Final和5.2.9 tested测试了这一点。

无论如何,您应该在之后彻底测试您的应用程序。Hibernate在构建时应用的字节码更改似乎与在运行时应用的字节码不同,导致应用程序行为略有不同。当我启用构建时字节码增强时,我的应用程序中成功了多年的单元测试突然失败了。(我不得不寻找新的LazyInitializationException错误和其他问题。)不同版本的Hibernate的行为似乎各不相同;我可以在5.0.12中修复我的单元测试,然后在5.1.5中再次看到它们失败。谨慎地进行.

票数 23
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43258796

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档