`
jeff312
  • 浏览: 77319 次
  • 性别: 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,真的要解决实际问题的时候总是理论跟实际脱节.


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

相关推荐

    EJB在很多企业中的面试题

    - 不得使用AWT,以确保UI组件不会与EJB组件混合。 - 不得实现服务器功能,保持组件的纯粹性。 - 避免静态属性的使用,防止跨实例数据污染。 - 不允许直接进行文件IO操作,以提高组件的可移植性。 - 不得加载本地库,...

    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....

    EJB3规范简化版中文版

    EJB (Enterprise JavaBeans) 是 Java 平台为企业级应用提供的一种组件模型。EJB3 是 EJB 的最新版本,相较于之前的版本,它进行了大幅度的简化和改进,引入了许多新的特性来提高开发效率并降低复杂度。 **EJB3 规范...

    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....

    EJB COOKBOOK

    **知识点:** 在 EJB 应用程序内部,可以通过直接调用本地接口(Local Interface)的方式来访问同一容器内的其他 EJB 组件。这种方式不需要进行远程调用,因此效率更高。 **应用场景:** 当一个 EJB 需要调用同一容器...

    葵花宝典之JAVA中高级笔试&面试经典题型总汇.doc

    Remote 和 Local 接口定义了客户端与 EJB 交互的方式,Home 接口负责实例化 Bean,而 Bean 类则是业务逻辑的载体。 2. EJB 的三种类型及其作用和实现技术: - 会话 Bean(Session Beans):分为有状态和无状态两种...

    《软件构件与中间件技术》全真试题

    - **Remote(或/和Local)接口**:定义远程访问或本地访问接口。 - **Home(或/和LocalHome)接口**:定义如何创建和查找bean实例的方法。 ### 11. J2EE 平台的事务控制服务 - 事务控制可以保证事务所包含的一系列...

    基于J2EE的人力资源管理系统分析与设计

    业务组件通过EJB容器内部的EJB组件实现。此层主要由会话Bean、容器管理的实体Bean等组成。 ##### 业务逻辑层详细设计 - **会话Bean**:会话Bean是业务逻辑层中的关键组件之一,用于处理具体的业务逻辑。会话Bean...

    《软件构件与中间件技术》全真试题[借鉴].pdf

    - 编写EJB涉及Enterprise bean类、Remote(或Local)接口以及Home(或LocalHome)接口。 11. **J2EE平台的事务控制服务**: - 事务控制确保了操作的原子性和一致性,增强了应用的安全性。 以上知识点涵盖了软件...

    JAVA模拟题笔记,亲自整理

    - EJB包含Remote(Local)接口、Home(LocalHome)接口和Bean类,Enterprise Bean Provider是提供EJB的服务器组件。 **名词解释**: - **JNDI**:Java Naming and Directory Interface,用于查找和访问分布式环境...

    一家公司的面试题

    - **EJB LocalHome**:LocalHome在EJB中用于创建和查找企业bean实例,提供业务方法的入口。 4. **程序测试题**: - **MyString类**:尝试扩展不可扩展的String类,`i++`在静态初始化块中,每次类加载时执行一次。...

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

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

    java基础问题集合

    - **EJB的角色和对象**:角色涉及开发者、应用组装者、部署者、系统管理员等,主要对象包括Remote(Local)接口、Home(LocalHome)接口和Bean类。 - **EJB的类型**:分为会话Bean(Session Bean)、实体Bean...

    中软面试题,我感觉很有用

    * EJB 的角色和三个对象:Remote(Local)接口、Home(LocalHome)接口、Bean 类 * EJB 的几种类型:会话(Session)Bean、实体(Entity)Bean、消息驱动的(Message Driven)Bean * bean 实例的生命周期 * 激活机制...

    java-软件工程师试题.pdf

    10. **EJB中的LocalHome接口**用于创建实体Bean的本地实例,提供了一种在容器内部查找和操作Bean的方法。 **程序测试题**涉及类的继承、构造器、变量作用域、静态变量、方法覆盖等概念,具体答案需要根据题目给出的...

    JAVA 面试题

    2. EJB角色与对象:Bean开发者、应用组装者、部署者等角色,Remote(Local)接口、Home(LocalHome)接口和Bean类是核心对象。 3. EJB类型:会话Bean(状态ful/less)、实体Bean(Bean/Container管理的持续性)和...

Global site tag (gtag.js) - Google Analytics