精华帖 (0) :: 良好帖 (0) :: 新手帖 (9) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-11-19
最后修改:2008-11-19
这个年代还在写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 组件作为资源注入客户端的运行环境。标签里的具体内容仅作示例。 说明一下: 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 世界里最恶心的事情之一,与智力无关,只是太麻烦了。
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-11-19
虽然没用过ejb3以前的版本,不过还是支持你.
象这样解决实际问题的帖子网上实在太少了,所谓的什么高人动辄高谈阔论SOA,SOP,真的要解决实际问题的时候总是理论跟实际脱节. 再牛逼的技术,再先进的理念,不能拿来实际应用于生产,都只是垃圾... |
|
返回顶楼 | |
发表时间:2008-11-19
吐血,单是让 EJB 2.x 跑一个 HelloWorld 都很难……
不过 HelloWorld 能跑了,后面的就都简单了。 |
|
返回顶楼 | |
发表时间:2008-11-19
兄弟,慢慢来吧,像EJB这类的资料确实难找,找个人问都不易啊
想当初我本地BES启动不了,花了近三四个月的时间才解决 期间还好有个测试服务器供我用,不然还不愁死啊 我现在最深的感受就是,不到万不得已决不问人 有问题自己找资料,调试,看日志,我就不信还解决不了了! |
|
返回顶楼 | |
浏览 3272 次