我一直在尝试从Java Application Client调用EJB的方法时遇到问题。 这是代码。
EJB远程接口
package com.test;
import javax.ejb.Remote;
@Remote
public interface HelloBeanRemote {
public String sayHello();
}
EJB
package com.test;
import javax.ejb.Stateless;
@Stateless (name="HelloBeanExample" , mappedName="ejb/HelloBean")
public class HelloBean implements HelloBeanRemote {
@Override
public String sayHello(){
return "hola";
}
}
主类(另一个项目)
import com.test.HelloBeanRemote;
import javax.naming.Context;
import javax.naming.InitialContext;
public class Main {
public void runTest()throws Exception{
Context ctx = new InitialContext();
HelloBeanRemote bean = (HelloBeanRemote)ctx.lookup("java:global/Test/HelloBeanExample!com.test.HelloBeanRemote");
System.out.println(bean.sayHello());
}
public static void main(String[] args)throws Exception {
Main main = new Main();
main.runTest();
}
}
嗯,我的问题是什么?无法找到此EJB的JNDI条目!
java.lang.NullPointerException
at com.sun.enterprise.naming.impl.SerialContext.getRemoteProvider(SerialContext.java:297)
at com.sun.enterprise.naming.impl.SerialContext.getProvider(SerialContext.java:271)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:430)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at testdesktop.Main.runTest(Main.java:22)
at testdesktop.Main.main(Main.java:31) Exception in thread "main" javax.naming.NamingException: Lookup failed for 'java:global/Test/HelloBeanExample!com.test.HelloBeanRemote' in SerialContext [Root exception is javax.naming.NamingException: Unable to acquire SerialContextProvider for SerialContext [Root exception is java.lang.NullPointerException]]
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:442)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at testdesktop.Main.runTest(Main.java:22)
at testdesktop.Main.main(Main.java:31) Caused by: javax.naming.NamingException: Unable to acquire SerialContextProvider for SerialContext [Root exception is java.lang.NullPointerException]
at com.sun.enterprise.naming.impl.SerialContext.getProvider(SerialContext.java:276)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:430)
... 3 more Caused by: java.lang.NullPointerException
at com.sun.enterprise.naming.impl.SerialContext.getRemoteProvider(SerialContext.java:297)
at com.sun.enterprise.naming.impl.SerialContext.getProvider(SerialContext.java:271)
... 4 more Java Result: 1
我尝试使用不同的JNDI条目但没有任何作用(我从NetBeans控制台获得了这些条目):
INFO:EJB HelloBeanExample的可移植JNDI名称:[java:global / Test / HelloBeanExample,java:global / Test / HelloBeanExample!com.test.HelloBeanRemote]
INFO:EJB HelloBeanExample的Glassfish特定(非可移植)JNDI名称:[ejb / HelloBean,ejb / HelloBean#com.test.HelloBeanRemote]
所以我尝试了以下条目,但我得到了同样的例外:
我正在使用Netbeans 6.8和Glassfish v3!
答案 0 :(得分:17)
实际上,你的问题是不查找你的bean的JNDI引用,或者你会得到类似的东西:
Caused by: javax.naming.NameNotFoundException: ejb/HelloBean not found
不,在这里,我怀疑一个简单的类路径问题,你只是在客户端项目的类路径上缺少一些jar。使用GlassFish v3,添加$GF_HOME/modules/gf-client.jar
应该足够了,如GlassFish的EJB FAQ中的How do I access a Remote EJB component from a stand-alone java client?所述(我的理解是这个jar应该替换$GF_HOME/lib/appserv-rt.jar
,因为兼容性原因与GFv2相同) 。然而,重要的是从GlassFish安装目录中引用gf-client.jar
或者找不到在其清单中声明的jar。
gf-client.jar
引用GlassFish安装目录中的许多其他.jars,因此最好从安装目录本身引用它,而不是将其(以及所有其他.jars)复制到另一个位置。
一旦你修复了这个问题,你应该能够使用GlassFish在日志中输出的JNDI名称来查找你的bean。我建议使用Java EE 6中新的可移植全局JNDI名称。
以防万一,GlassFish EJB FAQ中的What is the syntax for portable global JNDI names in EJB 3.1?条目提供了这个新约定的一个很好的摘要。如果您想了解更多信息,请查看:http://blogs.oracle.com/MaheshKannan/entry/portable_global_jndi_names。
答案 1 :(得分:0)
我找到了一些东西!我认为使用NetBeans添加和配置组件有一种“特殊方式”!我一直在从网页上阅读netbeans的教程,显然我做错了!所以,这不是解决这个问题的真正解决方案,但也许如果您阅读其中一个http://netbeans.org/kb/trails/java-ee.html,您会发现自己的问题!
问候
答案 2 :(得分:0)
我遇到了同样的问题。我 Google搜索网络,并逐行跟踪Oracle的教程,以设置一个独立的Java客户端,但仍然无效。我遇到了http://glassfish.java.net/javaee5/ejb/EJB_FAQ.html,它有一个我已经尝试解决问题的信息。
我将重新启动IDE,清理并构建项目;也许还可以重新创建项目。谁知道,当月亮满了,我的代码可能运行良好:)所以也许想尝试一下
答案 3 :(得分:0)
我的独立客户端终于运行了!诀窍是,只需重新启动Netbeans IDE,取消部署应用程序并重新部署它。这应该可以解决您的问题(假设代码和配置中没有其他错误)。