Исключение: не удалось найти Factory: javax.faces.context.FacesContextFactory
Я перехожу из 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 выполнялись в потоках, имеющих один и тот же загрузчик классов.
Я пытался использовать Google, не нашел много информации о том, кто имеет такую же проблему, что заставляет меня думать, что в моей среде что-то не так.
Может кто-нибудь прокомментировать или помочь с этим?
Ответы
Ответ 1
Это признак загрязнения класса. JBoss уже поставляется вместе с JSF. Это исключение может возникнуть, если вы добавите JSF в свою WAR. Это только столкнется.
Существует 2 решения:
-
Избавьтесь от jsf-api
и jsf-impl
JAR в вашей WAR (т.е. они не должны заканчиваться в /WEB-INF/lib
после сборки/развертывания.
-
Расскажите JBoss, что ваша WAR поставляется с собственной версией JSF, чтобы JBoss не использовал свой собственный.
<context-param>
<param-name>org.jboss.jbossfaces.WAR_BUNDLES_JSF_IMPL</param-name>
<param-value>true</param-value>
</context-param>
Ответ 2
У меня была такая же проблема, но со встроенным GlassFish v3. Я добавил это, и он сработал:
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
Вот веб-страница объясняет проблему: Использование JSF 1.2 с Facelets в Google App Engine.
Ответ 3
У меня была та же проблема с Jboss EAP 6.1 и 6.3.
Я использую Maven, тогда моя проблема заключалась в генерации файла EAR, когда я использую Maven, я обнаружил, что мой EAR файл был развернут с зависимостями "взорван", то есть мой EAR файл был развернут с папкой, содержащей файлы для моего проекта, а не WAR и JAR файлы.
При исследовании различий между взорванным каталогом EAR и архивом EAR я обнаружил, что то, что вы видите, не то, что вы получаете с Maven. Я думаю, проблема в том, что различные плагины Maven для WAR и EAR не применяются при создании взорванных каталогов.
Чтобы исправить это, я просто удалил директивы "unpack" из POM для 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>
Кроме того, я не рекомендую использовать взорванные каталоги в файле EAR.