开发者

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

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开发者_JAVA技巧.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
      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

I'm using Mojarra-1.2 as JSF implementation

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

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

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?


This is a sign of classpath pollution. JBoss already ships with JSF bundled. This exception can occur if you bundle JSF in your WAR as well. It'll only collide.

There are 2 solutions:

  1. Get rid of jsf-api and jsf-impl JARs in your WAR (i.e. they should not end up in /WEB-INF/lib after build/deploy.

  2. Tell JBoss that your WAR ships with its own version of JSF so that JBoss won't use its own.

    <context-param>
        <param-name>org.jboss.jbossfaces.WAR_BUNDLES_JSF_IMPL</param-name>
        <param-value>true</param-value>
    </context-param>
    


I had the same issue, but with embedded GlassFish v3. I added this and it worked:

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

Here is the web page explains the problem: Using JSF 1.2 with Facelets on Google App Engine.


I was having the same problem with Jboss EAP 6.1 and 6.3.

I´m using Maven, then, my problem was about the generation of the EAR file, when I´m using Maven I discovered that my EAR file was been deployed whith dependencies "exploded", that is to say, my EAR file was been deployed with a folder containing the files for my project, and not a WAR and a JAR files.

When investigating the differences between the exploded EAR directory and the EAR archive I discovered that what you see is not what you get with Maven. I think the issue is that the various Maven plugins for WAR and EAR building are not applied when creating the exploded directories.

To fix it, I just removed the 'unpack' directives from the POM for the EAR.

<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>  

In addition, I don't recommend that exploded directories should be used in a EAR file.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜