2 Replies Latest reply on Apr 1, 2011 4:45 AM by varkon

    Exception: could not find Factory: javax.faces.context.FacesContextFactory

    ylitvinov

      Hello,

       

      I'm migrating from JBoss 5.1.0.GA to JBoss 6.0.0-Final and facing following exception during FacesServler initialization

       

      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]
      

       

      I've looked into code and found out that FactoryFinder looks up corresponding FactoryManager based on current thread classloader. I also found that my FactoryFinder.FACTORIES_CACHE contains two entries for two class loaders:

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

       

      My deploy structure is following:

       

      • deploy
        • 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
        • jbossweb.deployer
        • jsf.deployer
        • and others

       

      I'm using Mojarra-1.2 as JSF implementation

       

      <context-param>

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

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

      </context-param>

       

      After some debugging I could sumup:

        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.

       

      I checked JBoss 5.1.0 and ensured that initialization and access for FactoryManager's were made in threads having same class loader.

      I've tried to google by didn't find much information about anybody having same problem - which makes me think something is wrong in my environment.

       

      Can anybody comment on or help with this?