首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么TomEE类加载器进程找不到来自ear/lib的Hibernate类?

为什么TomEE类加载器进程找不到来自ear/lib的Hibernate类?
EN

Stack Overflow用户
提问于 2017-09-28 12:05:11
回答 1查看 383关注 0票数 1

我构建的经典ear应用程序包含子模块EJB (放入jar)和WEB (放入war)。

我将ear (JAR + WAR)部署到TomEE中,并使用Hibernate JPA提供程序。我得到以下错误:

代码语言:javascript
运行
复制
Caused by: java.lang.NoClassDefFoundError: org/hibernate/integrator/spi/Integrator

Hibernate jars进入了ear/lib。hibernate-core-4.2.16.Final包含类org/hibernate/integrator/spi/Integrator

所以我认为Tomee进程不会从我的ear/ ClassLoader文件夹中加载类。

是对的吗?如果是,为什么?

请帮帮忙

EN

回答 1

Stack Overflow用户

发布于 2017-10-22 16:23:07

它不会从那里检测到它,因为这不是默认的假设,这样的“全局”库应该放在哪里。TomEE reference documentation声明:

至少有三个类加载器:一个用于ear的类加载器、一个用于每个ejb-jar的类加载器和一个用于每个WAR文件的类加载器。

正如我们从这句话中了解到的那样,EAR应用程序,特别是它的EAR模块,是在容器启动时很早就使用它们自己的类加载器实例进行初始化的,并且在WAR初始化之前使用自己的类加载器进行初始化。

我猜您的EAR模块( jar文件中的模块)代表后端层模块,扫描Hibernate,试图加载相关的类文件。遗憾的是,它不能在它的类加载器的范围内“看到”它们。

解决方案

但是,当您将所有Hibernate jars (以及所有可传递的依赖项,如antlr、dom4j、javassist...)根据TomEE directory layout添加到全局lib目录中。这无论如何都更有意义,因为它可以被你的应用程序的不同部分重用,这些部分可以/将被捆绑到你的EAR可部署的甚至在同一容器中运行的完全不同的应用程序中。因此,全局jar文件将在ejb模块的类路径中可用,因此可以在容器启动时启动Hibernate。

一旦放置到容器范围的安装中,您就可以将Hibernate jars从捆绑到EAR/lib文件夹中移除(通过在Maven项目设置的pom.xml中将其声明为提供的依赖项)。

作为一个副作用,这也会大大减少你的EAR包的大小,因为现在的库是“全局的”。在运行时,您还会观察到内存占用减少了,因为Hibernate ORM的所有类文件只会在容器中加载一次,而不会多次加载不同的WAR或WAR包。

提示:

  1. 在使用TomEE 7时,我建议至少将Hibernate升级到4.3.11版本,因为4.3.x版本的Hibernate JPA支持可用于2.1版本的规范。此外,如果您可以这样做,尝试将您的应用程序migrate到版本Hibernate 5.2.x,因为它带来了许多可传递的Hibernate依赖项的完整列表,请查看列表for version 4.2.x hereversion 4.3.x here,Hibernate 5.2.x。您只需收集/捆绑引用的“编译依赖项”,并将它们放入全局TomEE "lib“目录中即可运行。
  2. 还将您在应用程序中使用的JDBC驱动程序放在全局lib文件夹中。

希望能有所帮助。

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

https://stackoverflow.com/questions/46460794

复制
相关文章

相似问题

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