1. 调用EJB的三种方法
调用EAP 6 EJB的第一种方法,使用JBoss API,如下:
Properties p = new Properties();
p.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
p.put("remote.connections", "default");
p.put("remote.connection.default.host", "localhost");
p.put("remote.connection.default.port", "4447");
p.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false");
EJBClientConfiguration cc = new PropertiesBasedEJBClientConfiguration(p);
ContextSelector<EJBClientContext> selector = new ConfigBasedEJBClientContextSelector(cc);
EJBClientContext.setSelector(selector);
Properties props = new Properties();
props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
InitialContext context = new InitialContext(props);
final boolean useScopedExample = Boolean.getBoolean("UseScopedContext");
final String rcal = "ejb:jboss-ejb-multi-server-app-main/ejb//" + (useScopedExample ? "MainAppSContextBean" : "MainAppBean") + "!" + MainApp.class.getName();
final MainApp remote = (MainApp) context.lookup(rcal);
这种方法在Standalone client (client is not running inside of JBoss EAP 6)能正常调用,但在EAP 6环境中会报java.lang.SecurityException: EJBCLIENT000021: EJB client context selector may not be changed。
第二种方法使用scoped context,代码如下:
Properties props = new Properties();
props.put("org.jboss.ejb.client.scoped.context", "true");
props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
//props.put(Context.OBJECT_FACTORIES, "org.jboss.ejb.client.naming.ejb.ejbURLContextFactory");
props.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
props.put("remote.connections", "default");
props.put("remote.connection.default.port", 4447);
props.put("remote.connection.default.host", host);
//props.put("remote.connection.default.username", username);
//props.put("remote.connection.default.password", password);
props.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");
props.put("jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");
Context context = (Context) new InitialContext(props).lookup("ejb:");
try {
final TimerExample bean = (TimerExample) context.lookup("TestTimer/TestTimerEJB/TimerExampleBean!org.example.jboss.timer.TimerExample");
bean.doSomething();
} finally {
try {
context.close();
} catch(Exception e) { }
}
这种方式,可以完全通过代码实现配置,但由客户端来创建和管理Connection,因此需要更多的资源,性能不高。还有一个严重的问题,当使用CMT,事物跨多个EJB时,因每次调用EJB后都关闭context(如不close,connection会一直保持),这将造成事务commit/rollback失败。这种情况下,就得使用第三种方式,也是推荐的方式:
先来看代码:
Properties props = new Properties();
props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
final Context context = new javax.naming.InitialContext(props);
final Greeter bean = (Greeter) context.lookup("ejb:myapp/myejb/GreeterBean!" + org.myapp.ejb.Greeter.class.getName());
bean.doSometing();
代码很简单,注意没有调用close()方法。那这是怎么找到远程主机的呢?需要增加一些配置,先在war的WEB-INF或ear的META-INF中新建一个文件jboss-ejb-client.xml,内容如下:
<jboss-ejb-client xmlns="urn:jboss:ejb-client:1.2">
<client-context>
<ejb-receivers>
<remoting-ejb-receiver outbound-connection-ref="remote-ejb-connection-app1" connect-timeout="10000"/>
<remoting-ejb-receiver outbound-connection-ref="remote-ejb-connection-app2" connect-timeout="10000"/>
</ejb-receivers>
</client-context>
</jboss-ejb-client>
然后在standalone.xml增加如下配置,建立与远程主机的关联:
<subsystem xmlns="urn:jboss:domain:remoting:1.2">
<connector name="remoting-connector" socket-binding="remoting" security-realm="ApplicationRealm"/>
<outbound-connections>
<remote-outbound-connection name="remote-ejb-connection-app1" outbound-socket-binding-ref="remote-ejb-app1">
<properties>
<property name="SASL_POLICY_NOANONYMOUS" value="false"/>
<property name="SSL_ENABLED" value="false"/>
</properties>
</remote-outbound-connection>
<remote-outbound-connection name="remote-ejb-connection-app2" outbound-socket-binding-ref="remote-ejb-app2">
<properties>
<property name="SASL_POLICY_NOANONYMOUS" value="false"/>
<property name="SSL_ENABLED" value="false"/>
</properties>
</remote-outbound-connection>
</outbound-connections>
</subsystem>
...
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
<outbound-socket-binding name="remote-ejb-app1">
<remote-destination host="localhost" port="4447"/>
</outbound-socket-binding>
<outbound-socket-binding name="remote-ejb-app2">
<remote-destination host="localhost" port="4447"/>
</outbound-socket-binding>
</socket-binding-group>
调用EJB后,来查看一下connection情况:netstat -aon | findstr "4447"(netstat -np | grep 4447)
2. Could not register a EJB receiver: java.lang.RuntimeException: Operation failed with status WAITING
EJB调用配置中包含以下三个timeout参数:
The timeout for the EJB handshake or method invocation request/response cycle. The value is in milliseconds.
The invocation of any method throws a java.util.concurrent.TimeoutException if the execution takes longer than the timeout period. The execution completes and the server is not interrupted.
The timeout for the background reconnect tasks. The value is in milliseconds.
If a number of connections are down, the next client EJB invocation will use an algorithm to decide if a reconnect is necessary to find the right node.
- remote.connection.CONNECTION_NAME.connect.timeout
The timeout period for the initial connection. After that, the reconnect task will periodically check whether the connection can be established. The value is in milliseconds.
remote.connection.CONNECTION_NAME.connect.timeout默认值为5000ms(参见代码InitialContextFactory.getInitialContext),当在timeout时间内连接不上时,就会报以上错误。
3. 关于Rollback
EJB方法抛出RuntimeException会引起rollback,那有方法指定某个Exception是否引起Rollback么?可以使用注解@ApplicationException,如下:
@ApplicationException(rollback = true)
public class MyException extends Exception {
// ...
}
4. How to close scoped EJB client contexts?
Internally, when a lookup happens for a ejb: URL string, a relevant javax.naming.Context is created for that ejb: lookup.
So we first create a JNDI context and then use it to lookup an EJB.
final Properties props = new Properties();
// mark it for scoped EJB client context
props.put("org.jboss.ejb.client.scoped.context","true");
// add other properties
props.put(....);
...
Context jndiCtx = new InitialContext(props);
Context ejbRootNamingContext = (Context) jndiCtx.lookup("ejb:");
try {
final MyBean bean = ejbRootNamingContext.lookup("app/module/distinct/bean!interface"); // rest of the EJB jndi lookup string
bean.doSomething();
} finally {
try {
// close the EJB naming JNDI context
ejbRootNamingContext.close();
} catch (Throwable t) {
// log and ignore
}
try {
// also close our other JNDI context since we are done with it too
jndiCtx.close();
} catch (Throwable t) {
// log and ignore
}
}
Invoking Session Beans
Scoped EJB client contexts
How to configure an EJB client in JBoss EAP 6
分享到:
相关推荐
myeclipse 远程调试jboss as7或者jboss eap6,包括windows运行环境和linux运行环境分别介绍,同时jboss as7和jboss eap6的配置也有所不同。
jboss7以上版本发布ejb时需要的配置文件,jboss-ejb3.xml和ejb-jar.xml,缺少csdn分数所以上传,请见谅。
jboss eap 6.2或as 7 以上乱码问题解决
JBOSS EAP6安装部署手册 windows平台
jboss-eap-6.4.0.zip
JBoss 企业级应用程序平台 5.0 安装指南
jboss_EAP 部署在Window平台上
jboss-eap-7.1.0 jboss-eap-7.1.0 jboss-eap-7.1.0 jboss-eap-7.1.0 jboss-eap-7.1.0
jboss7.1.1 final部署EJB3
Jboss 7 + EJB 3.0 + Eclipse环境配置
Tomcat下web工程调用JBOSS部署的EJB项目 此源码包 包括local本地调用及remote远程调用 文档说明在http://blog.csdn.net/heardy/article/details/6906225
jboss下部署ejb详细步骤
jboss-eap-6.2.0,javaweb的服务器,性能稳定, 比jboss4更好用
jboss7.1+ejb3.1建立第一个Ejb项目希望可以帮到你
jboss-eap-6.3.0 ,windows 64位 安装包,可用的,欢迎下载
自己经过实践总结出来的jboss和jboss7访问EJB的方法,经过试验证明方法无误,这么好的资源还不赶快下载!
jboss-eap-5.0.2.zip,来自于官网,因为改动代码需要用到比较老的jboss-eap包,所以自己找到了这个资源,免费共享给大家,适用于JDK1.6
JBOSS上EJB的配置、部署,以及JBOSS中EJB的开发
jboss7下的ejb3开发的实例,从jboss官方文档中的代码示例中拷贝到本地工程中,亲测可用,附件是完整的工程。包括一个stateless session和一个stateful session,包括测试客户端。
JBoss支持EJB 1.1和EJB 2.0 EJB3.0的规范,它是一个管理EJB的容器和服务器。类似于Sun's J2SDK Enterprise Edition(J2EE),JBoss的目标是一个源代码开放的J2EE环境。但是JBoss核心服务仅是提供EJB服务器。JBoss不...