【问题标题】:JNDI lookup of EJB3 inside an EAR file on GlassfishGlassfish 上 EAR 文件中 EJB3 的 JNDI 查找
【发布时间】:2010-12-04 04:25:26
【问题描述】:

我有一个 EAR 文件,其中包含一堆 JAR,其中一个 JAR 包含本地会话 Bean (EJB3)。我需要从非托管 POJO 中执行这些会话 Bean 的 JNDI 查找,该 POJO 也包含在 EAR 中(在这种情况下,也包含在与 EJB 相同的 JAR 中)。我尝试关注Glassfish EJB FAQ,但无论我尝试什么,我都会继续收到 javax.naming.NameNotFoundException。

我不确定一些事情。我应该把我的 ejb-jar.xml 放在哪里(我尝试了 EARs META-INF 以及 JARs META-INF)?我需要 sun-ejb-jar.xml 吗? ejb-link到底是什么,它有什么作用?我可能做错了什么(我的配置与本地查找常见问题解答中给出的配置几乎相同)?

我列出了一些我尝试过的配置以及下面的结果:

<enterprise-beans>
  <session>
    <ejb-name>ITestBean</ejb-name>
    <ejb-class>com.test.TestBean</ejb-class>
    <ejb-local-ref>
      <ejb-ref-name>ITestBean</ejb-ref-name>
      <local>com.test.ITestBean</local>
    </ejb-local-ref>
  </session>
 </enterprise-beans>

应用程序已部署,但 JNDI 查找返回 null。

<enterprise-beans>
  <session>
    <ejb-name>ITestBean</ejb-name>
    <ejb-class>com.test.TestBean</ejb-class>
    <ejb-local-ref>
      <ejb-ref-name>ITestBean</ejb-ref-name>
      <local>com.test.ITestBean</local>
      <ejb-link>ITestBean</ejb-link>
    </ejb-local-ref>
  </session>
 </enterprise-beans>

应用程序未部署:无法确定 EJB 3.0 ref Unresolved Ejb-Ref ITestBean@jndi 的本地业务与远程业务指定。

<enterprise-beans>
  <session>
    <ejb-name>ITestBean</ejb-name>
    <ejb-class>com.test.TestBean</ejb-class>
    <ejb-local-ref>
      <ejb-ref-name>ITestBean</ejb-ref-name>
      <local>com.test.ITestBean</local>
      <ejb-link>MyJar.jar#ITestBean</ejb-link>
    </ejb-local-ref>
  </session>
 </enterprise-beans>

应用程序未部署:错误:未解决:MyJar.jar#ITestBean。

<enterprise-beans>
  <session>
    <ejb-name>ITestBean</ejb-name>
    <local>com.test.ITestBean</local>
    <ejb-local-ref>
      <ejb-ref-name>ITestBean</ejb-ref-name>
    </ejb-local-ref>
  </session>
 </enterprise-beans>

错误处理 EjbDescriptor

【问题讨论】:

  • “应用程序未部署:无法确定 EJB 3.0 ref Unresolved Ejb-Ref ITestBean@jndi 的本地业务与远程业务指定。” - 在这种情况下,你的价值观似乎很奇怪。 com.test.IEntityExtensionDefinitionBean 真的是该 bean 的本地接口吗?为什么你自己的bean和你试图引用的bean的名字一样?
  • 啊,对不起。我试图用更简单的类和名称来淡化这个例子,但我错过了那个。我用正确的名称更新了问题。我想我终于找到了问题的根源。你提到我有一个我想引用的 bean,以及我的“自己的”bean,我不明白,因为我只有一个 bean。在阅读之后,我似乎必须注册我想要访问另一个 bean 的 bean。这真的是唯一的方法吗?如果我想从既不是托管也不是从托管类访问的 POJO 访问 bean 怎么办?

标签: java ejb-3.0 jndi local


【解决方案1】:

您也可以随时在 System.out 或日志中转储 InitialContext 中的所有名称。

//Get all the names in the initial context
NamingEnumeration children = initialContext.list("");

while(children.hasMore()) {
    NameClassPair ncPair = (NameClassPair)children.next();
    System.out.print(ncPair.getName() + " (type ");
    System.out.println(ncPair.getClassName() + ")");
  }
}

【讨论】:

  • 谢谢你,它一定会派上用场的。
【解决方案2】:

ejb 文件的 ejb-jar.xml 进入 META-INF(EJB-Jar 的,而不是耳朵的)。部署描述符中的 EJB Ref 如下所示:

<ejb-local-ref>
    <ejb-ref-name>EJBName</ejb-ref-name>
    <ejb-ref-type>Session</ejb-ref-type>
    <local>classname</local>
    <ejb-link>JARName.jar#EJBName</ejb-link>
</ejb-local-ref>

查找代码如下所示:

Context c = new InitialContext();
return (EJBLocalInterface) c.lookup("java:comp/env/EJBName");

我认为您不需要容器特定的部署描述符 (sun-ejb-jar.xml) 来进行此类查找。

【讨论】:

    【解决方案3】:

    我认为EJB 3 Portability Issue 博客文章应该对您有所帮助。

    【讨论】:

    • 是的,这是一篇不错的帖子...谢天谢地,JEE6/EJB3.1 最终会解决这个问题。
    • 恭喜你,elhoim。 JNDI 是一个很好的 ideia 标准。
    • 感谢链接,我之前在搜索时看到了它,但假设它只适用于远程接口,而不是像我这样的本地接口。这同样适用于本地接口吗?
    • @Ristretto:对于本地名称,名称确实也没有标准化。
    • 这是否意味着我在查找 Local beans 时应该使用完全限定名称?
    【解决方案4】:

    不可能从 POJO 执行 bean 的 JNDI 查找,除非从托管类(例如会话 bean)(直接或间接)调用 POJO。换句话说,第一个示例不起作用,而第二个示例将起作用(假设 MyPOJO 是尝试执行 JNDI 查找的类):

    1) UnmanagedClass1 -> UnmanagedClass2 -> UnmanagedClass3 -> MyPOJO
    2) ManagedClass -> UnmanagedClass2 -> UnmanagedClass3 -> MyPOJO

    【讨论】:

    • 这不正确,您绝对可以从非托管组件中查找 EJB(注入不起作用,但标准查找肯定会)。
    • 嗨 Pascal,如果你知道如何让它工作,也请告诉我。我尝试的测试都没有成功。就像我在答案中所说的那样,我可以从非托管组件中查找 EJB 的唯一方法是调用堆栈是否包含更高级别的托管组件。
    【解决方案5】:

    我正在研究 glassfish v2,当从 EJB3 调用 JSNI 时,我只需要 ejb-jar.xml,而不需要 sun-ejb-jar.xml

    <ejb-jar xmlns = "http://java.sun.com/xml/ns/javaee" 
         version = "3.0" 
         xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">
    
             <enterprise-beans>
    
                 <session>
                     <ejb-name>TestBean1</ejb-name>
                     <ejb-local-ref>
                        <ejb-ref-name>ejb/TestLocal</ejb-ref-name>
                        <ejb-ref-type>Session</ejb-ref-type>
                        <local>com.clients.TestLocal</local>
                        <mapped-name>ejb/TestLocal</mapped-name>
                    </ejb-local-ref>
                     <ejb-local-ref>
                        <ejb-ref-name>ejb/Test2Local</ejb-ref-name>
                        <ejb-ref-type>Session</ejb-ref-type>
                        <local>com.clients.Test2Local</local>
                        <mapped-name>ejb/Test2Local</mapped-name>
                    </ejb-local-ref>
                  <session>
            <enterprise-beans>
    

    @Stateless(mappedName="ejb/TestLocal")
    public class TestBean1 implements TestLocal
    
    @Stateless(mappedName="ejb/Test2Local")
    public class TestBean2 implements Test2Local
    

    在TestBean1中调用服务定位器

    ic.lookup("java:comp/env/ejb/Test2Local");
    

    将返回 Test2Bean

    【讨论】:

      猜你喜欢
      • 2011-08-08
      • 1970-01-01
      • 2011-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-13
      • 1970-01-01
      • 2018-09-18
      相关资源
      最近更新 更多