2

我是 EJB3 的新手,当两者位于同一服务器(WAS 8)上的不同 ear 文件中时,我无法从我的 JSF 托管 bean 调用远程 ejb。如果它们在同一个耳朵文件中,那么我没有问题。但我需要调用才能在同一台服务器上的不同应用程序中工作。

在将 EJB 注入托管 Bean 期间,我收到以下异常:

Caused by: javax.ejb.EJBException: The EJB/BelgianBeerSessionBean EJB reference in the null component in the BeerStoreWebProject.war module of the BeerStoreWebEAR application could not be resolved; nested exception is: com.ibm.ejs.container.EJBNotFoundException: EJB with interface com.ejb.view.BelgianBeerSessionBeanRemote not present in application BeerStoreWebEAR
Caused by: com.ibm.ejs.container.EJBNotFoundException: EJB with interface com.ejb.view.BelgianBeerSessionBeanRemote not present in application BeerStoreWebEAR
    at com.ibm.ejs.container.HomeOfHomes.getHomeByInterface(HomeOfHomes.java:928)
    at com.ibm.ws.ejbcontainer.injection.factory.EJBLinkObjectFactory.getObjectInstance(EJBLinkObjectFactory.java:261)
    at com.ibm.ws.ejbcontainer.injection.factory.EJBLinkObjectFactory.getObjectInstance(EJBLinkObjectFactory.java:167)

我希望有人可以帮助我深入了解这一点,并解释如果远程 EJB 在单独的 EAR 文件中,我应该如何注入和查找它。

这是我的设置:

项目设置

1)BelgianBeersEJMProjectClient(一个包含接口的ejb客户端项目)

package com.ejb.view;
public interface BelgianBeerSessionInterface {
    List<Country> getAllCountries();
    void saveCountries(List<Country> countries);
}

package com.ejb.view;
@Remote
public interface BelgianBeerSessionBeanRemote extends
        BelgianBeerSessionInterface {

}

2)BelgianBeersEJBProject(包含ejb实现)

    package com.ejb;
    @Stateless
    public class BelgianBeerSessionBean implements BelgianBeerSessionBeanRemote,
            BelgianBeerSessionBeanLocal {

        public BelgianBeerSessionBean() {
            // TODO Auto-generated constructor stub
        }

        public List<Country> getAllCountries() {
                //to be implemented
                return null;
        }
        public void saveCountries(List<Country> countries) {
            //to be implemented
        }
    }

在 META-INF 中还有一个 ejb-jar.xml:

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar version="3.1" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd">
  <display-name>BelgianBeersEJBProject </display-name>
  <ejb-client-jar>BelgianBeersEJBProjectClient.jar</ejb-client-jar> 
 </ejb-jar>

3) BelgianBeersWebProject - 包含 jsf 应用程序

@ManagedBean
@ViewScoped
public class BeerStorePageBean {

    @EJB(name="EJB/BelgianBeerSessionBean")
    private BelgianBeerSessionBeanRemote store;
    public BelgianBeerSessionBeanRemote getStore() {
        return store;
    }
    public void setStore(BelgianBeerSessionBeanRemote store) {
        this.store = store;
    }
    private List<Country> countries = null;

    @PostConstruct
    public void populateCountries(){
        System.out.println("Store = " + store);
        countries = store.getAllCountries();    
    }
    public List<Country> getAllCountries() {

        return countries;
    }
}

在 web.xml 中有一个 ejb 条目:

<ejb-ref>
        <description />
        <ejb-ref-name>EJB/BelgianBeerSessionBean</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <home />
        <remote>com.ejb.view.BelgianBeerSessionBeanRemote</remote>
    </ejb-ref>

部署单位

EAR file 1 (BelgianBeersEARProject.ear) contains:
   1) BelgianBeersEJBProject.jar
   2) BelgianBeersEJBProjectClient.jar

 EAR file 2 (BeerStoreWebEAR.ear) contains: 
   1. BeerStoreWebProject.war
   2. BelginaBeersEJBProjectClient.jar

请有人向我解释调用位于单独 EAR 文件中的远程 EJB 的正确方法。请帮忙!我要扯头发了!

4

1 回答 1

1

@EJB注释(和XML 中的对应注释<ejb-ref>)只有在目标 EJB 位于同一应用程序中时才会自动链接。从javadoc:

如果没有提供显式链接信息,并且同一应用程序中只有一个会话 bean 公开了匹配的客户端视图类型,则默认情况下 EJB 依赖关系解析为该会话 bean。

要链接到另一个应用程序中的 EJB,您需要指定一个绑定。您可以通过多种方式执行此操作:

  1. <lookup-name>targetBindingName</lookup-name><ejb-ref>ejb-jar.xml 中指定。
  2. 在包含 ejb-ref 的 WAR 模块<ejb-ref name="EJB/BelgianBeerSessionBean" binding-name="targetBindingName"/>的文件中指定。WEB-INF/ibm-web-bnd.xml有关绑定文件格式的更多信息,请参阅信息中心。
  3. 在应用程序部署期间指定目标绑定名称(即,不要“使用默认绑定”)。

在任何情况下,您都需要目标 EJB 的绑定名称。上面的 InfoCenter 链接描述了“经典”WebSphere Application Server 绑定名称和 Java EE 6 标准“java:global”名称。前者可以配置,ibm-ejb-jar-bnd.xml后者不能(除了指定 Alternate<application-name><module-name>),但使用哪个并不重要。要查找正在使用的名称,最简单的方法是启动 EJB 应用程序,然后查找CNTR0167IEJB 容器在启动时打印的消息(第一个是“经典”绑定):

[6/6/13 17:26:04:531 CDT] 00000049 WASNameSpaceB I   CNTR0167I: The server is binding the javax.management.j2ee.ManagementHome interface of the Management enterprise bean in the mejb.jar module of the ManagementEJB application.  The binding location is: ejb/mgmt/MEJB
[6/6/13 17:26:04:544 CDT] 00000049 AbstractEJBRu I   CNTR0167I: The server is binding the javax.management.j2ee.ManagementHome interface of the Management enterprise bean in the mejb.jar module of the ManagementEJB application.  The binding location is: java:global/ManagementEJB/mejb/Management!javax.management.j2ee.ManagementHome
于 2013-06-06T22:31:02.220 回答