例外:找不到Factory:javax.faces.context.FacesContextFactory

时间:2011-03-10 11:39:07

标签: jsf jboss6.x

我正在从JBoss 5.1.0.GA迁移到JBoss 6.0.0-Final并在FacesServler初始化期间面临以下异常

2011-03-09 18:07:24,574 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/].[Faces Servlet]] (http-0.0.0.0-8080-4) Allocate exception for servlet Faces Servlet: java.lang.IllegalStateException: Application was not properly initialized at startup, could not find Factory: javax.faces.context.FacesContextFactory
    at javax.faces.FactoryFinder$FactoryManager.getFactory(FactoryFinder.java:725) [:1.2_15-20100816-SNAPSHOT]
    at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:239) [:1.2_15-20100816-SNAPSHOT]
    at javax.faces.webapp.FacesServlet.init(FacesServlet.java:164) [:1.2_15-20100816-SNAPSHOT]
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1208) [:6.0.0.Final]
    at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:955) [:6.0.0.Final]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:188) [:6.0.0.Final]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) [:6.0.0.Final]
    at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:181) [:6.0.0.Final]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) [:6.0.0.Final]
    at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:88) [:6.0.0.Final]
    at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:100) [:6.0.0.Final]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) [:6.0.0.Final]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [:6.0.0.Final]
    at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158) [:6.0.0.Final]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [:6.0.0.Final]
    at org.jboss.web.tomcat.service.request.ActiveRequestResponseCacheValve.invoke(ActiveRequestResponseCacheValve.java:53) [:6.0.0.Final]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:362) [:6.0.0.Final]
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [:6.0.0.Final]
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:654) [:6.0.0.Final]
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:951) [:6.0.0.Final]
    at java.lang.Thread.run(Thread.java:619) [:1.6.0_14]

我查看了代码并发现FactoryFinder根据当前的线程类加载器查找相应的FactoryManager。我还发现我的FactoryFinder.FACTORIES_CACHE包含两个类加载器的两个条目:

* BaseClassLoader which loads my EAR and
* WebCtxLoader.ENCLoader which is used during web app running and which was current context classloaded for failed thread.

我的部署结构如下:

* deploy
      o myapplication.ear
            + lib
                  # richfaces jars (3.3.1.GA)
                  # seam jars (2.2.1.Final)
                  # openfaces jar (2.0.0)
                  # other jars
            + META-INF
                  # jboss-app.xml
                  # application.xml
            + myapplication.war
                  # WEB-INF
                        * web.xml
                        * faces-config.xml
                        * components.xml
* deployers
      o jbossweb.deployer
      o jsf.deployer
      o and others

我正在使用Mojarra-1.2作为JSF实现

    <param-name>org.jboss.jbossfaces.JSF_CONFIG_NAME</param-name>

    <param-value>Mojarra-1.2</param-value>

经过一些调试后我可以总结:

     1. all JSF initialization is made in BaseClassLoader thread, i.e. when javax.faces.FactoryFinder#setFactory(..) is invoked getClassLoader() returns EAR BaseClassLoader
     2. A servlet thread (which cause exception) tries to look FactoryManager but his current classloader ( Thread.currentThread().getContextClassLoader()) is WebCtxLoader.ENCLoader. So nothing is returned and exception is thrown.

我检查了JBoss 5.1.0并确保在具有相同类加载器的线程中进行了FactoryManager的初始化和访问。

我试图通过谷歌搜索没有找到任何有同样问题的人的信息 - 这让我觉得我的环境出了问题。

有人可以评论或帮助吗?

3 个答案:

答案 0 :(得分:15)

这是类路径污染的标志。 JBoss已经捆绑了JSF。如果在WAR中捆绑JSF,也会发生此异常。它只会碰撞。

有两种解决方案:

  1. 摆脱WAR中的jsf-apijsf-impl JAR(即在构建/部署后,它们不应该以{{1​​}}结束。

  2. 告诉JBoss您的WAR附带了自己的JSF版本,以便JBoss不会使用它自己的版本。

    /WEB-INF/lib

答案 1 :(得分:13)

我遇到了同样的问题,但是使用了嵌入式GlassFish v3。我添加了这个并且它有效:

<listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>

以下网页解释了问题:Using JSF 1.2 with Facelets on Google App Engine

答案 2 :(得分:0)

我遇到了与Jboss EAP 6.1和6.3相同的问题。

我正在使用Maven,然后,我的问题是关于EAR文件的生成,当我使用Maven时,我发现我的EAR文件已被部署,其中依赖项“爆炸”,也就是说,我的EAR文件已部署为包含我的项目文件的文件夹,而不是WAR和JAR文件。

在调查爆炸的EAR目录和EAR档案之间的差异时,我发现你所看到的并不是你用Maven得到的。我认为问题是在创建爆炸目录时不会应用WAR和EAR构建的各种Maven插件。

为了解决这个问题,我刚从POM中删除了针对EAR的'unpack'指令。

<modules>  
        <webModule>  
                  <groupId>br.web</groupId>  
                  <artifactId>Web</artifactId>  
                  <contextRoot>/project</contextRoot>  
                  <unpack>false</unpack>
        </webModule>  
        <ejbModule>  
                  <groupId>br.ejb</groupId>  
                  <artifactId>Ejb</artifactId>  
                  <unpack>false</unpack>  
        </ejbModule>
  </modules>  

此外,我不建议在EAR文件中使用爆炸目录。