CSDN博客

img zlsunnan

恶斗EJB(二)

发表于2004/10/11 11:50:00  3078人阅读

我们的最终目的是在不同的机器上调用EJB,下面就该体验分布式了。
在另外一台机器上,架起一个Server,把EJB部署上去,然后改动client代码中的IP,准备,跑!
成功了吗?
我期望的是失败。
如果你看见了来自远程的问候,先别兴奋,看看运行client的机器上是否还跑着一个J2EE RI呢?
我调的是远程的EJB,和我本机起的server有什么关系呢?先别管这些,关了它。
恭喜你,代码终于正常的失败了。

谁愿意面对失败呢?出现了问题,我们要做就是解决它。
异常的提示是个不错的起点。
    javax.naming.CommunicationException: Can't find SerialContextProvider
        at com.sun.enterprise.naming.SerialContext.getProvider(SerialContext.java:63)
        at com.sun.enterprise.naming.SerialContext.lookup(SerialContext.java:120)
        at javax.naming.InitialContext.lookup(Unknown Source)
        ……
显然,这不是很好的提示,因为我们无法通过异常信息获得更多,但我们知道了出现错误的类。
幸运的是,SUN的J2EE RI源代码是公开的,这样我就省去了反编译class文件的麻烦。
打开com.sun.enterprise.naming.SerialContext这个类,找到getProvider,其中的一个debug变量引起了我的兴趣,这是一个调试的标志,只要把它置为true,一些调试信息就会流出来。
我肯定了自己的想法,改变debug,但如何来编译源代码呢?
我并不想费尽心力去编译J2EE RI庞大的源码,毕竟我需要的只是改变其中的一个类,而不是研究整个J2EE RI。

挥出自己常用法宝,在自己的IDE中建立,建立起一个工程之后,直接把包含目标类的JAR文件(可能还有一些比较的JAR文件)加入工程,这样编译这个类所需的全部内容就都有了。
取过我的目标类,按照包结构放入工程之中,这样代码应该就可以正常编译了。
将改动后的class文件再塞进JAR,这样我的改动就开始发挥作用了。

通过改动,我们可以多一些信息。
    org.omg.CORBA.COMM_FAILURE:   vmcid: SUN  minor code: 201  completed: No
        at com.sun.corba.ee.internal.iiop.ConnectionTable.getConnection(ConnectionTable.java:176)
        at com.sun.corba.ee.internal.iiop.ConnectionTable.getConnection(ConnectionTable.java:68)
        at com.sun.corba.ee.internal.iiop.GIOPImpl.getConnection(GIOPImpl.java:70)
        ……
CORBA错误?是的,CORBA。这就不太好办了,虽然听说过EJB和CORBA之间千丝万缕的联系,但是我可是标准的CORBA门外汉。
在下定决心不去从头学习CORBA之后,我决定继续用前面的手法挖掘问题的原因。

逆流而上的结果是我发现了这样的信息。
    com.sun.corba.ee.internal.iiop.GIOPImpl(Thread[main,5,main]): getEndpoint(IIOP_CLEAR_TEXT, 0, null)
    com.sun.corba.ee.internal.iiop.GIOPImpl(Thread[main,5,main]): createListener( socketType = IIOP_CLEAR_TEXT port = 0 )
    com.sun.corba.ee.internal.iiop.ConnectionTable(Thread[main,5,main]): Client get called: host = localhost port = 1050
    com.sun.corba.ee.internal.iiop.ConnectionTable(Thread[main,5,main]): Exception java.lang.RuntimeException: Connection refused: connect while creating socket for new connection: aborting connection
    com.sun.corba.ee.internal.iiop.ConnectionTable(Thread[main,5,main]): DeleteConn called: host = localhost port = 1050
    com.sun.corba.ee.internal.iiop.ConnectionTable(Thread[main,5,main]): Client get called: host = localhost port = 1050
很奇怪吧!这里出现了localhost。从直觉来说,我们明明在代码中写了调用远程的EJB,应该根本没有localhost什么事。事实就是这样奇怪,调用的时候居然先走localhost,这也就是为什么如果本机起的一个J2EE RI,我们就可以看到来自远方的问候。
就在我疑惑不知该如何走下一步时,无意之举给了我新的方向。
我翻起了J2EE RI配套的文档。没错,之前我一直在自行探索。
在J2EE SDK Tools的文档中,runclient的讲解中有一个小节,其标题是《Accessing a Remote Server》,显然这对我是个极大的触动。
其中提到了一个属性“org.omg.CORBA.ORBInitialHost”。
设置这个属性就可以访问远程EJB???
还等什么?
我们知道在Java运行时以-D定义一个属性同直接在代码中使用System.setProperty具有相同的功效,于是代码中出现了这样一段:
System.setProperty("org.omg.CORBA.ORBInitialHost", "xxx.xxx.xxx.xxx");
运行,祈祷!
来自远方的问候终于出现在我的面前,那种激动相信是程序员无数次经历却依然愿意体味的感觉。我愿意把这种感觉与吸毒等同起来,完全是一种瘾,这是这种瘾让我愿意迎接一次又一次的挑战,克服一个又一个的困难。

“众里寻她千百度,蓦然回首,那人却在灯火阑珊处”
应该说我的习惯并不好,在我自己绞尽脑汁独自摸索时,在我挥动google四处搜寻时,我居然没有想过自己的身边已经有了最好的答案。
以此为戒,以后解决问题时,先要了解配套文档中有哪些内容。

阅读全文
0 0

相关文章推荐

img
取 消
img