您的位置:首页 > 运维架构 > Tomcat

tomcat 调用websphere application server 中的EJB(soap over jms)

2009-07-11 11:03 411 查看
最近在做websphere application server 中的EJB,在用RAD生成客户端时,远程调用测试代码时运行正常,但当在Tomcat中用同样的代码时,出现不能初始InitialContext获得的是null.

在网上看到如下文章:

下面介绍一下如何通过一般的Web服务器,访问WAS的EJB,下面以TOMCAT为例。
Tomcat访问WAS的EJB1.x, 通过RMI-IIOP协议,实现分步式系统(解决方案3)下面介绍一下如何通过一般的Web服务器,访问WAS的EJB,下面以TOMCAT为例。
为什么会单独讲 WAS的EJB的访问呢,其实WAS 与 weblogic , jboss等服务器的机制稍微有一点不太一样。像weblogic, jboss可以直接通过下面的方式远程连接。

JBOSS为例。
Properties env = new Properties();
env.put("xxx","xxx");
//也可以定义在一个properties文件中,not hardcode,方便修改)
//如:java.naming.factory.initial java.naming.provider.url java.naming.factory.url.pkgs等
Context ctx = new InitialContext(System.getProperties());
env.put("xxx","xxx");
prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
prop.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:-Org.jnp.interfaces");
prop.put(Context.PROVIDER_URL, "jnp://localhost:1099");

当然,JBoss的端口是1099, WebLogic的使用的是自己的t3协议t3://localhost:7001端口是7001。这两个服务器,直接通过这样的写法,就可以得到 Context的环境,然后利用context.lookup("xx"),进行JNDI的查找。

WAS的由于内部的实现机制稍有不同,因此也像上面的写的法,是不能得到Context完全的环境的。也就是说,从外部获得的Context是空的。

WAS教程中提供的参考写法如下:(同的was的工程,可以连通,但是tomcat或者其他的环境,就没办法连接了)
Properties props = new Properties();//System.getProperties();
props.put("java.naming.factory.initial", "com.ibm.websphere.naming.WsnInitialContextFactory");
props.put("Context.PROVIDER_URL", "iiop://localhost:2809/");

上面是教程中提供的参考写法,只能在WAS环境中,进行连接可以成功。非WAS的环境,因为不能获得正确的Context,因此不能够连接成功。为什么会 出现这种情况呢??我查了一下相关的文档,上面的写出,WAS的环境,是在WAS启动以后,自动进行构建的,也就是说你只要在部署在同一个WAS上面的不 同工程,通过Properties props = System.getProperties();就可以获得WAS上面,全局的Context的环境,这个过程是WAS自动进行构建,因此不用自己写初始 化的条件,他有一些默认的设置值。这一点,也就是不同于其他容器的差别了。因此,如果想使用TOMCAT调用WAS的EJB,其实也没这么简单的。

明白了上面的原理,和之前对JNDI及Context的一些背景知识,其实最关键点是如何得到WAS 的Context。我在程序中,输出了一个可能连接成功的props属性,和Context的环境,有如下的系统配置参数。
{
com.ibm.websphere.naming.hostname.normalizer=com.ibm.ws.naming.util.DefaultHostnameNormalizer,
java.naming.factory.initial=com.ibm.websphere.naming.WsnInitialContextFactory,
com.ibm.websphere.naming.name.syntax=jndi,
com.ibm.ws.naming.ldap.ldapinitctxfactory=com.sun.jndi.ldap.LdapCtxFactory,
com.ibm.websphere.naming.namespace.connection=lazy,
com.ibm.websphere.naming.jndicache.cacheobject=populated,
com.ibm.websphere.naming.namespaceroot=defaultroot,
Context.PROVIDER_URL=iiop://localhost:2809/,
com.ibm.ws.naming.implementation=WsnIpCos,
com.ibm.ws.naming.wsn.factory.initial=com.ibm.ws.naming.util.WsnInitCtxFactory,
com.ibm.websphere.naming.jndicache.maxcachelife=0,
com.ibm.websphere.naming.jndicache.maxentrylife=0,
com.ibm.websphere.naming.jndicache.cachename=providerURL,
java.naming.provider.url=corbaloc:rir:/NameServiceServerRoot,
java.naming.factory.url.pkgs=com.ibm.ws.runtime:com.ibm.ws.naming,
Context.INITIAL_CONTEXT_FACTORY=com.ibm.websphere.naming.WsnInitialContextFactory
}

我想这也许,就是真正可以实现远程连接WAS的参数。所以,修改上面的程序。
Properties props = new Properties();//System.getProperties();

props.put("java.naming.factory.initial", "com.ibm.websphere.naming.WsnInitialContextFactory");
props.put("Context.PROVIDER_URL", "iiop://localhost:2809/");
props.put("com.ibm.websphere.naming.name.syntax","jndi");

props.put("com.ibm.websphere.naming.name.syntax","jndi");
props.put("com.ibm.websphere.naming.namespace.connection","lazy");
props.put("com.ibm.websphere.naming.jndicache.cacheobject","populated");
props.put("com.ibm.websphere.naming.namespaceroot","defaultroot");
props.put("com.ibm.ws.naming.implementation","WsnIpCos");
props.put("com.ibm.ws.naming.wsn.factory.initial","com.ibm.ws.naming.util.WsnInitCtxFactory");
props.put("com.ibm.websphere.naming.jndicache.cachename","providerURL");
props.put("java.naming.factory.url.pkgs","com.ibm.ws.runtime:com.ibm.ws.naming");
props.put("java.naming.provider.url","corbaloc:rir:/NameServiceServerRoot");

Context ctx = new InitialContext(props);

Object obj = ctx.lookup("ejb/org/conan/session/HelloSessionHome");
HelloSessionHome home = (HelloSessionHome) PortableRemoteObject.narrow(obj,HelloSessionHome.class);

把参数都写入到props里面再初始化,启动程Context里面,终于获得了WAS的环境,我的EJB也连接成功了。这里还要注意的一点是,JDK的环境必需是WAS 的Runtime环境,包括了IBM JRE, 和 WAS的Runtime JAR.

我机器的参考路径为:
WAS RUNTIME = ../IBM/Rational/SDP/6.0/runtimes/base_v6/lib
IBM JRE = ../IBM/Rantional/SDP/6.0/runtimes/base_v6/java/jre/lib 和 ../IBM/Rantional/SDP/6.0/runtimes/base_v6/java/jre/lib/ext
client程序,连接成功。

下面把连接在Client端的连接程序的程序,放到tomcat里面,设置TOMCAT的启动环境,使用IBM JDK,然后再把WAR RUNTIME的JAR包,放到TOMCAT的路径下面,就可以成功实现Tomcat访问WAS的EJB1.x, 通过RMI-IIOP协议。

最后要的实现分步式系统,就看你自己的设计了,因为从技术上已经解决了。

解决方案的优缺点:
优点:
1. 充分利用了WAS作为Application Server,发布Remote接口的EJB,通过多种服务器的整合实现分布式系统。
2. WAS的Application Server的资源,只用来处理复杂的数据计算,而把简单的Jsp/Servlet的解析的工作,交给其他的服务器处理,充分利用资源。

缺点:
1. 必需依赖于WAS的环境。
2. EJB1.X的解决方法,还是太过于复杂,不利于开发,维护,调试等的工作,并要求开发人员的能力较高。
3. 这种分布式的应用,在一般企业应用的情况下不会出现。
4. EJB1.X的系统相对来说,封闭性还是比较高,很多情况不如WS,JMS来的方便。

最后总结,这种EJB的升级方案,虽然我自己测试成功,但是如果真的要开始实施,还是有诸多的麻烦之处。因此,下一篇文章,我会解决一种轻量级的解决方案。





这样环境设置好后,运行client程序,连接成功。

下面把连接在Client端的连接程序的程序,放到tomcat里面,设置TOMCAT的启动环境,使用IBM JDK,然后再把WAR RUNTIME的JAR包,放到TOMCAT的路径下面,就可以成功实现Tomcat访问WAS的EJB1.x, 通过RMI-IIOP协议。

最后要的实现分步式系统,就看你自己的设计了,因为从技术上已经解决了。

解决方案的优缺点:
优点:
1. 充分利用了WAS作为Application Server,发布Remote接口的EJB,通过多种服务器的整合实现分布式系统。
2. WAS的Application Server的资源,只用来处理复杂的数据计算,而把简单的Jsp/Servlet的解析的工作,交给其他的服务器处理,充分利用资源。

缺点:
1. 必需依赖于WAS的环境。
2. EJB1.X的解决方法,还是太过于复杂,不利于开发,维护,调试等的工作,并要求开发人员的能力较高。
3. 这种分布式的应用,在一般企业应用的情况下不会出现。
4. EJB1.X的系统相对来说,封闭性还是比较高,很多情况不如WS,JMS来的方便。

原文引自:http://gocom.primeton.com/blog9621_14478.htm?PHPSESSID=%3C
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: