读书人

EJB2.1的localhome有关问题

发布时间: 2012-05-31 12:19:24 作者: rapoo

EJB2.1的localhome问题
最近要重构一批代码,某些EJB要改成local访问,于是先动手做了个简单例子做试验,没想到这里就碰了钉子。

首先说明,所有东西不变,只要改用remote和remoteHome接口就完全没问题

我用来试验的容器是glassfish u2

提示一直都是TestLocal not found (NameNotFoundException)

客户端Servlet的代码很简单:

Java code
Context ctx = new InitialContext();Object o = ctx.lookup("ejb/TestLocal");……

执行到第二句已经出错,后面的什么create()早就免谈。


网上搜到无数解决方案,对我都无效。先把试过的方案先摆一摆:

1. 在war包的WEB-INF里的web.xml里,加入<ejb-local-ref>标签内容如下:
XML code
  <ejb-local-ref>      <ejb-ref-name>ejb/TestLocal</ejb-ref-name>      <ejb-ref-type>Session</ejb-ref-type>      <local-home>com.jeff.TestLocalHome</local-home>      <local>com.jeff.TestLocal</local>      <ejb-link>TestLocalEJB.jar#TestLocal</ejb-link>  </ejb-local-ref>

结果,按照"ejb/TestLocal"或"TestLocal"去lookup,都一样失败。servlet和ejb在同一个ear,但不在同一个jar包里,所以<ejb-link>里才要采用引入jar的方法。

2. 看到有人说一定要在同一个包里才能用到localhome, 于是在同一个包里定义另一个stateless session EJB,并在其ejb-jar配置内容下加上以上同样的XML(ejb-link改成TestLocal),然后在其商业方法中尝试lookup TestLocalHome,结果同样失败。实际上我认为这种说法不过是第一步里ejb-link的一种简单化方案,两者之间没有本质区别。

3. 查找资料,发现本地接口是通过link方法实现的,与JNDI没有关系,因此上述XML应该没错。

4. 尝试servlet以外其他途径,如jsp,独立客户端,pojo调用等等,没用。

论坛不能上传附件,只好把源码/XML一一贴在这里,盼望热心人帮我测试一下,到底哪里出的问题(也许是glassfish的问题?有没有可能用weblogic或jboss试试?)。 下面的代码,尤其是xml我已经试着改过不少地方,所以,希望大家帮忙尽量亲自测试一下, 而不只是指点一些毛病。 如果能通过邮箱把通过测试的源码包发给我那就更感谢了,我的邮箱 : jeff2033333@yahoo.com.sg
分数比较少,请多担待,白读了很久CSDN今天才开始发帖,惭愧。

TestLocalHome:
Java code
package com.jeff;import javax.ejb.CreateException;import javax.ejb.EJBLocalHome;public interface TestLocalHome extends EJBLocalHome {    public TestLocal create() throws CreateException;}


TestLocal:
Java code
package com.jeff;import javax.ejb.EJBLocalObject;public interface TestLocal extends EJBLocalObject {    public int get6();}


TestBean:
Java code
package com.jeff;import java.rmi.RemoteException;import javax.ejb.EJBException;import javax.ejb.SessionBean;import javax.ejb.SessionContext;public class TestBean implements SessionBean {        public TestBean() {    }    public void ejbActivate() throws EJBException, RemoteException {    }    public void ejbPassivate() throws EJBException, RemoteException {    }    public void ejbRemove() throws EJBException, RemoteException {    }    public void setSessionContext(SessionContext arg0) throws EJBException,            RemoteException {    }        //business methods;        public int get6() {        return 6;    }}


ejb-jar.xml:
XML code
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"    "http://java.sun.com/dtd/ejb-jar_2_0.dtd"><ejb-jar>    <enterprise-beans>        <session>            <ejb-name>TestLocal</ejb-name>            <local-home>com.jeff.TestLocalHome</local-home>            <local>com.jeff.TestLocal</local>            <ejb-class>com.jeff.TestBean</ejb-class>            <session-type>Stateless</session-type>            <transaction-type>Container</transaction-type>        </session>    </enterprise-beans></ejb-jar> 



sun-ejb-jar.xml:
XML code
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sun-ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Application Server 8.1 EJB 2.1//EN' 'http://www.sun.com/software/appserver/dtds/sun-ejb-jar_2_1-1.dtd'> <sun-ejb-jar>  <enterprise-beans>    <ejb>      <ejb-name>TestLocal</ejb-name>      <jndi-name>ejb/TestLocal</jndi-name>    </ejb>  </enterprise-beans></sun-ejb-jar>


DoTest(Servlet, 访问时加参数 ?remote=true或false,可以看到remote=true时正确地返回值6):
Java code
package com.jeff;import javax.naming.Context;import javax.naming.InitialContext;import javax.naming.NamingException;import javax.rmi.PortableRemoteObject;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class DoTest extends HttpServlet {    public DoTest() {        super();    }    public void destroy() {        super.destroy(); // Just puts "destroy" string in log        // Put your code here    }    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        TestHome home1;        TestLocalHome home2;        Test test1;        TestLocal test2;                String jndiName = "ejb/Test";        String localLookupName = "ejb/TestLocal";        try {            Context ctx = new InitialContext();            if ("true".equals(request.getParameter("remote"))) {                home1 = (TestHome)PortableRemoteObject.narrow(ctx.lookup(jndiName), TestHome.class);                test1 = home1.create();                System.out.println(test1.get6());            } else {                Object o = ctx.lookup(localLookupName);                home2 = (TestLocalHome) o;                test2 = home2.create();                System.out.println(test2.get6());            }        } catch (Exception e) {            e.printStackTrace();        }    }    public void init() throws ServletException {        // Put your code here    }}


web.xml:
XML code
<?xml version="1.0" encoding="UTF-8"?><web-app version="2.4"     xmlns="http://java.sun.com/xml/ns/j2ee"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee     http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">  <servlet>    <description>DotestServlet</description>    <display-name>DotestServlet</display-name>    <servlet-name>DoTest</servlet-name>    <servlet-class>com.jeff.DoTest</servlet-class>  </servlet>  <servlet-mapping>    <servlet-name>DoTest</servlet-name>    <url-pattern>/servlet/DoTest</url-pattern>  </servlet-mapping>    <ejb-local-ref>      <ejb-ref-name>ejb/TestLocal</ejb-ref-name>      <ejb-ref-type>Session</ejb-ref-type>      <local-home>com.jeff.TestLocalHome</local-home>      <local>com.jeff.TestLocal</local>      <ejb-link>TestLocalEJB.jar#TestLocal</ejb-link>  </ejb-local-ref></web-app>




[解决办法]

TestLocal not found (NameNotFoundException)
JNDI名字没找到
配置文件一般都是自动生成的,不会有错,看看JNDI名字有没搞错


或者源文件发我邮箱ming_303@126.com,我跑跑看,这上面贴太多看的我眼花

读书人网 >J2EE开发

热点推荐