可以在WebLogic 12c上使用MyFaces + CDI吗?

时间:2013-03-30 17:57:47

标签: jsf cdi myfaces weblogic12c

我一直试图让这个设置运行几天,但仍然没有运气。这是我一直在使用的测试应用程序:

@Named
@RequestScoped
public class Test {

    private String test = "test";
    public String getTest() { return test; }
    public void setTest(String test) { this.test = test; }
}

在jsf页面中:

<h:outputText value="#{test.test}"/>

在没有MyFaces的情况下运行此示例工作正常(呈现“测试”应该如此),但是当我在WAR文件中部署MyFaces并在weblogic.xml中执行必要的配置时,CDI似乎停止工作(或者至少是集成在JSF和CDI之后,输出html中没有显示任何内容。不过,MyFaces本身似乎没问题。

我的基本配置如下:

  • WebLogic Server 12c(12.1.1.0),补丁应该是最新的,因为我刚刚下载了一个开发版本,只是为了确保
  • MyFaces-2.1.10,部署在WEB-INF / libs
  • Beans.xml已到位
  • org.apache.myfaces.webapp.StartupServletContextListener已在web.xml中注册
  • WebLogic配置为使用weblogic.xml
  • 使用MyFaces

Weblogic.xml内容:

<prefer-application-packages>
    <package-name>javax.faces.*</package-name>
    <package-name>com.sun.faces.*</package-name>
    <package-name>com.bea.faces.*</package-name>
</prefer-application-packages>
<prefer-application-resources>
    <resource-name>javax.faces.*</resource-name>
    <resource-name>com.sun.faces.*</resource-name>
    <resource-name>com.bea.faces.*</resource-name>
    <resource-name>META-INF/services/javax.servlet.ServletContainerInitializer</resource-name>
    <resource-name>META-INF/services/com.sun.faces.spi.FacesConfigResourceProvider</resource-name>
</prefer-application-resources>

到目前为止我学到了什么:

  • WL12c配备了Weld 1.1.3,因为它是CDI实现。
  • 我读到某处(不记得在哪里),每当你决定切换JSF实现时,你都要负责自己集成JSF / CDI。这是真的吗(肯定不希望)?

到目前为止我尝试过的事情:

  • 将MyFaces CODI添加到混合物中,希望它能以某种方式将Weld和MyFaces粘合在一起,但事实并非如此。
  • 将OpenWebBeans替换为Weld作为CDI实现。这似乎最初起作用,但稍后在一些内部sun.reflection包中提供了各种有趣的ClassCastExceptions。无论如何,这是一个我宁愿避免的解决方案。
  • 使用web.xml和faces-config.xml中的各种选项手动触发Weld。这似乎让Weld继续使用各种错误消息来淹没日志。在某种程度上,这些可以通过将weblogic升级到更新的Weld版本来“修复”,但每次我这样做时都会遇到下一个错误。同样,我也宁愿避开这条路线。

在保留CDI支持的同时,在WL12c上使用MyFaces真的很难吗?或者我只是错过了明显的问题?谢谢你的帮助。

3 个答案:

答案 0 :(得分:3)

在你的例子中有很多不清楚的事情。例如。什么包是@RequestScoped来自?它是javax.enterprise.context.RequestScoped(应该工作)还是javax.faces.bean.RequestScoped(不起作用)?如果您只使用CDI bean(并且没有使用javax.faces.bean),那么JSF容器和CDI容器相互集成的唯一方式实际上是统一表达式语言javax.el.E​​LResolver。这必须开箱即用。

org.apache.myfaces.webapp.StartupServletContextListener并不是真的需要imo。您只需要设置FacesServlet。

有问题的地方可能是JSF EG被迫使用ServletContainerInitializer [1]盲目地激活JSF impl,即使应用程序根本不使用JSF。这很难解决,因为servlet-3.0规范只定义了如何自动激活这些功能,但没有办法再次禁用它们。

[1] http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContainerInitializer.html

答案 1 :(得分:1)

我担心没有办法做到这一点。焊接胶水代码需要在那里。那些微小的集成层是jsf的wls可部署库的一部分,不适用于myfaces ....

答案 2 :(得分:1)

只是想知道,您是否尝试在应用中启用焊接servlet?

我问的原因是因为这句话:

  

我在某处读到(不记得在哪里)每当你决定切换JSF实现时,你自己负责集成JSF / CDI

这是相当准确的。容器是将JSF impl和CDI impl整合在一起的容器。如果用你自己的JSF impl替换它,你就会绕过容器给你的东西。如果您还没有,我强烈建议您尝试在应用程序中启用Weld Servlet,以查看CDI是否与自定义JSF impl一起启动。