在 ear 应用程序中从 web 模块(RESTful 服务)访问 ejb

Access ejb from web module (RESTful services) in ear application

我有一个 ear 应用程序,它由一个 ejb.jar 和一个网络应用程序 (war) 组成。 ejb.jar 包含我所有的 EJB(bean 和接口),我的 war 包含 REST Web 服务。我想从 war 模块访问 EJB,这可能吗?注入 EJB 不起作用,出现空指针异常。

我知道这个问题已经被问过很多次了,但我似乎无法让它工作...

我正在使用 Glassfish v2.1.1(我知道我应该升级,但现在很难...)

这里是 returns nullPointerException 的代码片段: (我知道我不应该通过 GET 验证用户,但这只是我尝试检查是否可以访问 ejb 的示例代码)

@Path("/user")
public class UserWS
{
    @EJB
    SB_usrRemote sb_usrRemote;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String checkLoginAttempt(String username, String password)
    {
        return sb_usrRemote.checkLoginAttempt(username, password).toString();
    }
}

我没有提到只有当我将 ejb.jar 包含在 ear 应用程序的 lib 文件夹中时,war 模块才能 "see" 它才有效。有没有其他方法可以访问 EJB 类? 我也在使用 Intellij,该应用程序是一个 java EE 应用程序,其中包含一个 Web 模块(用于 war)。

编辑

我无法避免 glassfish 从 v2 升级到 v4。这是我做出的最好的决定,因为我所有的问题都消失了。我代码中的所有 ejb 注入都非常有效!

谢谢两位的建议!我接受 hugh 的回答,因为 JNDI 可能会起作用,但从长远来看,升级 glassfish 似乎是更合适的解决方案 运行。

编辑 2

我终于成功地使用这段代码进行了适当的 ejb 注入:

@Path("/user")
public class UserWS
{
    @EJB (lookup = "java:global/<ear-name>/<ejb-jar-name>/SB_usrRemote")
    SB_usrRemote sb_usrRemote;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String checkLoginAttempt(String username, String password)
    {
        return sb_usrRemote.checkLoginAttempt(username, password).toString();
    }
}

我在部署 ear 文件时在 glassfish 日志中找到了正确的查找路径。

bean 没有被注入,因为这个 class 不是 EJB。您应该能够使用 JNDI 查找获取副本:

SB_usrRemote bean = (SB_usrRemote) new InitialContext().lookup("SB_usrRemote");

更多关于 JNDI 查找的信息:link

另一种可能性是使 bean 成为托管 bean - 我认为这在 JSF 中是可能的,但恐怕我不知道。 [编辑 - JAX-RS,而不是 JSF,根据 Bkail 的回答]

根据 JAX-RS 规范,在 JAX-RS classes 中默认不启用注入。您需要使用 CDI bean 部署存档(为 CDI 1.0 添加 WEB-INF/beans.xml),使 JAX-RS class 成为托管 bean(添加 @ManagedBean class 的注释),或者使 JAX-RS class 成为 EJB(例如,将 @Stateless 注释添加到 class)。