Не удалось найти Factory: javax.faces.context.FacesContextFactory
Я замечаю, что при попытке настроить мой JSF 2 webapp, работающий на причале, у меня есть эта ошибка:
java.lang.IllegalStateException: приложение не было правильно инициализированный при запуске, не удалось найти Factory: javax.faces.context.FacesContextFactory
что легко решить, добавив это в мой web.xml
<listener>
<listener-class>
com.sun.faces.config.ConfigureListener
</listener-class>
</listener>
Я попытался найти подробное объяснение, но бесполезно.
jetty-maven-plugin: 8.0.3.v20111011: run + jdk 7 + eclipse индиго
И вот моя зависимость от maven:
<dependencies>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.faces</artifactId>
<version>2.1.3</version>
<scope>compile</scope>
</dependency>
</dependencies>
Вот мой web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>Basic Setup Web Application</display-name>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
<listener>
<listener-class>
com.sun.faces.config.ConfigureListener
</listener-class>
</listener>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
</web-app>
и здесь вывод плагина причала:
[INFO] <<< jetty-maven-plugin:8.0.3.v20111011:run (default-cli) @ BasicSetup <<<
[INFO]
[INFO] --- jetty-maven-plugin:8.0.3.v20111011:run (default-cli) @ BasicSetup ---
[INFO] Configuring Jetty for project: BasicSetup Maven Webapp
[INFO] webAppSourceDirectory C:\Users\albert\workspace\BasicSetup\src\main\webapp does not exist. Defaulting to C:\Users\albert\workspace\BasicSetup\src\main\webapp
[INFO] Reload Mechanic: automatic
[INFO] Classes = C:\Users\albert\workspace\BasicSetup\target\classes
[INFO] Context path = /basicSetup
[INFO] Tmp directory = C:\Users\albert\workspace\BasicSetup\target\tmp
[INFO] Web defaults = org/eclipse/jetty/webapp/webdefault.xml
[INFO] Web overrides = none
[INFO] web.xml file = file:/C:/Users/albert/workspace/BasicSetup/src/main/webapp/WEB-INF/web.xml
[INFO] Webapp directory = C:\Users\albert\workspace\BasicSetup\src\main\webapp
2011-10-25 14:24:51.091:INFO:oejs.Server:jetty-8.0.3.v20111011
2011-10-25 14:24:51.334:INFO:oejpw.PlusConfiguration:No Transaction manager found - if your webapp requires one, please configure one.
2011-10-25 14:24:52.108:INFO:oejsh.ContextHandler:started o.m.j.p.JettyWebAppContext{/basicSetup,[file:/C:/Users/albert/workspace/BasicSetup/src/main/webapp/, jar:file:/C:/Users/albert/.m2/repository/org/glassfish/javax.faces/2.1.3/javax.faces-2.1.3.jar!/META-INF/resources/]},file:/C:/Users/albert/workspace/BasicSetup/src/main/webapp/
2011-10-25 14:24:52.108:INFO:oejsh.ContextHandler:started o.m.j.p.JettyWebAppContext{/basicSetup,[file:/C:/Users/albert/workspace/BasicSetup/src/main/webapp/, jar:file:/C:/Users/albert/.m2/repository/org/glassfish/javax.faces/2.1.3/javax.faces-2.1.3.jar!/META-INF/resources/]},file:/C:/Users/albert/workspace/BasicSetup/src/main/webapp/
2011-10-25 14:24:52.108:INFO:oejsh.ContextHandler:started o.m.j.p.JettyWebAppContext{/basicSetup,[file:/C:/Users/albert/workspace/BasicSetup/src/main/webapp/, jar:file:/C:/Users/albert/.m2/repository/org/glassfish/javax.faces/2.1.3/javax.faces-2.1.3.jar!/META-INF/resources/]},file:/C:/Users/albert/workspace/BasicSetup/src/main/webapp/
2011-10-25 14:24:52.149:WARN:/basicSetup:unavailable
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:967)
at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:316)
at javax.faces.webapp.FacesServlet.init(FacesServlet.java:302)
at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:456)
at org.eclipse.jetty.servlet.ServletHolder.doStart(ServletHolder.java:276)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:779)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:255)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1212)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:610)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:453)
at org.mortbay.jetty.plugin.JettyWebAppContext.doStart(JettyWebAppContext.java:256)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:224)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:167)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:224)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:89)
at org.eclipse.jetty.server.Server.doStart(Server.java:262)
at org.mortbay.jetty.plugin.JettyServer.doStart(JettyServer.java:65)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:511)
at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:364)
at org.mortbay.jetty.plugin.JettyRunMojo.execute(JettyRunMojo.java:514)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:107)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:319)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:534)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
[INFO] Started Jetty Server
2011-10-25 14:24:52.165:INFO:oejs.AbstractConnector:Started [email protected]:8080 STARTING
[INFO] Starting scanner at interval of 10 seconds.
Любые мысли?
Ответы
Ответ 1
Этот слушатель с тех пор, как JSF 1.x должен автоматически регистрироваться файлом определения библиотеки тегов jsf_core.tld
. Вы можете найти его в папке /META-INF
JAR файла JSF-реализации. В случае Mojarra 2.1.3 (который вы, по-видимому, используете в соответствии с журналами), слушатель регистрируется следующим образом из строки 80 и на:
<!-- ============== Configuration Listener ============== -->
<!--
This ServletContextListener initializes the runtime environment
of the JavaServer Faces Reference Implementation when a web
application including it is initialized by the container.
-->
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
Однако, по-видимому, это не было правильно подобрано Jetty. Я также где-то читал, что при инициализации FacesServlet
до того, как файл TLD будет обработан, вы также получите именно это исключение. Возможно, это происходит в Jetty. Чтобы исключить одно и другое, попробуйте удалить запись <load-on-startup>
, чтобы она загружалась только по первому конкретному HTTP-запросу, далеко после обработки TLD. В любом случае, явная регистрация слушателя в web.xml
должна действительно решить его.
Кроме того, поскольку JSF 2.x в дополнение к файлу TLD, слушатель также должен автоматически регистрироваться ServletContainerInitializer
реализация в файле JAR, чтобы обход ошибки Glassfish 3. В Mojarra 2.x это класс com.sun.faces.config.FacesInitializer
, который имеет следующие строки, начиная со строки 131:
// The following line is temporary until we can solve an ordering
// issue in V3. Right now the JSP container looks for a mapping
// of the FacesServlet in the web.xml. If it not present, then
// it assumes that the application isn't a faces application. In this
// case the JSP container will not register the ConfigureListener
// definition from our TLD nor will it parse cause or JSP TLDs to
// be parsed.
servletContext.addListener(com.sun.faces.config.ConfigureListener.class);
Это работает только в контейнерах Servlet 3.0, таких как Tomcat 7, Glassfish 3, Jetty 8 (предположительно!) и т.д. Кажется, вы используете Jetty 8.0, который должен, таким образом, соответствовать Servlet 3.0, но ваш web.xml
объявлен совместимым Servlet 2.5, поэтому контейнер будет работать в резервном модуле Servlet 2.5. Изменение вашего web.xml
для соответствия Servlet 3.0 должно инициировать этот инициализатор.
Ответ 2
Еще одно решение:
Я получил эту ошибку после создания java файлов на лету с CXF из wsdl.
JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance();
Client client = factory.createClient(wsdlURL, serviceName);
CXF помещает свой собственный ClassLoader (экземпляр URLClassLoader) в загрузчик класса Thread. Он работает нормально, пока пользовательский поток не попадет в JSF FactoryFinder, который кэшируется ClassLoader в качестве ключа.
Поскольку ClassLoader изменился, он создает новый FactoryManager, который не может быть инициализирован, поскольку списки экземпляров реализации удаляются при запуске оригинального FactoryManager. Из-за этого классы реализации не найдены, поэтому выбрано исключение IllegalStateException.
Резервное копирование исходного ClassLoader до CXF createClient, сохраните URLClassLoader в переменной и верните исходный ClassLoader в Thread.
Когда вы хотите получить доступ к динамическому классу из CXF, найдите его через URLClassLoader, который вы введете в переменную.