从单独Web应用程序的POJO类引用EJB Local home

时间:2016-04-04 06:55:48

标签: java jndi ejb-3.0 websphere-7

我正在尝试将我的应用程序中的2个EJB模块从EJB2.1移植到EJB3.0。我正在使用Eclipse Kepler IDE并使用EJB3.0配置重新生成会话bean。我没有使用ejb-jar.xml,因为在EJB 3.0中应该是多余的。我改为使用注释将我的bean标记为无状态并指定本地和本地Home接口。我仍然保留了Local Home接口,因为我希望我的项目的基本结构与EJB2.1中的基本结构类似。我还在迁移时废除了EJB的xml绑定。

我们正在使用WAS 7应用程序服务器进行部署,并且在成功部署EJB时没有错误,我在从不同Web应用程序的单独POJO类查找本地Home接口时收到命名异常,这是必需的in。我基本上想在引用EJB Local Home之后调用Local Home接口的create()方法。在下面添加代码示例:

会话Bean:

@Stateless
@Local(AccessLDAPSessionLocal.class)
@LocalHome(AccessLDAPSessionLocalHome.class)
public class AccessLDAPSessionBean implements AccessLDAPSessionLocal {
//Business Logic
}

本地界面:

public interface AccessLDAPSessionLocal {
//business Interface
}

本地家庭界面:

public interface AccessLDAPSessionLocalHome extends EJBLocalHome {

public AccessLDAPSessionLocal create() throws CreateException;

}

引用Local Home界面的Pojo类:

public static AccessLDAPSessionLocal getAccessLDAPSessionBean() throws NamingException, CreateException {
    if (accessLDAPSessionBean == null) {
    InitialContext context = new InitialContext();
    Object obj = context.lookup("java:global/AccessLDAP/AccessLDAPSessionBean!com.ibm.asset.hrportal.core.ejb.ldap.AccessLDAPSessionLocalHome");
        accessLDAPSessionBean = ((AccessLDAPSessionLocalHome) obj).create();
    }
    return accessLDAPSessionBean;
}

我的本​​地和本地Home接口也在我的EJB客户端内部,我用作jar文件,而我的会话Bean在实际的EJB中,用作EAR。

以下是我得到的错误:

NamingException::javax.naming.NameNotFoundException: Name global not found in context "java:".

我是否遗漏了一些导致JNDI查找失败的配置?任何帮助将不胜感激。提前谢谢。

2 个答案:

答案 0 :(得分:2)

WebSphere Application Server 7.0只是EJB 3.0的一个实现,但是直到EJB 3.1才添加java:global命名空间,而EJB 3.1直到8.0才在WebSphere Application Server中实现。与所有EJB 3.0实现一样,您需要查找特定于供应商的绑定名称。您可以通过查看SystemOut.log中的CNTR0167I消息来查找WebSphere Application Server绑定名称。如果您要自定义此绑定名称,请参阅知识中心中的EJB 3.0 application bindings overview主题。

无论如何,通过绑定名称直接查找EJB并不是最佳实践。相反,您应该使用EJB引用。在EJB 3.0中,这意味着在EE托管对象(例如servlet或其他EJB)中使用这样的注释:

@EJB 
private AccessLDAPSessionLocalHome home;

在这种情况下,EJB容器需要在包含EJB引用的同一应用程序中查找目标EJB,因此您无需为EJB引用显式配置目标绑定名称。

如果需要从实用程序类而不是EE托管类访问EJB引用,则在托管类(例如servlet或其他EJB)上使用名称声明EJB引用,并从中查找实用类:

@EJB(name = "ejb/accessHome", beanInterface = AccessLDAPSessionLocalHome.class)
public class MyServlet { ... }

public class MyUtility {
    ...
    InitialContext context = new InitialContext();
    Object obj = context.lookup("java:comp/env/ejb/accessHome");
    ...
}

您可以使用@EJBs注释在同一个托管EE类上配置多个此类EJB引用:

@EJBs({
    @EJB(name = "ejb/accessHome", beanInterface = AccessLDAPSessionLocalHome.class),
    @EJB(name = "ejb/other" beanInterface = Other.class)
})
public class MyServlet { ... }

如果您的EJB打包在单独的EAR中,请注意这不是可移植配置。请参阅知识中心中EJB modules主题的“本地客户端视图”部分。此外,您还需要为EJB引用显式配置绑定名称。

答案 1 :(得分:0)

我认为你查找ejb的方式不正确。 JNDI名称类似于“java:comp / env /”。 ejb-ref-name将成为web.xml的一部分

此外,在执行查找之前,您需要将providerURL和factoryName提供给上下文对象。