【问题标题】:JNDI Lookup on JBoss AS 6.0JBoss AS 6.0 上的 JNDI 查找
【发布时间】:2013-08-24 18:29:08
【问题描述】:

我在 JBoss 6.0 AS 的本地主机上部署了一个应用程序。此应用程序有一个名为 ExampleEJB 的远程 EJB bean。现在我正在尝试编写一个使用 ExampleEJB 的简单客户端应用程序。此客户端应用程序不会部署在任何应用程序服务器上。这个想法是编写一个简单的 Java SE 客户端程序。我写了以下内容来尝试执行查找:

Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
env.put(Context.PROVIDER_URL,"localhost:1099");
env.put("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");

InitialContext ic = new InitialContext(env);

此时,我尝试了两种方法第一种是执行直接查找,如 Java EE 6 教程 (http://docs.oracle.com/javaee/6/tutorial/doc/gipjf.html) 中的示例:

ExampleEJB exampleEJB = (ExampleEJB) ic.lookup("java:global/myApp/ExampleEJB");

第二次尝试是尝试获取 JNDI 上下文环境,然后从该环境中获取所需的 bean:

Context envContext  = (Context)ic.lookup("java:/comp/env");
envContext.lookup(...)

问题是我收到以下异常:“javax.naming.NameNotFoundException: global not bound”和“javax.naming.NameNotFoundException: comp not bound”。我无法根据需要执行查找。

有人知道吗?

【问题讨论】:

    标签: jakarta-ee jndi jboss6.x


    【解决方案1】:

    如果您使用的是java:global/,那么 JNDI 名称应如下所示:

    java:global/<application>/<module>/<component>
    

    java:global/<ear>/<ejb-jar>/<ejb-name>
    

    其中 ear 是 .ear 文件的名称,ejb-jar 是 EJB .jar 文件的名称。


    如果您同时拥有本地和远程接口,则可以使用此方案进行区分:

    java:global/<ear>/<ejb-jar>/<ejb-name>!<interface>
    

    interface 包含包和接口名称(例如:a.b.c.ExampleEJBRemoteIfc)。


    所以在您的设置中:如果 myApp.ear 包含 myEjb.jar,其中包含名称为 ExampleEJB 的 EJB,那么试试这个 JNDI 名称:

    java:global/myApp/myEjb/ExampleEJB
    

    java:global/myApp/myEjb/ExampleEJB!a.b.c.ExampleEJBRemoteIfc
    

    无论如何,请在 JMX 控制台中仔细检查 JNDI 名称:

    http://localhost:8080/jmx-console/
    
    1. 点击Service=JNDIView
    2. 操作list:点击invoke按钮
    3. 按 EJB 名称在该页面中搜索

    至于 comp/envglobalWhat is the relationship between java:comp/env and java:global

    【讨论】:

    • 你好,铍。非常感谢您的回答。我在 jmx-console 检查了 JNDIView。我写这个问题的时候不知道。当我在以下位置执行查找时:“ExampleEar/ExampleEJBImpl/remote”一切正常。你能确认一下 JBoss 将 EJB 绑定到没有“java:global”前缀的位置吗?你知道为什么吗?我认为这是 Java EE 6 规范,因此每个应用程序服务器都会尊重默认的“java:global///”位置。
    • 名称绑定到不同的命名空间(具有不同的作用域)。这就是为什么我以“如果您使用的是 java:global ...”作为答案的原因。所以是的,还有其他地方也有不同的方案。您选择的名称也有效。 JNDIView 在 java: 命名空间中显示什么?在我的例子中,java:global 条目只是 JNDI 中指向您使用的条目的链接。所以两者都应该工作。
    • 是的,你是对的。我还可以在 java: namespace 上看到我的 ExampleEJBImpl,就像你说的那样。它位于全局和 Java 命名空间中。但是,我无法从我的客户端应用程序访问 java 命名空间。即使我使用 JNDIView 给我的正确路径。当我尝试从不同的 JVM 进程执行查找时,显然会出现问题。 Java 命名空间只能从同一个 JVM 访问。就我而言,我必须使用全局命名空间来执行查找。那正确吗?再次感谢您。
    【解决方案2】:

    好的,我已经解决了我的问题。我发现可以通过访问 JBoss JMX 管理控制台(默认位置在 localhost:8080/jmx-console/)来可视化 JBoss 上的 JNDI 树。找到 JNDIView 服务并调用列表方法。通过可视化 JNDI 树,我发现我在寻找错误的位置。 JBoss 在以下位置注册了我的 EJB:

    +- ExampleEar (class: org.jnp.interfaces.NamingContext)
      |   +- ExampleEJBImpl (class: org.jnp.interfaces.NamingContext)
      |   |   +- remote-br.exemplo.ejb.ExampleEJB (class: Proxy for: br.example.ejb.ExampleEJB)
      |   |   +- remote (class: Proxy for: br.example.ejb.ExampleEJB)
    

    我刚刚修改了我的代码以在以下位置执行查找:

    ExampleEJB exampleEJB = (ExampleEJB) ic.lookup("ExampleEar/ExampleEJBImpl/remote");
    

    一切都很顺利。

    【讨论】:

      猜你喜欢
      • 2012-01-24
      • 1970-01-01
      • 1970-01-01
      • 2011-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-24
      • 1970-01-01
      相关资源
      最近更新 更多