【问题标题】:Injecting EJB3.0 Beans into JSF2.0 Backing Beans... Impossible?将 EJB3.0 Bean 注入 JSF2.0 支持 Bean... 不可能?
【发布时间】:2011-06-08 16:01:11
【问题描述】:

我正在开发一个基于 Weblogic 11g 的 JSF 项目,我们最初的设计是调用 JSF Backing Beans 来调用 EJB3.0 bean 来执行业务逻辑和数据访问调用。当我尝试将 EJB 引用注入到支持 bean 时,@EJB 注释似乎在我的项目中不起作用。每当我点击我正在测试的类时,我的 EJB 的构造函数永远不会被调用,我最终会得到一个 NPE。是否可以将 EJB3.0 bean 注入 JSF 支持 bean?我应该通过 JSF Backing bean 调用 EJB 的另一种方法吗?最佳做法是什么?

【问题讨论】:

  • 可以肯定的是,EJB 类本身已经使用javax.ejb 注释进行了注释,对吧?
  • @BalusC 是的,EJB 使用 javax.ejb.Stateless 进行注释。当我浏览到 Weblogic 控制台时,我可以看到 EJB 已部署。
  • 好的,那么可能是 Weblogic 特定的问题。对不起,不知道,因为我不使用它。编辑:哦,可以肯定的是,您是否知道注入的依赖项在 bean 的构造函数中不可用,但最早在 @PostConstruct 以及 bean 的生命周期之外?
  • @BalusC 但是将 EJB3.0 bean 注入 JSF 支持 bean 是可能的吗?
  • 当然有可能。我们在 JBoss 5 和 6 上做了很多年。在当地的操场上,它在 Glassfish 3 上也能完美运行。

标签: jsf ejb-3.0 ejb weblogic11g backing-beans


【解决方案1】:

googled 有点,这似乎确实是 Weblogic 的一个已知问题。很多类似的话题都没有得到解答。

我发现this blog 证实了Weblogic 中的@EJB 仅适用于web.xml 定义的资源,不适用于JSF。该博客还详细描述了使用 ServletContextListener 的解决方法,这在 IMO 中并不比使用 JNDI 好多少。

我还发现 this OTN topic 确认当 EJB 模块包含在子目录中时,Weblogic 中的 @EJB 开始工作(请参阅底部发布的答案,2011 年 2 月 15 日 5:下午 44 点)。

【讨论】:

    【解决方案2】:

    事实证明,在使用 JSF 和 EJB 部署任何东西时,这是一个特定于 Weblogic 的问题。我在 Oracle 论坛上找到了这篇文章,它解释了如何使用 Weblogic 11g 在 JSF Managed Beans 中获得 @EJB 注入:

    EJB3.0 Injection into JSF Managed beans

    更新:

    在旋转太久之后,我不得不放弃尝试将 EJB 注入 Weblogic 11g 上的 JSF ManagedBean 中。似乎在Tomcat中工作正常。也许 EJB3 和 JSF 的实现在 12G 中会更好……

    【讨论】:

      【解决方案3】:

      要使其正常工作,您需要执行两个步骤:

      1. 将jsf-2.0.war部署为LIBRARY,可以找到/ORACLE_HOME/wlserver_10.3/common/deployable-libraries

      1. 在您的 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 文件的一部分。

      【讨论】:

        【解决方案4】:

        所以这里是节拍!有一个简单的方法可以解决这个问题。

        1. 在 ...wlserver_10.3\common\deployable-libraries 下打开 jsf-2.0.war

        2. 导航到 WEB-INF/lib 并将 wls.jsf.di.jar JAR 保存在某处

        3. 将 wls.jsf.di.jar JAR 放在 WAR 应用程序的 lib 文件夹下。

        4. 部署

        现在只需将@EJB 添加到@ManagedBean 中的属性即可。

        【讨论】:

        • 啊,要是这么简单就好了……我试过这个,看了你的帖子后又试了一次。您可以添加对代码示例的引用吗?也许这会帮助我理清思路。
        【解决方案5】:

        @EJB 注释还有一个替代方法,可以在 JSF ManagedBean Web 应用程序中访问本地 EJB bean。考虑到您将 EJB 类和 WAR 打包在同一个 EAR 文件中,请执行以下操作:

        1. 配置您的 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>
          
        2. 通过 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>
          
        3. 在您的 JSF 托管 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

        【讨论】:

          猜你喜欢
          • 2011-07-16
          • 2012-04-11
          • 2014-02-21
          • 1970-01-01
          • 2015-04-15
          • 1970-01-01
          • 2011-10-17
          • 2011-09-28
          • 2011-09-09
          相关资源
          最近更新 更多