找不到Factory:javax.faces.context.FacesContextFactory

我注意到,当试图安装我在docker上运行的JSF 2 webapp时,我有这个错误:

java.lang.IllegalStateException:应用程序在启动时未正确初始化,无法findFactory: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 indigo

这里是我的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> 

这里是jetty插件的输出:

 [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 omjpJettyWebAppContext{/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 omjpJettyWebAppContext{/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 omjpJettyWebAppContext{/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 SelectChannelConnector@0.0.0.0:8080 STARTING [INFO] Starting scanner at interval of 10 seconds. 

有什么想法吗 ?

这个监听器是自JSF 1.x假定由jsf_core.tld标签库定义文件自动注册的。 您可以在JSF实现JAR文件的/META-INF文件夹中find它。 在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正确拾起。 我也读过一些地方,当在TLD文件被处理之前 FacesServlet被初始化的时候 ,你也会得到这个exception。 也许这是发生在docker。 要排除这个和其他,尝试删除<load-on-startup>条目,以便它只在第一个具体的HTTP请求中加载,远在TLD被处理之后。 无论如何,显式注册监听器在web.xml应该确实解决它。

此外,除了TLD文件之外,自JSF 2.x以外,监听器也应该由JAR文件中的ServletContainerInitializer实现自动注册,以解决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's 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应该触发这个初始化程序。

还有一个解决scheme:在我用wsdl的CXFdynamic创buildjava文件后,出现了这个错误。

 JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance(); Client client = factory.createClient(wsdlURL, serviceName); 

CXF将自己的ClassLoader(URLClassLoader的实例)放到Thread的类加载器中。 它以正常的方式工作,直到用户的线程进入由ClassLoadercaching的JSF的FactoryFinder中作为关键字。 因为ClassLoader发生了变化,所以创build了一个新的FactoryManager,因为在初始的FactoryManager启动时删除了实现实例列表,所以它不能被初始化。 正因为如此,实现类没有find,因此抛出了IllegalStateException。

解决scheme:在CXF的createClient之前备份原始的ClassLoader,将URLClassLoader保存在一个variables中,并将原来的ClassLoader放回到Thread中。 当你想从CXF访问一个dynamic类时,通过放入一个variables的URLClassLoader来search它。