繁体   English   中英

Jboss AS 6-如何通过JNDI查找EJB

[英]Jboss AS 6 - How to find an EJB via JNDI

我正在使用Jboss AS 6试用一个简单的EJB 2.1 HelloWorld。我创建了一个具有以下结构的EJB jar文件:

HelloWorldEjb
    |-ex1
        |-ejb21
            |-ejb.jar.xml
            |-Hello.java
            |-HelloBean.java
            |-HelloHome.java
            |-HelloLocal.java
            |-HelloLocalHome.java

我还创建了一个客户端独立的Java类来测试上述ejb。 我使用Jboss 6管理控制台在“应用程序”>“ EJB2 jars”下部署了jar文件,然后单击“添加新资源”。 当我添加jar文件时,它会显示此消息,因此我认为它已正确部署。

Resource HelloWorldEjb.jar created successfully! 

现在,当我运行客户端时,出现此错误:

log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
javax.naming.NameNotFoundException: HelloHome not bound
    at org.jnp.server.NamingServer.getBinding(NamingServer.java:771)
    at org.jnp.server.NamingServer.getBinding(NamingServer.java:779)
    at org.jnp.server.NamingServer.getObject(NamingServer.java:785)
    at org.jnp.server.NamingServer.lookup(NamingServer.java:443)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:305)
    at sun.rmi.transport.Transport$1.run(Transport.java:159)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
    at java.lang.Thread.run(Thread.java:619)
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:142)
    at org.jnp.server.NamingServer_Stub.lookup(Unknown Source)
    at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:728)
    at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:688)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at client.HelloClient.main(HelloClient.java:58)
Exception in thread "main" java.lang.NullPointerException
    at client.HelloClient.main(HelloClient.java:72)

最初,我认为我必须配置JNDI资源,客户端将使用该资源来连接以在应用程序服务器上找到EJB。 没必要吗? 我使用的示例在查找语句中使用EJB名称。 这是用于建立连接的客户端代码部分。

    Properties env = new Properties();

env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory" );
env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
env.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099");

    //env = new InitialContext(env);

InitialContext ctx = null;

try {
    ctx = new InitialContext(env);
} catch (NamingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}       

Object obj = null;

try {
    obj = ctx.lookup("HelloHome");
} catch (NamingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

HelloHome home = (HelloHome) javax.rmi.PortableRemoteObject.narrow(obj, HelloHome.class);

这是ejb-jar.xml的内容

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instalce"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"
    version="2.1">

    <enterprise-beans>
        <session>
            <ejb-name>HelloWorldEJB</ejb-name>
            <home>ex1.ejb21.HelloHome</home>
            <remote>ex1.ejb21.Hello</remote>
            <local-home>ex1.ejb21.HelloLocalHome</local-home>
            <local>ex1.ejb21.HelloLocal</local>
            <ejb-class>ex1.ejb21.HelloBean</ejb-class>
            <session-type>Stateless</session-type>
            <transaction-type>Container</transaction-type>
        </session>  
    </enterprise-beans>

</ejb-jar>

我发现有趣的一件事是,当我编译客户端类时,除非它引用了HelloHome类,否则它拒绝编译。 为了解决这个问题,我不得不将ejb jar文件添加到客户端类的类路径中。 这是应该如何工作的吗? 即ejb jar文件需要在客户端的类路径上吗?

根据用于查找的jndi名称,我需要创建一个新名称吗? 在上面的示例中,它看起来将EJB名称用作查找。

编辑

我目前正在阅读有关EJB 3.0的书。 EBJ 3.0简介的一部分是向我介绍2.0版本,因此为什么我要尝试这个示例。 我认为,即使我不打算使用EJB2,也至少要对它们的工作原理有一些了解是有意义的。

我在控制台上查看了已部署应用程序的列表,但在EJB2.0菜单项上看不到我的应用程序。 我认为这意味着jar文件未正确部署。 Jboss日志确实显示它已部署(请参阅下面的第4行)。

16:36:50,982 INFO  [org.rhq.core.pc.PluginContainer] Plugin Container initialized.
16:36:50,987 INFO  [org.jboss.on.embedded.manager.pc.PluginContainerResourceManager] Discovering Resources...
16:36:50,988 INFO  [org.rhq.core.pc.inventory.AutoDiscoveryExecutor] Executing server discovery scan...
16:36:53,920 INFO  [org.rhq.core.pc.inventory.InventoryManager] Detected new Server [Resource[id=-3, type=JBossAS Server, key=C:\bin\appservers\jboss-6.1.0.Final\server\default, name=JBoss AS 6 (default), parent=<null>, version=6.1.0.Final]] - adding to local inventory...
16:36:54,032 INFO  [org.rhq.core.pc.inventory.AutoDiscoveryExecutor] Found 0 servers.
16:36:54,032 INFO  [org.rhq.core.pc.inventory.RuntimeDiscoveryExecutor] Running runtime discovery scan rooted at [platform]
16:36:54,093 INFO  [org.rhq.core.pc.inventory.InventoryManager] Detected new Server [Resource[id=-4, type=JBoss AS JVM, key=JVM, name=JVM, parent=<null>, version=1.6.0_07]] - adding to local inventory...
16:36:54,097 INFO  [org.rhq.plugins.jmx.JMXServerComponent] Starting connection to JMX Server JVM
16:36:54,695 INFO  [org.rhq.core.pc.inventory.RuntimeDiscoveryExecutor] Scanned [0] servers and found [0] total descendant Resources.

我上述的结构中有什么看起来不对的地方吗?

编辑

好的,我在richj的评论帮助下设法解决了这个问题。 看来我在错误的位置放置了ejb-jar.xml文件。 它应该在META-INF文件夹中。 我将其从ext1 / ejb21复制到/ META-INF,jboss拾取了jar文件。

17:21:44,376 INFO  [org.rhq.core.pc.inventory.RuntimeDiscoveryExecutor] Scanned [0] servers and found [0] total descendant Resources.
17:21:45,301 INFO  [org.jboss.ejb.plugins.local.BaseLocalProxyFactory] Unbind EJB LocalHome 'HelloWorldEJB' from jndi 'local/HelloWorldEJB@21777607'
17:21:45,349 INFO  [org.jboss.proxy.ejb.ProxyFactory] Unbind EJB Home 'HelloWorldEJB' from jndi 'HelloWorldEJB'
17:21:45,358 INFO  [org.jboss.ejb.EjbModule] Undeployed HelloWorldEJB
17:21:45,437 INFO  [org.jboss.ejb.deployers.EjbDeployer] installing bean: ejb/#HelloWorldEJB,uid10624357
17:21:45,438 INFO  [org.jboss.ejb.deployers.EjbDeployer]   with dependencies:
17:21:45,439 INFO  [org.jboss.ejb.deployers.EjbDeployer]   and supplies:
17:21:45,440 INFO  [org.jboss.ejb.deployers.EjbDeployer]        jndi:HelloWorldEJB/ex1.ejb21.Hello
17:21:45,441 INFO  [org.jboss.ejb.deployers.EjbDeployer]        jndi:local/HelloWorldEJB@28622485
17:21:45,442 INFO  [org.jboss.ejb.deployers.EjbDeployer]        jndi:HelloWorldEJB/ex1.ejb21.HelloLocal
17:21:45,443 INFO  [org.jboss.ejb.deployers.EjbDeployer]        jndi:HelloWorldEJB
17:21:45,466 INFO  [org.jboss.ejb.EjbModule] Deploying HelloWorldEJB
17:21:45,495 INFO  [org.jboss.ejb.plugins.local.BaseLocalProxyFactory] Bound EJB LocalHome 'HelloWorldEJB' to jndi 'local/HelloWorldEJB@28622485'
17:21:45,503 INFO  [org.jboss.proxy.ejb.ProxyFactory] Bound EJB Home 'HelloWorldEJB' to jndi 'HelloWorldEJB'

我还对xml文件做了一些小的更改,因为所使用的名称空间中有一个错字。

我使用HelloWorldEJB作为客户端的jndi名称,它终于可以工作了。

谢谢。

我认为您的例外情况意味着:

  • 客户端代码使用错误的名称查找EJB,或者...
  • EJB未在JNDI中注册

这样行吗?

obj = ctx.lookup("HelloHomeEJB");

可以使用<jndi-name>标记定义远程家庭的JNDI名称(并使用<local-jndi-name>标记定义本地家庭的JNDI名称。)

这是应该如何工作的吗? 即ejb jar文件需要在客户端的类路径上吗?

客户端需要访问接口类。 最简单的方法是使用ejb jar文件,但最干净的方法是创建ejb jar文件的客户端版本,该客户端版本不包含仅与EJB实现有关的任何类。

编辑-未部署jar文件

部署EJB时,应将以下内容写入日志文件:

18:49:33,979 INFO  [EjbDeployer] installing bean: ejb/helloworld-ejb.jar#HelloWorld,uid181111540
18:49:33,979 INFO  [EjbDeployer]   with dependencies:
18:49:33,980 INFO  [EjbDeployer]   and supplies:
18:49:33,980 INFO  [EjbDeployer]        jndi:HelloWorldLocal
18:49:33,980 INFO  [EjbDeployer]        jndi:HelloWorld

部署EJB jar文件的通常方法是将其拖放到您正在使用的服务器的deploy目录中(请注意,标准的JBoss安装通常提供多个服务器配置。)在我的系统上,deploy目录是:

/usr/local/jboss/server/default/deploy

有时将多个jar文件打包在一个ear文件中。 部署方法相同,但jar文件应在ear文件的META-INF / application.xml部署描述符中列出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM