Eccezione: imansible trovare Factory: javax.faces.context.FacesContextFactory

Sto migrando da JBoss 5.1.0.GA a JBoss 6.0.0-Final e sto affrontando la seguente eccezione durante l’inizializzazione di 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] 

Ho esaminato il codice e ho scoperto che FactoryFinder cerca il FactoryManager corrispondente basato sul classloader del thread corrente. Ho anche scoperto che il mio FactoryFinder.FACTORIES_CACHE contiene due voci per due caricatori di class:

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

La mia struttura di implementazione sta seguendo:

 * 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 

Sto usando Mojarra-1.2 come implementazione JSF

  org.jboss.jbossfaces.JSF_CONFIG_NAME Mojarra-1.2 

Dopo un po ‘di debug, ho potuto riassumere:

  1. all JSF initialization is made in BaseClassLoader thread, ie 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. 

Ho controllato JBoss 5.1.0 e assicurato che l’inizializzazione e l’accesso per FactoryManager fossero realizzati in thread con lo stesso caricatore di class.

Ho provato a google non ho trovato molte informazioni su qualcuno con lo stesso problema – il che mi fa pensare che qualcosa non va nel mio ambiente.

Qualcuno può commentare o aiutare con questo?

Questo è un segno dell’inquinamento del classpath. JBoss viene già fornito con JSF in bundle. Questa eccezione può verificarsi se si raggruppa JSF anche nel WAR. Si scontrerà solo

Ci sono 2 soluzioni:

  1. Sbarazzati di jsf-api e jsf-impl JARs nella tua WAR (cioè non dovrebbero finire in /WEB-INF/lib dopo la build / deploy.

  2. Dì a JBoss che la tua GUERRA viene spedita con la sua versione di JSF in modo che JBoss non ne faccia uso.

      org.jboss.jbossfaces.WAR_BUNDLES_JSF_IMPL true  

Ho avuto lo stesso problema, ma con GlassFish v3 incorporato. Ho aggiunto questo e ha funzionato:

  com.sun.faces.config.ConfigureListener  

Ecco la pagina web spiega il problema: Utilizzo di JSF 1.2 con Facelets su Google App Engine .

Avevo lo stesso problema con Jboss EAP 6.1 e 6.3.

Sto usando Maven, quindi, il mio problema riguardava la generazione del file EAR, quando sto usando Maven ho scoperto che il mio file EAR è stato distribuito con le dipendenze “esplose”, vale a dire che il mio file EAR era stato distribuito con una cartella contenente i file per il mio progetto e non con un file WAR e JAR.

Quando ho esaminato le differenze tra la directory EAR esplosa e l’archivio EAR ho scoperto che ciò che vedi non è ciò che ottieni con Maven. Penso che il problema sia che i vari plugin Maven per WAR e EAR non vengono applicati durante la creazione delle directory esplose.

Per risolvere il problema, ho appena rimosso le direttive “scompattiamo” dal POM per l’EAR.

   br.web Web /project false   br.ejb Ejb false   

Inoltre, non è consigliabile che le directory esplose vengano utilizzate in un file EAR.