我正在使用 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 管理控制台在 Applications > 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 名称,它终于奏效了。
谢谢。