【问题标题】:How to inject EJB by parent interface?如何通过父接口注入 EJB?
【发布时间】:2017-11-21 23:19:21
【问题描述】:

我正在开发一个简单的 JEE 应用程序,并在构建耳朵时尝试选择 @Local 接口实现。 我有接口的层次结构:ParentLocalChildALocalChildBLocal 和相应的实现:ChildABeanChildBBean。我可以使用注释选择ParentLocalChildALocal/ChildBLocal 实现。如何使用 ejb-jar.xml 做同样的事情?
ParentLocal.java

@Local
public interface ParentLocal {
    public String getName();
}

ChildALocal.java

@Local
public interface ChildALocal extends ParentLocal {
}

ChildBLocal.java

@Local
public interface ChildBLocal extends ParentLocal {
}

ChildABean.java

@Stateless
public class ChildABean implements ChildALocal {
    @Override
    public String getName() {
        return "ChildA";
    }
}

ChildBBean.java

@Stateless
public class ChildBBean implements ChildBLocal {
    @Override
    public String getName() {
        return "ChildB";
    }
}

ManagerBean.java

@Stateless
public class ManagerBean implements ManagerLocal {
    /**works fine, servlet prints "ChildA", so I would like to get the same result using DD
    @EJB(beanInterface = my.package.model.ChildALocal.class)
    ParentLocal annotatedChildBean;*/

    /**doesn`t work!*/
    @EJB
    ParentLocal childBeanUsingDeploymentDesrciptor;

    //....
}

资源/META-INF/ejb-jar.xml

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar>
    <description>IBM WAS test application </description>
    <display-name>Test Manager</display-name>
    <enterprise-beans>
        <session>
            <ejb-local-ref>
                <ejb-ref-name>my.package.manager.ManagerBean/childBeanUsingDeploymentDesrciptor</ejb-ref-name>
                <local>my.package.model.ParentLocal</local>
                //doesn`t work
                <!--<local>my.package.model.ChildBLocal</local>--> 
                //doesn`t work
                <ejb-link>ChildBBean</ejb-link> 
            </ejb-local-ref>
        </session>
    </enterprise-beans>
</ejb-jar>

资源/META-INF/ibm-ejb-jar-bnd.xml

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar-bnd xmlns="http://websphere.ibm.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee/ibm-ejb-jar-bnd_1_0.xsd" version="1.0">
    <session name="ManagerBean">
        //doesn`t work
        <ejb-ref name="my.package.manager.ManagerBean/childBeanUsingDeploymentDesrciptor" binding-name="ejb/session/ChildBBean"/> 
    </session>
</ejb-jar-bnd>

在 WebServlet 中,我注入 ManagerBean 并调用它的方法来打印内部 bean 名称
MainServlet.java

@WebServlet(urlPatterns = "/my_app")
public class MainServlet extends HttpServlet {
    @EJB
    ManagerLocal elementMngr;
    //...
    String childName = elementMngr.getChildNameUsedDeploymentDescriptor();
}

我所有的子实现都在我放入耳朵的单独模块中。 当我尝试启动 servlet 时,IBM WebSpehere 8.5.5 显示以下错误:

Error 500: javax.ejb.EJBException: The EJB reference in the war-main-servlet.war module of 
the earManager application could not be resolved; nested exception is: 
com.ibm.ejs.container.EJBNotFoundException: EJB with interface my.package.model.ChildBLocal 
not present in application earManager.

UPD

Error 500: javax.ejb.EJBException: The EJB reference in the war-main-servlet.war module of 
    the earManager application could not be resolved; nested exception is: 
    com.ibm.ejs.container.EJBNotFoundException: EJB with interface my.package.model.ParentLocal
    not present in application earManager.

beanInterface 属性如何在 ejb-jar.xml 或(和)ibm-ejb-jar-bnd.xml 中重复?

【问题讨论】:

    标签: interface websphere ejb-3.0 implementation deployment-descriptor


    【解决方案1】:

    beanInterface 的 DD 等效项是 &lt;local&gt;(或 &lt;remote&gt;),beanName 的等效项是 &lt;ejb-link&gt;

    这个例子的问题似乎是ejb-jar.xml 中的&lt;session&gt; 元素没有任何东西可以将它与特定的EJB 联系起来。当 EJB 名称匹配时,XML 元素被视为对注释的覆盖。由于@Stateless 不包含名称,默认为ManagerBean,因此XML 应包含:

    <enterprise-beans>
        <session>
            <ejb-name>ManagerBean</ejb-name>
            <ejb-local-ref>
                <ejb-ref-name>my.package.manager.ManagerBean/childBeanUsingDeploymentDesrciptor</ejb-ref-name>
                    <local>my.package.model.ChildBLocal</local> 
                </ejb-local-ref>
            </session>
    
    <ejb-name>
    

    或者,您可以使用&lt;ejb-link&gt;ChildBBean&lt;/ejb-link&gt;,而不是&lt;local&gt;

    由于所有 bean 都在同一个应用程序中,因此不需要 ibm-ejb-jar-bnd.xml 文件。但是,如果您确实想使用绑定文件,此处指定的语法似乎是正确的,因此 binding-name 值可能不正确。需要有另一个ibm-ejb-jar-bnd.xml 文件将ChildBBean 配置为绑定到同一位置。

    【讨论】:

    • 更新错误:我指向的是 ChildBLocal 接口而不是 ParentLocal,抱歉。无论如何都没有改变,我删除了 ibm-ejb-jar-bnd.xml,现在我的 ejb-jar.xml 是:&lt;enterprise-beans&gt; &lt;session&gt; &lt;ejb-name&gt;ManagerBean&lt;/ejb-name&gt; &lt;ejb-local-ref&gt; &lt;ejb-ref-name&gt;my.package.manager.ManagerBean/childBeanUsingDeploymentDesrciptor&lt;/ejb-ref-name&gt; &lt;local&gt;my.package.model.ChildBLocal&lt;/local&gt; &lt;ejb-link&gt;my.package.children.ChildBBean&lt;/ejb-link&gt; &lt;/ejb-local-ref&gt; &lt;/session&gt; &lt;ejb-name&gt; 错误仍然存​​在
    • &lt;ejb-link&gt; 不正确,它应该是 EJB 名称,而不是类。由于@Stateless没有指定名字,所以默认是ChildBBean,所以&lt;ejb-link&gt;ChildBBean&lt;/ejb-link&gt;
    • 只要 bean 与 servlet 在同一个 EAR 中,&lt;local&gt; 和/或&lt;ejb-link&gt; 的使用就应该有效。有可能它们不是这样包装的吗?此外,您应该确认 bean 正在启动...日志中应该有这样的消息: CNTR0167I: 服务器正在绑定 xyx 应用程序的 abc.jar 模块中的 ChildBBean 企业 bean 的 ChildBLocal 接口。绑定位置为:java:global/xyz/abc/ChildBBean!ChildBLocal
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-11
    • 1970-01-01
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多