我已经创建了一个带有 Web 项目、ejb3 项目和 ejb 客户端的 EAR。我可以通过在 servlet 中注入(inject)来调用 bean 方法。 我打算使用一个 ServiceDelegate,它是一个 pojo 来处理 bean 调用。所以我将从我的 servlet 调用委托(delegate),委托(delegate)将调用适当的 bean 及其方法。
但是我无法在 Web 项目中的委托(delegate)类中获取 bean 引用。 @EJB 注释返回了空引用。因此,我尝试使用 java:comp/env/EARname/BeanName 进行 JNDI 查找。但我总是以命名异常(exception)结束。
Name comp/env/EARname not found in context "java:".
请建议我在 Websphere 7 服务器上通过 JNDI 调用 ejb3 bean 的正确方法。
最佳答案
Java EE 5 和 6 中的依赖注入(inject)仅适用于托管类。在 servlet 容器中,这在一些类型的类中受支持,而不是在所有 POJO 中(不幸的是)。
Servlet 规范 2.5 阐明了容器必须为其注入(inject)依赖项(如果存在)的类:
组件类型:Servlet
实现以下接口(interface)的类
- javax.servlet.Servlet
组件类型:过滤器
实现以下接口(interface)的类:
- javax.servlet.Filter
组件类型:监听器
实现以下接口(interface)的类:
- javax.servlet.ServletContextListener
- javax.servlet.ServletContextAttributeListener
- javax.servlet.ServletRequestListener
- javax.servlet.ServletRequestAttributeListener
- javax.servlet.http.HttpSessionListener
- javax.servlet.http.HttpSessionAttributeListener
因此,如果您必须解决依赖查找的问题,您可以采用以下任一策略:
- 将依赖项注入(inject)托管类,并将其传播到 ServiceDelegate。恕我直言,这是一种设计气味。
- 使用 InitialContext 执行 JNDI 查找,但您应该了解为已部署的 EJB 生成的 JNDI 绑定(bind)。这似乎是失败的,因为 JNDI 名称可能不正确——Java EE 规范没有标准化分配给部署的 EJB 的 JNDI 名称。换句话说,鉴于缺少可移植的 JNDI 名称,您应该尝试将 EJB 绑定(bind)到已知名称并执行相同的查找。
- 您需要验证 EJB session 对象确实绑定(bind)到 java:comp/env 命名空间。情况可能并非如此。需要明确的是,如果容器没有注入(inject)依赖项,则必须在 web.xml 中声明本地 EJB 引用条目。容器不会自动将 session EJB 对象注入(inject) servlet 的 namespace ;它将要求将 EJB 声明为托管类中的资源。这似乎是主要的失败案例,尽管它被列在最后。
关于java - Websphere 7 中的 EJB3 bean JNDI 查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3534821/