【问题标题】:JNDI / Classpath problem in glassfishglassfish 中的 JNDI / 类路径问题
【发布时间】:2010-05-06 17:06:55
【问题描述】:

我正在将一个大型 J2EE 应用程序(以下称为 AeApp)从 EJB 2 转换为 EJB 3(所有无状态会话 bean,使用 glassfish 2.1.1),但想法不多了。

我转换的第一个 EJB(我们称之为 Foo)运行时没有出现重大问题(它是其 ejb 模块中唯一的一个,我可以用注释完全替换部署描述符)并且应用程序运行良好。但是在转换第二个(我们称之为 Bar,不同 ejb 模块中的几个之一)之后,出现了奇怪的问题组合:

  • AeApp 部署没有错误(日志中也没有)。在日志中,我得到了 Foo 和 Bar 的初始化消息,但更多的消息是关于 Foo 的方法权限和 JNDI 名称:

    [#|2010-05-10T12:26:13.234+0200|FINE|sun-appserver2.1|javax.enterprise.system.core.security|_ThreadID=25;_ThreadName=Thread-2821;ClassName=com.sun.enterprise.security.application.EJBSecurityManager;MethodName=initialize;_RequestID=1801c4ff-90fe-4406-aaac-219c669be8c1;|Codebase (module id for ejb Foo) = null|#]
    [#|2010-05-10T12:26:11.625+0200|FINE|sun-appserver2.1|javax.enterprise.system.core.security|_ThreadID=25;_ThreadName=Thread-2821;ClassName=com.sun.enterprise.security.application.EJBSecurityManager;MethodName=initialize;_RequestID=1801c4ff-90fe-4406-aaac-219c669be8c1;|Codebase (module id for ejb Bar) = null|#]
    [#|2010-05-10T12:26:13.234+0200|FINE|sun-appserver2.1|javax.enterprise.system.core.security|_ThreadID=25;_ThreadName=Thread-2821;ClassName=com.sun.enterprise.security.application.EJBSecurityManager;MethodName=fooMethod;_RequestID=1801c4ff-90fe-4406-aaac-219c669be8c1;|JACC DD conversion: EJBMethodPermission ->(Foo fooMethod,Remote,java.lang.Long,java.util.Locale)protected by role -> FOOUSER|#]
    [#|2010-05-10T12:26:19.312+0200|INFO|sun-appserver2.1|javax.enterprise.system.container.ejb|_ThreadID=17;_ThreadName=httpWorkerThread-14848-1;|**RemoteBusinessJndiName: com.example.Foo; remoteBusIntf: com.example.Foo|#]
    
  • 通过JNDI查找Bar时出错

  • 在 glassfish 管理控制台中查看 JNDI 树时,Bar 根本不存在。
  • 确实会出现同一模块中的其他 EJB,Foo 也是如此。
  • 日志中有关于 Foo 的异常,但这些异常在它仍在工作时已经出现。

任何想法可能导致此问题或如何进一步诊断?豆类非常简单:

@Stateless(name = "Foo")
@RolesAllowed("FOOUSER")
@TransactionAttribute(TransactionAttributeType.SUPPORTS)
public class FooImpl extends BaseBean implements Foo {

Bar 的部署描述符也有一些问题:我想消除它,但 glassfish 似乎不喜欢 bean 只出现在 sun-ejb-jar.xml 中,或者有一些在描述符中声明的模块中的 bean 和其他只使用注释。

编辑: EAR 的结构是这样的:

AeApp.ear
    AeApp.war
    Foo.jar (Foo.class and FooImpl.class present here)
    Bar.jar (Bar.class and BarImpl.class present here, also BaseBean.class)
    (some more EJB module JARs)
    (lots of library JARs)

AeApp.ear 没有(AFAIK 从来没有,即使它正在工作)META-INF/MANIFEST.MF。它的 application.xml 看起来像这样:

<application>
  <description>AE EAR</description>
  <display-name>AE EAR</display-name>
  <module><ejb>Foo.jar</ejb></module>
  <module><ejb>Bar.jar</ejb></module>
  <module><ejb>Baz.jar</ejb></module>
  <module><ejb>Doh.jar</ejb></module>
  <module><web>
      <web-uri>AeApp.war</web-uri>
      <context-root>/</context-root>
  </web></module>
</application>

【问题讨论】:

  • 你能展示一下你的EAR的结构吗? XXX 班级报告失踪在哪里?你能提供一个匿名版本的 EAR 允许复制吗?
  • @Pascal:我添加了一些关于 EAR 结构的信息。 XXX 是一个匿名工件,它的意思是 Foo,它存在于 JAR 中。我不认为我可以发布 EAR,因为这是一个非常大的商业开发应用程序 - 将其匿名化同时保留所有可能相关的内容或多或少是不可能的
  • FooImpl 扩展了 BaseBean。如何将 BaseBean.class 添加到 Foo 的 Classpath 中?
  • @chris_l:我现在很确定这些例外是一个红鲱鱼,并已将它们从问题中删除;我发现它们在 Foo 转换为 EJB 3 后已经出现,并且应用程序运行良好。

标签: glassfish ejb-3.0


【解决方案1】:

经过反复试验,我缩小了问题范围,一位同事把我带上了正确的轨道。问题不在于类路径或 EJB 本身。它更愚蠢。

我的 ejb-jar.xml 有一个 EJBv2 DOCTYPE。这导致 glassfish 只使用注释默默地忽略 EJB,并且在部署描述符中声明它们时无法将它们放入 JNDI 树中。我所要做的就是替换这个:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
     <ejb-jar>

有了这个:

<?xml version="1.0" encoding="UTF-8"?>
     <ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0" 
              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
                                  http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">

【讨论】:

    【解决方案2】:

    我没有看到您之前发布的确切错误消息,但在我看来,好像 bar 的 META-INF/MANIFEST.MF Class-Path 属性中缺少“foo-ejb.jar”。可以通过使用其他方式将 Foo 放入其类路径来编译 bar,但是在运行应用程序时将不起作用。

    但我同意 Pascal 的观点,我们可能确实需要有关您的项目结构的更多信息。关于您拥有哪些罐子,哪些相关类(Foo/Bar/FooImpl/BaseBean/..)在哪个罐子中,它们是如何相关的+它们的注释可能就足够了。 /p>

    【讨论】:

    • 清单中确实没有类路径 - 但从来没有,即使应用程序仍在工作时也是如此。当您使用基于注释的 EJB 时,是否有必要使用它?
    • @Michael:我不确定,但有可能。我拥有的 EJB 2 应用程序总是只包含一个 ejb 模块(老实说,我不记得所有的部署细节,那是很久以前的事了)。对于我的 EJB 3.1 应用程序,我总是使用 MANIFEST 的 Class-Path 属性——据我了解,这是 JavaEE 模块依赖项的标准机制,没有它就无法工作。
    • 我怀疑 ClassNotFoundError 是一个红鲱鱼或至少是真正问题的症状而不是其原因,因为它仅在显示 JNDI 树时发生,而实际上找到并初始化了 Foo EJB部署应用程序时(请参阅问题中添加的日志消息);真正的问题是 Bar EJB 不是。
    猜你喜欢
    • 1970-01-01
    • 2012-04-11
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-25
    相关资源
    最近更新 更多