【问题标题】:EJBs 2.0 on OpenEJB - Where do I put the needed jars?OpenEJB 上的 EJB 2.0 - 我在哪里放置所需的 jar?
【发布时间】:2025-12-27 21:35:07
【问题描述】:

到目前为止,我们一直在使用 WAS 6.1 来部署我们的 Web 应用程序。现在我们需要迁移到精通经济的 Tomcat + OpenEJB 解决方案。 OpenEJB 3.1.2 容器插入到 Tomcat 6.18 中,这里没有独立的 OpenEJB 服务器。

所以我在这里,尝试将我的 EJB 2.1 对象部署到 OpenEJB...

我的问题是 EJB 代码需要外部 .jar 库,我不知道将它们放在哪里,以便将它们实际考虑到容器的类路径中。它适用于 catalina.home/lib,因此适用于 openejb.home/lib。但我仍然希望找到一种方法来打包 EJB,以便将它们链接的 .jar 轻松部署到适当的位置以供 OpenEJB 容器使用。

它可以包括使用正确的描述符文件构建 .ear 或 .jar...任何可行的解决方案对我来说都足够好。

有人可以帮忙吗?

【问题讨论】:

  • 我认为 tomcat_home/lib 是避免任何类加载器问题的方法。见usna86-techbits.blogspot.com/2009/12/…
  • @JoseK 我认为特定问题与在 webapp 中包含 javax 库有关。其中大部分是通过 OpenEJB 附带的 javaee-api jar 添加的。其他第三方库应该没问题。如果您有其他经历,请务必告诉我。

标签: deployment tomcat6 ejb-2.x openejb


【解决方案1】:

入耳法

你可以把它放到 Tomcat webapps/ 目录中,它就会被拾取。

示例耳朵(有效):

myapplication.ear
  lib/
  lib/libraryOne.jar
  lib/libraryTwo.jar
  redEjbs.jar
  blueEjbs.jar

常见错误(无效):

myapplication.ear
  libraryOne.jar  (err. not a javaee module)
  libraryTwo.jar  (err. not a javaee module)
  redEjbs.jar
  blueEjbs.jar

根目录中只允许使用 Java EE 模块。这些是 EJB jar、.war 文件、连接器 .rar 文件和应用程序客户端 jar。在 Java EE 5 之前,必须在 application.xml 文件中明确列出库。 Java EE 5 及更高版本可以将它们添加到 lib/ 目录中,并且可以理解为只是普通的 jar,而不是 Java EE 模块。

折叠 EAR 方法

在 OpenEJB/Tomcat 中,您可以将所有库放入 war 文件中,并且可以摆脱耳朵的概念。这现在是 Java EE 6 的一部分。

mywebapp.war
  WEB-INF/lib/libraryOne.jar
  WEB-INF/lib/libraryTwo.jar
  WEB-INF/lib/redEjbs.jar
  WEB-INF/lib/blueEjbs.jar

常见错误,包括规格:

mywebapp.war
  WEB-INF/lib/javax.ejb.jar   (err. *es with the related system library)
  WEB-INF/lib/libraryOne.jar
  WEB-INF/lib/libraryTwo.jar
  WEB-INF/lib/redEjbs.jar
  WEB-INF/lib/blueEjbs.jar

听起来这不是问题,但为了完整性而添加。

常见错误,损坏的依赖关系:

tomcat/lib/libraryTwo.jar

mywebapp.war
  WEB-INF/lib/libraryOne.jar
  WEB-INF/lib/redEjbs.jar
  WEB-INF/lib/blueEjbs.jar

从规范的角度来看,上述内容并非无效,服务器无法检测到,但仍会导致应用无法正确加载。如果 libraryTwo.jar 需要 libraryOne.jar 中的类,那么这个应用程序将永远无法工作,因为 Tomcat“lib”类加载器无法看到“webapp”类加载器中的类,因此 libraryTwo.jar 中的类将永远不会成功加载。不幸的是,虚拟机几乎永远不会说出丢失的实际类,而是会报告导致需要丢失的类的事件链中的第一个类。这几乎总是一个 bean 或 servlet 类。

【讨论】:

  • 不,不会工作...我的 EJB 依赖于另一个 .jar 中的类。我试过把 .jar 放到几个没有运气的地方:在 .ear 的根目录中,在 .war 的根目录中,在 .war 的 WEB-INF/lib 文件夹中……当我启动 Tomcat服务器我一直有'java.lang.NoClassDefFoundError:无法完全加载类:eu.partecis.proxya.ejb.autorisation.UcAutorisationBean 由于:类加载器中的EvtAutorisationRechercheBean:(yadayada)'异常。
  • 将第三方库放在耳朵或战争的根源是无效的。如果您的 ejb jar 在同一个 WEB-INF/lib 目录中,则 WEB-INF/lib 应该可以工作。将扩展答案以显示一些假设的示例。如果您可以扩展问题以显示您正在使用的所有实际 jar,那就太好了。
【解决方案2】:

谢谢大卫。 我尝试了以上所有方法,但仍然没有运气。 我猜 Collapsed EAR 方法对我不起作用,据我所知 Tomcat 6.0.18 不符合 J2EE 6 规范。也许我错了,但我试过了,但还是不行。所以回到标准的 EAR 方法。

我的 EAR 完全按照您的第一个示例中的描述进行组织。一个 Ejb jar,/lib 中的两个库 jar,仅此而已。 Tomcat 仍然无法实例化我的 EJB,因为 EJB 类与 Library Jar 2 中无法访问的类相关。

我简化了我的 application.xml 文件,使其只声明一个 EJB:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ...>
<application>
  <display-name>ProxyaEAR</display-name>
  <module id="EjbModule">
     <ejb>ProxyaEJB.jar</ejb>
  </module>
</application>

还有什么想法吗??

【讨论】:

  • 另一篇文章中的示例没有描述符。如果您有一个描述符,那么您必须使用 myLibrary.jar 为每个第三方库明确列出所有 jar。
最近更新 更多