`
jeff312
  • 浏览: 76317 次
  • 性别: Icon_minigender_1
  • 来自: 新加坡
社区版块
存档分类
最新评论

使用 Local 与 LocalHome 访问 EJB 组件 -- 解惑篇

    博客分类:
  • J2EE
阅读更多

    这个年代还在写EJB 2.1的东西感觉很怪,毕竟我在网上寻找答案的时候发现绝大多数提问的帖子都是04年以前的了,如今也没什么人还会用EJB 2.1以下的版本做项目。然而,实际生产总是跟不上潮流的,公司里需要我维护的还是EJB 1.x 与 2.x 的系统呢,不学也是没办法。

   

    写这篇文章,一来是为了帮自己记着点,二来是看到相关问题在网上总是找不到满意的答案,被提问的高手(或假高手)大都语焉不详,解释了半天也没提供一点可操作性,甚是失望。查书的结果也让人沮丧。死样活气的 “NameNotFoundException” 简直把人气到无语。如今把搜索了好几天、研究了好几天的成果写下来,只怕不会因为它基础、简单而毫无价值。废话少说,开始吧。



    1. 要使用本地接口访问 EJB,首先自然是在 ejb-jar.xml 里面规定 <local> 和 <local-home> 接口的类(当然前提是你已经写好了这两个接口,不要笑,不少初学都会摆这个乌龙)。这里需要注意的是, EJB 2.x 的规范是不允许同时配置本地和远程接口的,你只能选择其中一个,这一点只要在一个有 xml 检查机制的编辑器(如 MyEclipse 自带的编辑器,或者大名鼎鼎的 XMLSpy )里就可以看出来。


    2. 其次,在客户端(我一般是用 servlet,jsp 也可以。注意不能用独立客户端,它只能用远程方式访问 EJB )写调用代码。写法99%和远程访问差不多,需要改的地方只有三个:

         a) 所有的接口引用都改成对应的本地接口,如 ProductHome --> ProductLocalHome, Product --> ProductLocal 等。

      b) PortableRemoteObject.narrow() 方法不需要了,直接强制转型即可。参考这里的讨论: http://topic.csdn.net/t/20040419/09/2981624.html

      c) 在做 context.lookup() 的时候,查找字串必须是 "java:comp/env/xxx" 的格式,这里要注意 xxx 不再是所调 EJB 的 jndi 名了,你可以自由指定,原因后面再说。

 

    3. 配置 ejb-jar.xml 或 web.xml 文件。这一步最关键,因为大多数人都是在这里崩溃的,遇到 NameNotFoundException 一点都不美。这里到底是配置 ejb-jar.xml 还是 web.xml 呢,这就看你的“客户端”是什么了。如果你使用 session bean 来访问 entity bean (其实只要是两个EJB就适用,类型不限),那么就配置 ejb-jar.xml ; 如果用 servlet 或 jsp 来访问 EJB 就改 web.xml 。

       如果是 ejb-jar.xml, 则在<enterprise-beans><ejb>...</ejb></enterprise-beans> 中加入以下描述符;

       如果是 web.xml, 则在根标签<web-app>...</web-app> 中加入以下描述符;

 

  <ejb-local-ref>
      <ejb-ref-name>ejb/ProductLocal</ejb-ref-name>
      <ejb-ref-type>Entity</ejb-ref-type>
      <local-home>examples.cmp.ejb.ProductLocalHome</local-home>
      <local>examples.cmp.ejb.ProductLocal</local>
      <ejb-link>ProductEJB</ejb-link>
  </ejb-local-ref>

 

       这一段的作用是把一个本地 EJB 组件作为资源注入客户端的运行环境。标签里的具体内容仅作示例。 说明一下:

      1) <ejb-ref-name> 是客户端 lookup EJB 时的名字,也就是上面提到的 "java:comp/env/xxx" 里面的 xxx, 惯例是推荐前面都带一个ejb/ 的了,倒是无所谓。

      2) <ejb-link> 是该 EJB 资源的名字即它在自己的 ejb-jar.xml 里的<ejb-name>。

 

      到这里可能有人糊涂了,Jndi 在哪里呢?这正是本文的重点所在。事实上,通过本地接口来访问一个 EJB,客户端是不需要知道它的 Jndi 名字的,因为此时采用的是 link 的方式,通过 <ejb-link> 指定的相对路径来访问这个本地资源。与该 <ejb-link> 相对应的 <ejb-ref-name> 实质上就是客户端专有资源的一个 伪Jndi 名。真正的 Jndi 名只在远程调用的时候才有意义,那时候调用被调用双方的相对路径是未知的。 这里真伪 Jndi 有点像 成员变量 和局部变量的关系。

      那末,为什么我们在 lookup 的时候不能直接用 <ejb-ref-name> 里面的名字,而是还要加上 "java:comp/env/" 的前缀呢?粗糙点解释就是,这个前缀就是专门用来查找“伪Jndi”的。详细的讲解见 : http://www.blogjava.net/javababy/archive/2006/12/06/85881.html

 

     补充一点,由于 <ejb-link> 是本地相对路径的标识, 首先就限制了调用客户端和 EJB 必须位于同一个 application 即 ear 里。其次,如果 EJB 模块的 jar 包下面还有 包含 EJB 模块的 jar 包,在访问最里面的那个 EJB 的时候就需要把 jar 的路径也写进 <ejb-link> 里去,如 <ejb-link>SalesEJB.jar#ProductEJB.jar#ProductEJB</ejb-link>

 

    到这里,文章就算写完了。我是非常奇怪,这么一个基础而常见的问题,要找个现成的答案居然这么难。哎,很多人成了高手,就都忘了初学者的痛苦了,要知道,初学 EJB 2.x 可是 J2EE 世界里最恶心的事情之一,与智力无关,只是太麻烦了。

 

分享到:
评论
3 楼 ming_303 2008-11-19  
兄弟,慢慢来吧,像EJB这类的资料确实难找,找个人问都不易啊
想当初我本地BES启动不了,花了近三四个月的时间才解决
期间还好有个测试服务器供我用,不然还不愁死啊
我现在最深的感受就是,不到万不得已决不问人
有问题自己找资料,调试,看日志,我就不信还解决不了了!
2 楼 jeff312 2008-11-19  
吐血,单是让 EJB 2.x 跑一个 HelloWorld 都很难……

不过 HelloWorld 能跑了,后面的就都简单了。
1 楼 xixix2004 2008-11-19  
虽然没用过ejb3以前的版本,不过还是支持你.
象这样解决实际问题的帖子网上实在太少了,所谓的什么高人动辄高谈阔论SOA,SOP,真的要解决实际问题的时候总是理论跟实际脱节.


再牛逼的技术,再先进的理念,不能拿来实际应用于生产,都只是垃圾...

相关推荐

    javax.ejb.jar下载

    javax.ejb.LocalHome.class javax.ejb.Lock.class javax.ejb.LockType.class javax.ejb.MessageDriven.class javax.ejb.MessageDrivenBean.class javax.ejb.MessageDrivenContext.class javax.ejb....

    javax.ejb.rar

    javax.ejb.LocalHome.class javax.ejb.Lock.class javax.ejb.LockType.class javax.ejb.MessageDriven.class javax.ejb.MessageDrivenBean.class javax.ejb.MessageDrivenContext.class javax.ejb....

    javax.ejb.jar

    javax.ejb.LocalHome.class javax.ejb.Lock.class javax.ejb.LockType.class javax.ejb.MessageDriven.class javax.ejb.MessageDrivenBean.class javax.ejb.MessageDrivenContext.class javax.ejb....

    超级有影响力霸气的Java面试题大全文档

    但EJB必须被布署在诸如Webspere、WebLogic这样的容器中,EJB客户从不直接访问真正的EJB组件,而是通过其容器访问。EJB容器是EJB组件的代理, EJB组件由容器所创建和管理。客户通过容器来访问真正的EJB组件。 24、...

    java 面试题 总结

    但EJB必须被布署在诸如Webspere、WebLogic这样的容器中,EJB客户从不直接访问真正的EJB组件,而是通过其容器访问。EJB容器是EJB组件的代理,EJB组件由容器所创建和管理。客户通过容器来访问真正的EJB组件。 21、...

Global site tag (gtag.js) - Google Analytics