Jboss EAP 6 EJB调用常见问题
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);
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) { }
- }
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();
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>
<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>
<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参数:
- invocation.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.
- reconnect.tasks.timeout
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
- }
- }
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
} }
How to configure an EJB client in JBoss EAP 6
Jboss EAP 6 EJB调用常见问题的更多相关文章
- JBoss部属和EJB调用-EJB3.0入门经典学习笔记(2)
目录 1. 在JBoss中部属 2. 在Tomcat中调用EJB 3. 在JBoss中调用EJB 1. 在JBoss中部属 1) JBoss的配置目录 路径D:\Java\jboss6\serv ...
- 需要安全认证的远程EJB调用示例(Jboss EAP 6.2环境)
一,Remote EJB 服务接口定义: package yjmyzz.ejb.server.helloworld; public interface HelloWorldService { publ ...
- JBOSS EAP 6 系列四 EJB实现——调用(贯穿始终的模块)
本文主要介绍在JBOSS EAP 6.2(或者JBOSS AS7)中模块是如何贯穿EJB实现的始终.延续上一博文<认识模块的使用>的话题继续聊JBOSS做为模块申明式容器的这一特性在EJB ...
- JBOSS EAP 6 系列一 新特性
在项目中,采用的架构是Springmvc+spring+EJB+Jpa等架构,当然服务器是Jboss,本次Jboss我们采用的是JBossEap6.2,Jboss7的新特性与Jboss4.5的大的改变 ...
- 如何让jboss eap 6.2+ 的多个war应用共享 jar 包?
weblogic有一个很贴心的功能,允许把多个war应用共同依赖的jar包,打包一个单独的war,以libary方式部署,然后各应用在weblogic.xml里声明引用该libary即可,这样可大大减 ...
- jboss EAP 6.2 + Message Drive Bean(MDB) 整合IBM Webshpere MQ 7.5
上一篇我们知道了消息驱动Bean的基本用法,实际大型分布式企业应用中,往往会采用高性能的商业Queue产品,比如IBM Webshpere MQ(目前最新版本是7.5 ),下面讲解下如何在Jboss ...
- JBoss+Ant实现EJB无状态会话bean实例
EJB分为session bean.entity bean.message-driven bean,session bean又分为无状态会话bean和有状态会话bean. session bean负责 ...
- JBOSS EAP实战(1)
JBOSS的诞生 1998年,在硅谷SUN公司的SAP实验室,一个年轻人正坐在电脑前面思考,然后写着什么东西.不,他没有在写程序,他在写辞呈.他正在做出人生的一个重大决定:他要辞掉在SUN的这份工作, ...
- WebLogic Server 12c相对JBoss EAP 6的优势
原文来自:https://blogs.oracle.com/middlewareplace/entry/why_should_you_choose_oracle 1.多数据中心部署和集群 WebLog ...
随机推荐
- 前端通信:ajax设计方案(八)--- 设计请求池,复用请求,让前端通信快、更快、再快一点
直接进入主题,本篇文章有点长,包括从设计阶段,到摸索阶段,再到实现阶段,最后全面覆盖测试阶段(包括数据搜集清洗),还有与主流前端通信框架进行对比PK阶段. 首先介绍一下一些概念: 1. 浏览器的并发能 ...
- 轻量级web富文本框——wangEditor使用手册(6)——配置“上传图片”功能
最新版wangEditor: 配置说明:http://www.wangeditor.com/doc.html demo演示:http://www.wangeditor.com/wangEditor/d ...
- 你真的理解编码吗?unicode,utf8,utf16详解
背景 前两天在网上看到一篇关于编码的讨论,仔细学习了一下unicode,utf8,utf16的定义.这篇博客旨在让读者真正理解他们是什么. 什么是编码 在阅读本文之前建议读者先去阅读这篇文章:http ...
- 《Netty权威指南》目录
一.基础篇 走进Java NIO 1. Java 的 I/O 演进之路:https://www.cnblogs.com/zengzhihua/p/9930652.html 2. NIO 入门:http ...
- GitHub多人协作简明教程
本文面向已经了解/熟悉git基本命令但是并不熟悉如何使用GitHub进行多人协作开发项目的同学. 为了简单起见,这里假设只有两个开发人员,HuanianLi 和 DaxiangLi.他们在GitHub ...
- Tomcat学习总结(7)——Tomcat与Jetty比较
Jetty 基本架构 Jetty目前的是一个比较被看好的 Servlet 引擎,它的架构比较简单,也是一个可扩展性和非常灵活的应用服务器. 它有一个基本数据模型,这个数据模型就是 Handler(处理 ...
- 开源方案搭建可离线的精美矢量切片地图服务-8.mapbox 之sprite大图图标文件生成(附源码)
项目成果展示(所有项目文件都在阿里云的共享云虚拟主机上,访问地图可以会有点慢,请多多包涵). 01:中国地图:http://test.sharegis.cn/mapbox/html/3china.ht ...
- 拓展KMP算法详解
拓展KMP解决的问题是给两个串S和T,长度分别是n和m,求S的每一个后缀子串与T的最长公共前缀分别是多少,记作extend数组,也就是说extend[i]表示S[i,n-1](i从0开始)和T的最长公 ...
- el-upload源码修改跳坑
之前给element-ui提了一个问题,结果没有鸟我,没办法,只能修改源码来满足需求了 (备注:element-ui2依然没有修改,为了迎合产品还是要改源码) 本文讨论的组件属性仅限于list-typ ...
- VC++6.0调试:Watch窗口的使用
#include <stdio.h> #include <windows.h> class AutoExpand { public: AutoExpand(int val, c ...