Glassfish 4 通过独立应用程序访问 EJB
Glassfish 4 Acessing EJBs via Standalone Application
我正在尝试通过 JSE 独立应用程序访问 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 的可移植 JNDI 名称 HelloBean:java:global/ponteWS/HelloBean!br.com.pontews.HelloRemote, java:global/ponteWS/HelloBean!br.com.pontews.HelloBean]]]
“
我尝试了远程名称,瞧!!!有效。
我尝试了其他名称,但没有用。
问题来了:
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: ----------开始服务器端堆栈跟踪----------
org.omg.CORBA.NO_IMPLEMENT:警告:01000001:缺少本地值实现 vmcid:SUN 次要代码:1 已完成:可能
:
:
:
由以下原因引起:java.lang.ClassNotFoundException:br.com.pontews.EJB31_Generated__HelloBean__Intf____Bean (无安全管理器:RMI class 加载程序已禁用)
谢谢
您用于查找 () 的名称具有 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)
Step 1. Use the no-arg InitialContext() constructor in your code.
The most common problem developers run into is passing specific JNDI bootstrapping properties to InitialContext(args). Some other vendors require this step but GlassFish does not. Instead, use the no-arg InitialContext() constructor.
Step 2. Pass the global JNDI name of the Remote EJB to InitialContext.lookup()
Stand-alone java clients do not have access to a component naming environment (java:comp/env) or to the @EJB annotation, so they must explicitly use the global JNDI name to lookup the Remote EJB. (See here for more information on how global JNDI names are assigned to EJB components) Assuming the global JNDI name of the Remote EJB is "FooEJB" :
For Beans with a 3.x Remote Business interface :
Foo foo = (Foo) new InitialContext().lookup("FooEJB");
Note that in the EJB 3.x case the result of the lookup can be directly cast to the remote business interface type without using PortableRemoteObject.narrow().
For EJB 2.1 and earlier session/entity beans :
Object homeObj = new InitialContext().lookup("FooEJB");
FooHome fooHome = (FooHome)
PortableRemoteObject.narrow(homeObj,FooHome.class);
Foo foo = fooHome.create(...)
Step 3. Include the appropriate GlassFish .jars in the java client's classpath.
For GlassFish 3.
Include $GLASSFISH_HOME/glassfish/lib/gf-client.jar in the client's classpath.
E.g., assuming the application classes are in /home/user1/myclasses and the main client class is acme.MyClient :
java -classpath $GLASSFISH_HOME/glassfish/lib/gf-client.jar:/home/user1/myclasses acme.MyClient
Note that the Java EE 6 API classes are automatically included by gf-client.jar so there is no need to explicitly add javaee.jar to the classpath. gf-client.jar refers to many other .jars from the GlassFish installation directory so it is best to refer to it from within the installation directory itself rather than copying it(and all the other .jars) to another location.
Note: gf-client.jar is located in $GLASSFISH_HOME/modules/gf-client.jar in GlassFish v3.
我正在尝试通过 JSE 独立应用程序访问 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 的可移植 JNDI 名称 HelloBean:java:global/ponteWS/HelloBean!br.com.pontews.HelloRemote, java:global/ponteWS/HelloBean!br.com.pontews.HelloBean]]] “
我尝试了远程名称,瞧!!!有效。
我尝试了其他名称,但没有用。
问题来了:
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: ----------开始服务器端堆栈跟踪---------- org.omg.CORBA.NO_IMPLEMENT:警告:01000001:缺少本地值实现 vmcid:SUN 次要代码:1 已完成:可能 : : : 由以下原因引起:java.lang.ClassNotFoundException:br.com.pontews.EJB31_Generated__HelloBean__Intf____Bean (无安全管理器:RMI class 加载程序已禁用)
谢谢
您用于查找 () 的名称具有 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)
Step 1. Use the no-arg InitialContext() constructor in your code.
The most common problem developers run into is passing specific JNDI bootstrapping properties to InitialContext(args). Some other vendors require this step but GlassFish does not. Instead, use the no-arg InitialContext() constructor.
Step 2. Pass the global JNDI name of the Remote EJB to InitialContext.lookup()
Stand-alone java clients do not have access to a component naming environment (java:comp/env) or to the @EJB annotation, so they must explicitly use the global JNDI name to lookup the Remote EJB. (See here for more information on how global JNDI names are assigned to EJB components) Assuming the global JNDI name of the Remote EJB is "FooEJB" :
For Beans with a 3.x Remote Business interface :
Foo foo = (Foo) new InitialContext().lookup("FooEJB");
Note that in the EJB 3.x case the result of the lookup can be directly cast to the remote business interface type without using PortableRemoteObject.narrow().
For EJB 2.1 and earlier session/entity beans :
Object homeObj = new InitialContext().lookup("FooEJB");
FooHome fooHome = (FooHome) PortableRemoteObject.narrow(homeObj,FooHome.class);
Foo foo = fooHome.create(...) Step 3. Include the appropriate GlassFish .jars in the java client's classpath.
For GlassFish 3.
Include $GLASSFISH_HOME/glassfish/lib/gf-client.jar in the client's classpath.
E.g., assuming the application classes are in /home/user1/myclasses and the main client class is acme.MyClient :
java -classpath $GLASSFISH_HOME/glassfish/lib/gf-client.jar:/home/user1/myclasses acme.MyClient
Note that the Java EE 6 API classes are automatically included by gf-client.jar so there is no need to explicitly add javaee.jar to the classpath. gf-client.jar refers to many other .jars from the GlassFish installation directory so it is best to refer to it from within the installation directory itself rather than copying it(and all the other .jars) to another location.
Note: gf-client.jar is located in $GLASSFISH_HOME/modules/gf-client.jar in GlassFish v3.