【问题标题】:Why does TomEE class loader process not find Hibernate classes from ear/lib?为什么 TomEE 类加载器进程无法从 ear/lib 中找到 Hibernate 类?
【发布时间】:2017-09-28 04:05:11
【问题描述】:

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

我将耳朵 (JAR + WAR) 部署到 TomEE 并使用 Hibernate JPA 提供程序。我收到以下错误:

Caused by: java.lang.NoClassDefFoundError: org/hibernate/integrator/spi/Integrator

Hibernate jar 位于 ear/lib 中。 有一个 hibernate-core-4.2.16.Final 包含类org/hibernate/integrator/spi/Integrator

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

对吗?如果是,为什么?

请帮忙

【问题讨论】:

    标签: hibernate ear tomee-7


    【解决方案1】:

    它不会从那里检测到它,因为它不是应该放置此类“全局”库的默认假设。 TomEE reference documentation 状态:

    最少三个类加载器:耳朵一个类加载器,每个 ejb-jar 一个,每个 WAR 文件一个。

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

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

    解决方案

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

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

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

    提示:

    1. 在使用 TomEE-7 时,我建议将 Hibernate 至少升级到 4.3.11 版本,因为 4.3.x 的 Hibernate JPA 支持可用于规范的 2.1 版本。此外,如果您有空,请尝试将您的应用程序migrate 升级到 Hibernate 5.2.x 版本,因为它带来了很多改进。

    2. 有关传递 Hibernate 依赖项的完整列表,请查看列表 for version 4.2.x hereversion 4.3.x here,类似地查看 Hibernate 5.2.x。您只需要收集/捆绑引用的“编译依赖项”并将它们放入全局 TomEE“lib”目录即可。

    3. 还将您在应用程序中使用的 JDBC 驱动程序放在全局 lib 文件夹中。

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-22
      • 1970-01-01
      • 1970-01-01
      • 2021-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多