我正在开发一个基于 Weblogic 11g 的 JSF 项目,我们最初的设计是调用 JSF Backing Beans 来调用 EJB3.0 bean 来执行业务逻辑和数据访问调用。当我尝试将 EJB 引用注入到支持 bean 时,@EJB 注释似乎在我的项目中不起作用。每当我点击我正在测试的类时,我的 EJB 的构造函数永远不会被调用,我最终会得到一个 NPE。是否可以将 EJB3.0 bean 注入 JSF 支持 bean?我应该通过 JSF Backing bean 调用 EJB 的另一种方法吗?最佳做法是什么?
5 回答
我用谷歌搜索了一下,这确实似乎是 Weblogic 的一个已知问题。很多类似的话题都没有得到答复。
我发现这个博客确认@EJB
在 Weblogic 中仅适用于由 定义的资源web.xml
,不适用于 JSF。该博客还详细描述了使用ServletContextListener
IMO 的解决方法,它并不比使用 JNDI 好多少。
我还发现了这个 OTN 主题,它确认当 EJB 模块不@EJB
包含在子目录中时,Weblogic 开始工作(请参阅底部发布的答案,2011 年 2 月 15 日下午 5:44)。
事实证明,在使用 JSF 和 EJB 部署任何东西时,这是 Weblogic 特有的问题。我在 Oracle 论坛上找到了这篇文章,它解释了如何使用 Weblogic 11g 在 JSF Managed Beans 中获得 @EJB 注入:
更新:
在旋转太久之后,我不得不放弃尝试将 EJB 注入 Weblogic 11g 上的 JSF ManagedBean 中。似乎在Tomcat中工作正常。也许 EJB3 和 JSF 实现在 12G 中会更好......
要使其工作,您需要执行两个步骤:
- 将jsf-2.0.war部署为LIBRARY,可以找到/ORACLE_HOME/wlserver_10.3/common/deployable-libraries
在您的 Web 项目中,在 WEB-INF/weblogic.xml 中添加对 jsf-2.0.war 库的引用
<?xml version="1.0" encoding="UTF-8"?> <wls:weblogic-web-app xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app" 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_0.xsd http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.1/weblogic-web-app.xsd"> <wls:weblogic-version>10.3.3</wls:weblogic-version> <wls:context-root>your_context_app</wls:context-root> <wls:library-ref> <wls:library-name>jsf</wls:library-name> <wls:specification-version>2.0</wls:specification-version> <wls:implementation-version>1.0.0.0_2-0-2</wls:implementation-version> <wls:exact-match>true</wls:exact-match> </wls:library-ref> </wls:weblogic-web-app>
我已经在 weblogic 10.3.3 和 10.3.5 中成功测试了这个。如果这不起作用,请尝试将应用程序部署为 EAR 文件的一部分。
所以这里是节拍!有一个简单的方法可以解决这个问题。
在 ...wlserver_10.3\common\deployable-libraries 下打开 jsf-2.0.war
导航到 WEB-INF/lib 并将 wls.jsf.di.jar JAR 保存在某处
将 wls.jsf.di.jar JAR 放在 WAR 应用程序的 lib 文件夹下。
部署
只需将@EJB 添加到@ManagedBean 中的属性,现在一切都应该工作了。
@EJB 注释还有一个替代方法,以便让您的本地 EJB bean 在您的 JSF ManagedBean Web 应用程序中可访问。考虑到您将 EJB 类和 WAR 打包在同一个 EAR 文件中,请执行以下操作:
配置您的ejb-jar.xml以告诉 weblogic 将 EJB bean 暴露给外部组件;
<enterprise-beans> <session> <ejb-name>MyEJBBean</ejb-name> <business-local>com.app.MyEJBBeanLocalInterface</business-local> <ejb-class>com.app.MyEJBBeanLocalImpl</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> <ejb-local-ref> <ejb-ref-name>ejb/MyEJBBeanLocal</ejb-ref-name> <local>com.app.MyEJBBeanLocalInterface</local> </ejb-local-ref> </session> <enterprise-beans>
通过 ejb-link 名称在 Web 应用程序的web.xml中插入对 EJB 的引用。ejb-ref-name 是 JSF 托管 bean 可见的名称。
<ejb-local-ref> <ejb-ref-name>ejb/MyEJBBeanLocal</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <local>com.app.MyEJBBeanLocalInterface</local> <ejb-link>MyEJBBean</ejb-link> </ejb-local-ref>
在您的JSF Managed Bean中,通过 JNDI 查找调用 EJB Bean,如下所示:
try { Context context = new InitialContext(); MyEJBBeanLocalInterface myEJBBean = context.lookup("java:comp/env/ejb/MyEJBBeanLocal"); } catch (NamingException e) { e.printStackTrace(); }
就我而言,我使用的是带有 JPA (Eclipselink) 的 Weblogic 10.3.6 (11g)、JSF 2.0 和 EJB 3.0