CSDN博客

img zlsunnan

恶斗EJB(五)

发表于2004/10/11 11:53:00  1179人阅读

SUN工程师的回复中,我得到了另外一个有用的信息,在SUN ONE Application Server的安装目录下的samples/rmi-iiop/simple有一个完整的普通应用调用EJB的例子。
赶紧操练起来,按照文档一步一步走来,很是轻松愉悦,除了EJB Stub,还要用到应用服务器安装目录的lib目录下appserv-ext.jar。
走到“Local or remote RMI/IIOP-based client without ACC(Application Client Container)”的一节,同样的问题出现了,程序运行起来就僵死在那里,没有反应。
怎么又是这样?在我确定了我确实是按照文档一步一步走下来的,我有了一种束手无策的感觉。
穷极无聊之际,我扫了一眼Troubleshooting:
如果运行应用出现了任何问题,看一下server的日志。
嗯?是啊!我光顾着client端了,竟然根本没有想过server端。打开server的日志,一个异常让我眼前一亮:
com.iplanet.ias.cis.connection.ConnectException: com.iplanet.ias.cis.channel.tcp.TCPNativeException: -5973:EndPoint.JNI_getValidAddressNative: PR_GetHostByAddr() Failed
        at com.iplanet.ias.cis.connection.Connection.<init>(Connection.java:205)
        at com.iplanet.ias.cis.connection.ServerConnection.accept(ServerConnection.java:251)
        at com.sun.corba.ee.internal.iiop.ListenerThread.run(ListenerThread.java:77)
Caused by: com.iplanet.ias.cis.channel.tcp.TCPNativeException: -5973:EndPoint.JNI_getValidAddressNative: PR_GetHostByAddr() Failed
        at com.iplanet.ias.cis.connection.EndPoint.getValidAddressNative(NativeMethod)
        at com.iplanet.ias.cis.connection.EndPoint.getValidAddress(EndPoint.java:239)
        at com.iplanet.ias.cis.connection.EndPoint.<init>(EndPoint.java:101)
        at com.iplanet.ias.cis.connection.EndPoint.getEndPoint(EndPoint.java:73)
        at com.iplanet.ias.cis.connection.EndPoint.getEndPoint(EndPoint.java:78)
        at com.iplanet.ias.cis.channel.tcp.TCPChannel.getPeerEndPoint(TCPChannel.java:74)
        at com.iplanet.ias.cis.connection.Connection.<init>(Connection.java:201)
        ... 2 more
虽然单凭这个异常,我无法得知问题所在,但这比漫无目的的搜寻显然好上许多。

再次向SUN工程师请教。很快,我得到了回复。显然,这个问题对于SUN的工程师来说已经是轻车熟路了。
RMI通信的时候,需要主机地址解析,只要在两台机器互相把主机名和IP放到hosts配置文件中就可以了。
在WinXP上,这个文件是C:/WINDOWS/system32/drivers/etc的目录下hosts,在Solaris上,这个文件是/etc/hosts。
在文件中加入IP和主机名的映射
    xxx.xxx.xxx.xxx hostname

运行,bingo,成功!
SUN工程师的答案果然见效。只是我想不通,我用的是IP直连,这和主机名有什么关系。显然,这让人不爽,因为将来部署的时候,这肯定需要写在安装手册里,增加复杂度,牵扯得不仅仅是应用本身的部署了。

再来试试自己的例子。显然我前面的思路多少有些偏差,没有加入EJB Stub确实是个问题,但并不是根本原因,地址解析才是我的代码僵死的元凶。
好了,加入EJB Stub和appserv-ext.jar,运行,我终于见到了期盼已久的问候。
在这个调用中,我并没有使用ORB的那两个参数,这大概也算是J2EE RI和SUN ONE Application Server的差异之一吧!不过后来的事实证明,这并非一个不可逾越的鸿沟。
原来的异常出现在server端,client端为什么也要加呢?于是,我去掉了client端IP和主机名的映射,使用IP调用没问题,使用主机名调用的时候,抛出了个无法连接ORB的异常。没问题,和我预想的一样。

再接再厉,尝试在Servlet中调用。
因为Servlet最终要运行在应用服务器上,所以我省去了appserv-ext.jar,只加入了EJB Stub。写程序,

配参数,部署……
又出问题了,它怎么提示我<ejb-link>的参数不对。这是一个用来在Servlet中指示欲使用的EJB名称的参数。难道它让我把EJB应用也加进去,那还是一个单纯的Web应用了吗?
瞎猫总能碰到死耗子。当我糊涂的把EJB Stub作为一个Module加入到Web应用中,居然部署成功了。
敲入URL,又是半天没响应,这次可有经验了,赶紧把那台机器的IP和主机名加到部署EJB的服务器上。
OK,成功!

终于搞定了在SUN ONE Application Server上远程调用EJB的问题,最初设置的一个参数又引起了我的兴趣。前面的设置有这样一句:
    env.put("java.naming.factory.initial", "com.sun.jndi.cosnaming.CNCtxFactory");
这个com.sun.jndi.cosnaming.CNCtxFactory并不是J2EE包特有的,而是存在于rt.jar中,换句话说,它是J2SE中的。那它是否可以用在J2EE RI上呢?
带着这个问题,我翻出之前的那个例子,改动了参数,去掉ORB的那两个参数。
运行,Hello来了。
原来可以这么调。早知如此,何必当初呢!

总结一下,算是个经验和教训的集合吧!
J2EE RI和SUN ONE Application Server通用的调用远程EJB的参数是:
    java.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
    java.naming.provider.url=iiop://host:port

如果使用的是SUN ONE Application Server,调用远程EJB需要在部署EJB的机器上hosts配置文件中加入调用端IP和主机名的映射。
如果调用端在IIOP参数中使用的是主机名,则需要在其hosts配置文件中加入部署EJB的机器的IP和主机名的映射。
在WinXP上,hosts配置文件是C:/WINDOWS/system32/drivers/etc的目录下hosts;在Solaris上,这个文件是/etc/hosts。
在文件中加入IP和主机名映射的方式是
    xxx.xxx.xxx.xxx hostname

又是一场恶斗,虽然精疲力竭,却也心情愉悦!战斗后的胜利感觉,总是最美妙的。

阅读全文
0 0

相关文章推荐

img
取 消
img