我已经试着让这个设置运行了几天了,但仍然没有运气。下面是我一直在使用的测试应用程序:
@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的情况下运行这个示例工作得很好(像它应该的那样呈现"test"),但是当我在WAR文件中部署MyFaces并在weblogic.xml中进行必要的配置时,CDI似乎停止工作(或者至少,JSF和CDI之间的集成),并且在输出html中没有显示任何内容。不过,MyFaces本身似乎还不错。
我的基本配置如下:
- WebLogic Server 12c(12.1.1.0),补丁应该是最新的,因为我昨天刚刚下载了一个开发版本,只是为了确保
- MyFaces-2.1.10,部署在WEB-INF/lib
- 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配备焊缝1.1.3作为其CDI实施。
- 我在某个地方读到(不记得在哪里了),无论何时你决定切换JSF实现,你都要自己负责集成JSF/CDI。这是真的吗(当然希望不是)?
我已经尝试过的事情:
- 添加MyFaces CODI到混合中,希望它能以某种方式将Weld和MyFaces粘合在一起,但它没有。
- 用OpenWebBeans代替Weld作为CDI实现。这似乎一开始工作,但后来在一些内部太阳给出了各种有趣的classcastexception。反映包。这是一个我宁愿避免的解决方案。
- 使用web.xml和faces-config.xml中的各种选项手动触发Weld。这似乎让Weld继续下去,它充斥着各种错误信息的日志。在某种程度上,这些可以通过升级weblogic到较新的Weld版本来"修复",但每次我这样做时,我都会遇到下一个错误。同样,我也宁愿避免这条路线。
在WL12c上使用MyFaces同时保留CDI支持真的那么难吗?还是我只是错过了显而易见的东西?谢谢你的帮助。
在您的示例中有相当多的事情不清楚。例如,@RequestScoped来自哪个包?是javax.enterprise.context.RequestScoped(应该工作)还是javax.faces.bean.RequestScoped(不工作)?如果您只使用CDI bean(而不是javax.faces.bean之类的东西),那么JSF容器和CDI容器相互集成的唯一方法实际上是统一表达式语言javax.el.ELResolver。这必须是开箱即用的
org.apache.myfaces.webapp。我不需要StartupServletContextListener。您所需要做的就是设置FacesServlet。
问题的地方可能是JSF EG被迫使用ServletContainerInitializer[1]来盲目地激活JSF impl,即使应用程序根本不使用JSF。这很难解决,因为servlet-3.0规范只定义了如何自动激活这些特性,但没有办法再次禁用它们。
[1] http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContainerInitializer.html
恐怕没有办法。焊接胶代码必须在那里。这些很小的集成层是jsf的可部署库的一部分,但myfaces无法使用....
只是想知道,你有没有尝试在你的应用程序中启用焊缝servlet ?
我问这个问题的原因是:
我在某个地方读到(不记得在哪里了),无论何时你决定切换JSF实现,你都要自己负责集成JSF/CDI
这是相当准确的。容器是完成JSF impl和CDI impl的整个组合分层的容器。如果用您自己的JSF impl替换它,您就绕过了容器提供给您的东西。如果你还没有,我强烈建议你尝试在你的应用程序中启用Weld Servlet,看看CDI是否启动了自定义的JSF impl。