问题
I notice that when trying to setup my JSF 2 webapp running on jetty, i have this error :
java.lang.IllegalStateException: Application was not properly initialized at startup, could not find Factory: javax.faces.context.FacesContextFactory
which is easily solved by adding this to my web.xml
<listener>
<listener-class>
com.sun.faces.config.ConfigureListener
</listener-class>
</listener>
I've tried searching for a detailed explanation but in futile ..
jetty-maven-plugin:8.0.3.v20111011:run + jdk 7 + eclipse indigo
And here's my maven dependency :
<dependencies>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.faces</artifactId>
<version>2.1.3</version>
<scope>compile</scope>
</dependency>
</dependencies>
Here's my 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>
and here's the output of the jetty plugin :
[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 SelectChannelConnector@0.0.0.0:8080 STARTING
[INFO] Starting scanner at interval of 10 seconds.
Any thoughts ?
回答1:
This listener is since JSF 1.x supposed to be automatically registered by the jsf_core.tld
tag library definition file. You can find it in the /META-INF
folder of the JSF implementation JAR file. In case of Mojarra 2.1.3 (which you seem to be using according the logs), the listener is registered as follows from line 80 and on:
<!-- ============== 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>
However, this is apparently not been picked up properly by Jetty. I've also read somewhere that when the FacesServlet
is been initialized before the TLD file is been processed, then you will also get exactly this exception. Perhaps this is happening in Jetty. To exclude the one and other, try to remove the <load-on-startup>
entry so that it will be loaded only on first concrete HTTP request, far after the TLD is been processed. In any way, explicitly registering the listener in web.xml
should indeed solve it.
Further, since JSF 2.x, in addition to the TLD file, the listener is also supposed to be automatically registered by a ServletContainerInitializer implementation in the JAR file in order to workaround a Glassfish 3 bug. In Mojarra 2.x this is the com.sun.faces.config.FacesInitializer
class which has the following lines starting at line 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);
This works in Servlet 3.0 containers only, such as Tomcat 7, Glassfish 3, Jetty 8 (supposedly!), etc. You seem to be using Jetty 8.0 which should thus comply Servlet 3.0, but your web.xml
is declared conform Servlet 2.5, so the container will run in Servlet 2.5 fallback modus. Changing your web.xml
to conform Servlet 3.0 should trigger this initializer.
回答2:
One more resolve: I got this error after I created java files on the fly with CXF from wsdl.
JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance();
Client client = factory.createClient(wsdlURL, serviceName);
CXF puts its own ClassLoader (instance of URLClassLoader) to the Thread's classloader. It works the normal way, until user's thread gets into JSF's FactoryFinder, which is cached by the ClassLoader as the key. Because the ClassLoader changed, it creates a new FactoryManager, which cannot be initialized, because the implementation instance lists are removed when the original FactoryManager initiated. Because of it, the Implementation classes are not found, hence the IllegalStateException is thrown.
Solution: backup the original ClassLoader before CXF's createClient, save the URLClassLoader in a variable and put back the original ClassLoader to the Thread. When you want to access a dynamic class from CXF, search it through the URLClassLoader you put in a variable.
来源:https://stackoverflow.com/questions/7886035/could-not-find-factory-javax-faces-context-facescontextfactory