13

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

Yury Litvinov
  • 1,354
  • 2
  • 16
  • 24

3 Answers3

16

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>
    
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 1
    Thank you for the comment. I know that JBoss 6.0.0 ships with JSF deployer and that is the reason why I did not included jsf-api and jsf-impl jars into my war (as I did in JBoss 5.1.0). Did you managed to use Mojarra 1.2 in JBoss 6.0? – Yury Litvinov Mar 10 '11 at 13:40
  • 1
    I didn't see your comment update: well, we're successfully running JSF 1.2 and 2.0 apps here which uses JBoss 6.0.0.Final bundled JSF impls. As to your problem, surely there must be another JSF impl somewhere in the EAR/WAR or even in JRE/lib(/ext) which is colliding the one provided by JBoss. – BalusC Mar 10 '11 at 15:43
  • @BalusC. I'm also having the error as OP's. My war file doesn't include JSF impl. I'm not sure about the jre6 though, although I had a look at the lib couldn't find any. Does jre6 comes with a jsf impl? – sarahTheButterFly May 13 '11 at 00:12
  • @sarah: No, JRE doesn't by default. It can happen that you (or someone else) has dropped the JSF JARs in JRE's lib. If after all still in vain, try to clean JBoss data, temp and work folders. – BalusC May 13 '11 at 00:25
  • @BalusC: Thanks for your prompt reply. I'm actually using embedded glassfish3 in Eclipse. How do I clean up the embedded glassfish3 data? BTW, my project's classpath is pointing to JDK1.6. I made it this way because Maven complains when JRE was used. I wonder if it has something to do with this? – sarahTheButterFly May 13 '11 at 00:43
  • @BalusC: I did what you suggested on the other discussion thread which is to find out what's on my classpath. Here is what I found out: `classLoader = WebappClassLoader (delegate=true; repositories=WEB-INF/classes/) SharedSecrets.getJavaNetAccess()=java.net.URLClassLoader$7@1c53bd7 workspace_helios/hello/gfembed8174621719549625198tmp/lib/install/applications/__ds_jdbc_ra/ workspace_helios/hello/gfembed8174621719549625198tmp/lib/install/applications/__cp_jdbc_ra/` – sarahTheButterFly May 19 '11 at 06:19
  • and `workspace_helios/hello/gfembed8174621719549625198tmp/lib/install/applications/__xa_jdbc_ra/ workspace_helios/hello/gfembed8174621719549625198tmp/lib/install/applications/__dm_jdbc_ra/ workspace_helios/hello/gfembed8174621719549625198tmp/applications/hello-0.0.1-SNAPSHOT/WEB-INF/classes/ workspace_helios/hello/gfembed8174621719549625198tmp/generated/ejb/hello-0.0.1-SNAPSHOT/` – sarahTheButterFly May 19 '11 at 06:22
  • This suggests no other jsf impl jars are there...so If classpath is not polluted, why this error still exists? – sarahTheButterFly May 19 '11 at 06:25
  • 1
    @BalusC: I finally solved the issue. Add this to web.xml worked ` com.sun.faces.config.ConfigureListener ` – sarahTheButterFly May 19 '11 at 06:50
  • I faced the same problem when trying to upgrade from weblogic 11g to weblogic 12c. removing these jars solved the problem :) – AFF Jan 11 '15 at 06:09
13

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.

Emil Sierżęga
  • 1,785
  • 2
  • 31
  • 38
sarahTheButterFly
  • 1,894
  • 3
  • 22
  • 36
  • Sarah, thank you very much for you comment. But I couldn't verify it right now. Will come back here with reply later. – Yury Litvinov May 20 '11 at 21:44
  • Do note that this answer is specific to GlassFish v3, not to JBoss AS as asked about in the question. This GlassFish-specific bug was already fixed in 3.1.x and then it's not necessary to explicitly register the configure listener. – BalusC Apr 30 '15 at 07:40
0

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.

Edson Cezar
  • 25,884
  • 5
  • 19
  • 27