【问题标题】:Referencing EJB Local home from a POJO class of a separate web application从单独的 Web 应用程序的 POJO 类引用 EJB 本地主目录
【发布时间】:2016-04-04 06:55:48
【问题描述】:

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

我们正在使用 WAS 7 应用程序服务器进行部署,当 EJB 成功部署且没有错误时,我在从不同 Web 应用程序的单独 POJO 类查找本地主页界面时遇到命名异常,这是必需的我基本上是想在引用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;

}

Pojo 类引用本地 Home 接口:

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;
}

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

以下是我得到的错误:

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

我是否缺少某些配置导致 JNDI 查找失败?任何帮助将不胜感激。提前致谢。

【问题讨论】:

    标签: java jndi ejb-3.0 websphere-7


    【解决方案1】:

    WebSphere Application Server 7.0 只是 EJB 3.0 的一个实现,但 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 引用显式配置绑定名称。

    【讨论】:

    • 嗨..感谢您的回复..我尝试了从 SysOut 日志中找到的以下 jndi 名称:“ejblocal:AccessLDAPSessionLocalHome#com.ibm.asset.hrportal.core.ejb.ldap.AccessLDAPSessionLocalHome”。我收到以下错误:'Configured LOCAL interface does not extend javax.ejb.EJBLocalObject : com.ibm.asset.hrportal.core.ejb.ldap.AccessLDAPSessionLocal of bean AccessLDAPEAR#AccessLDAP.jar#AccessLDAPSessionBean'。但我认为在 EJB3.0 中,Local 接口没有扩展 EJBLocalObject。有什么建议吗?不知道出了什么问题。
    • @SubhankarNath 这是一个单独的问题,但如果您使用的是@LocalHome/EJBLocalHome,那么您还必须使用EJBLocalObject。否则,如果您不想要 EJBLocalHome/EJBLocalObject,则仅使用 @Local,并将查找和 beanInterface 更改为直接转换为业务接口并完全删除主接口。
    • 实际上在 LocalHome 接口中有一个内置的 create() 方法,代码正在引用。如果我完全删除 Local Home(实际上我想因为我在 EJB3.0 LocalHome 中阅读是非常多余的) 那么这部分代码是如何工作的:'accessLDAPSessionBean = ((AccessLDAPSessionLocalHome) obj).create();'
    • 查找将直接返回业务接口,因此您将转换为该接口而不是主接口。
    • 嗨,Brett...终于能够成功部署和运行 EJB 并运行应用程序。非常感谢您在这方面的帮助......
    【解决方案2】:

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

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

    【讨论】:

    • 另外,在进行查找之前,您需要将 providerURL 和 factoryName 提供给上下文对象。我不知道该怎么做。你能帮我吗?
    • context = new InitialContext(); providerURL = "corbaloc::localhost:2809"; factoryName = "com.ibm.websphere.naming.WsnInitialContextFactory";哈希表 = 新哈希表(2); table.put(Context.INITIAL_CONTEXT_FACTORY, factoryName); table.put(Context.PROVIDER_URL, providerURL); context = new InitialContext(table);
    • 我在 web.xml 中使用了以下代码: ejb/AccessLDAPSession会话com.ibm.asset.hrportal.core.ejb.ldap.AccessLDAPSessionLocalHomecom.ibm.asset.hrportal.core.ejb .ldap.AccessLDAPSessionLocalAccessLDAPSession 并使用以下查找: Object obj = initialContext.lookup("java:comp/env/ejb/ AccessLDAPSession");
    • 收到此错误:[根异常是 com.ibm.ejs.container.EJBNotFoundException:名为 AccessLDAPSession 的 EJB 不存在于应用程序 PresentationLayer2EAR] 不确定我是否正确引用了 EJB,因为它是从一个不同的应用程序。有什么建议吗?
    • 尝试将 作为它所在的 jar 的引用:yourrejbjar.jar#AccessLDAPSession
    猜你喜欢
    • 2013-06-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-25
    • 2016-09-26
    • 1970-01-01
    • 1970-01-01
    • 2021-01-24
    • 1970-01-01
    相关资源
    最近更新 更多