我试图通过JSE Standalone应用程序访问EJB。
在查找过程中找不到JNDI名字时,我一直在苦苦挣扎。
经过一些没有任何解决方案的研究后,我在Glassfish服务器日志中找到了一条消息后发现的信息:
“[glassfish 4.1] [INFO] [AS-EJB-00054] [javax.enterprise.ejb.container] [tid:_ThreadID = 47 _ThreadName = admin-listener(4)] [timeMillis:1424811833554] [levelValue: 800 [[EJB HelloBean的可移植JNDI名称:java:global / ponteWS / HelloBean!br.com.pontews.HelloRemote,java:global / ponteWS / HelloBean!br.com.pontews.HelloBean]]] “
我尝试了远程名称和voilá!!!它有效。
我尝试了另一个名字但没有用。
问题出现了:
1 - 为什么JNDI名称如此奇怪????有什么我可以做的,以避免在bean的名称前面的包名称? 2-直接访问bean而不是HelloRemote接口时得到的错误是什么?
这是HelloRemote:
package br.com.pontews;
import javax.ejb.Remote;
@Remote
public interface HelloRemote {
public String sayHello(String name);
}
这是Bean:
package br.com.pontews;
import java.io.Serializable;
import javax.ejb.LocalBean;
import javax.ejb.Remote;
import javax.ejb.Stateless;
@Stateless(name="HelloBean")
@LocalBean
@Remote
public class HelloBean implements HelloRemote, Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public HelloBean() {
}
public String sayHello(String name) {
return "Hello," + name + ".!" ;
}
}
以下是有效的通话:
Object lookup =
ctx.lookup("java:global/ponteWS/HelloBean!br.com.pontews.HelloRemote");
这是不起作用的电话:
Object lookup =
ctx.lookup("java:global/ponteWS/HelloBean!br.com.pontews.HelloBean");
最后我通过调用得到的错误不起作用:
线程“main”中的异常javax.naming.CommunicationException:SerialContext的通信异常[myEnv = {java.naming.factory.initial = com.sun.enterprise.naming.impl.SerialInitContextFactory,java.naming.factory.url .pkgs = com.sun.enterprise.naming,java.naming.factory.state = com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl} [根异常是java.rmi.RemoteException:CORBA NO_IMPLEMENT 1398079489也许;嵌套异常是: org.omg.CORBA.NO_IMPLEMENT:---------- BEGIN服务器端堆栈跟踪---------- org.omg.CORBA.NO_IMPLEMENT:警告:01000001:缺少本地值实现vmcid:SUN次要代码:1已完成:可能 : : : 引起:java.lang.ClassNotFoundException:br.com.pontews。 EJB31_Generated__HelloBean__Intf ____ Bean (没有安全管理器:禁用RMI类加载器)
由于
答案 0 :(得分:0)
您用于lookup()的名称具有EJB规范指定的格式。
对于glassfish,还应该可以使用远程业务接口的完全限定名来查找bean(https://glassfish.java.net/javaee5/ejb/EJB_FAQ.html#SessionBeanGlobalJNDINameAssignment)。在你的情况下,这将是
br.com.pontews.HelloRemote
如果您仍然遇到查询问题,此处的说明可能有所帮助:(来自https://glassfish.java.net/javaee5/ejb/EJB_FAQ.html#StandaloneRemoteEJB)
步骤1.在代码中使用no-arg InitialContext()构造函数。
开发人员遇到的最常见问题是将特定的JNDI引导属性传递给InitialContext(args)。其他一些供应商需要这一步,但GlassFish不需要。相反,使用no-arg InitialContext()构造函数。
步骤2.将远程EJB的全局JNDI名称传递给InitialContext.lookup()
独立Java客户端无权访问组件命名环境(java:comp / env)或@EJB批注,因此必须显式使用全局JNDI名称来查找远程EJB。 (有关如何将全局JNDI名称分配给EJB组件的更多信息,请参见此处)假设Remote EJB的全局JNDI名称为“FooEJB”:
对于具有3.x远程业务界面的Bean:
Foo foo =(Foo)new InitialContext()。lookup(“FooEJB”);
请注意,在EJB 3.x情况下,可以直接将查找结果强制转换为远程业务接口类型,而无需使用PortableRemoteObject.narrow()。
对于EJB 2.1及更早版本的会话/实体bean:
Object homeObj = new InitialContext()。lookup(“FooEJB”);
FooHome fooHome =(FooHome) PortableRemoteObject.narrow(homeObj,FooHome.class);
Foo foo = fooHome.create(...) 步骤3.在java客户端的类路径中包含适当的GlassFish .jars。
对于GlassFish 3。
在客户端的类路径中包含$ GLASSFISH_HOME / glassfish / lib / gf-client.jar。
,假设应用程序类在/ home / user1 / myclasses中,主客户端类是acme.MyClient:
java -classpath $ GLASSFISH_HOME / glassfish / lib / gf-client.jar:/ home / user1 / myclasses acme.MyClient
请注意,gf-client.jar会自动包含Java EE 6 API类,因此无需将classee.jar显式添加到类路径中。 gf-client.jar引用GlassFish安装目录中的许多其他.jars,因此最好从安装目录本身引用它,而不是将其(以及所有其他.jars)复制到另一个位置。
注意:gf-client.jar位于GlassFish v3中的$ GLASSFISH_HOME / modules / gf-client.jar中。