2011-10-25 209 views
20

noto que cuando se trata de fijar mi JSF 2 webapp que se ejecuta en el embarcadero, tengo este error:no pudo encontrar la fábrica: javax.faces.context.FacesContextFactory

java.lang.IllegalStateException: La aplicación no era correctamente inicializado en el arranque, no pudo encontrar la fábrica: javax.faces.context.FacesContextFactory

que se resuelve fácilmente añadiendo esto a mi web.xml

<listener> 
    <listener-class> 
     com.sun.faces.config.ConfigureListener 
    </listener-class> 
</listener> 

He intentado buscar una explicación detallada, pero en vano ..

embarcadero-maven-plugin: 8.0.3.v20111011: Run + JDK 7 + Eclipse Indigo

Y aquí está mi dependencia Maven:

<dependencies> 
    <dependency> 
     <groupId>org.glassfish</groupId> 
     <artifactId>javax.faces</artifactId> 
     <version>2.1.3</version> 
     <scope>compile</scope> 
    </dependency> 
</dependencies> 

aquí es mi 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> 

y aquí está la salida del plugin de amarre:

[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. 

¿Alguna idea?

+0

¿Tiene la dependencia de mojarra? – Bozho

+0

@Bozho: supongo que sí, ya que al agregar la etiqueta de escucha hace que funcione – bertie

Respuesta

28

Este detector se supone que JSF 1.x se debe registrar automáticamente mediante el archivo de definición de biblioteca de etiquetas jsf_core.tld. Puede encontrarlo en la carpeta /META-INF del archivo JAR de implementación JSF. En caso de Mojarra 2.1.3 (que parece estar utilizando según los registros), el detector se registra como sigue por la línea 80 y en:

<!-- ============== 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>  

Sin embargo, esto no es aparentemente ha recogido adecuadamente por el embarcadero . También he leído en alguna parte que cuando el FacesServlet se ha inicializado antes de el archivo TLD ha sido procesado, entonces también obtendrá exactamente esta excepción. Quizás esto esté sucediendo en Jetty. Para excluir uno y otro, intente eliminar la entrada <load-on-startup> para que se cargue solo en la primera solicitud HTTP concreta, mucho después de que se haya procesado el TLD. De cualquier forma, registrar explícitamente al oyente en web.xml debería resolverlo.

Además, desde JSF 2.x, además del archivo TLD, se supone que el oyente debe registrarse automáticamente mediante una implementación ServletContainerInitializer en el archivo JAR para solucionar un error de Glassfish 3. En Mojarra 2.x esta es la clase com.sun.faces.config.FacesInitializer que tiene las siguientes líneas que comienzan en la línea 131: (supuestamente)

// 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); 

Esto funciona en Servlet 3.0 contenedores sólo, como Tomcat 7, Glassfish 3, Espolón 8, etc. Parece que está utilizando Jetty 8.0, que debería cumplir con el Servlet 3.0, pero su web.xml se declara conforme al Servlet 2.5, por lo que el contenedor se ejecutará en el modo de repliegue Servlet 2.5. Cambiar su web.xml para conformar el Servlet 3.0 debe activar este inicializador.

+0

He intentado tanto eliminar la carga al iniciar como cambiar a 3.0, pero aún con el mismo error. Creo que es hora de pasar a tomcat7 nuevamente para poner a prueba las cosas. Estaba pensando en usar embarcadero por su capacidad de desplegarse rápidamente con una guerra explosiva con el plugin maven. Encontraré otras formas para que estas funcionen en tomcat7 más tarde. Gracias ! – bertie

+0

De nada. – BalusC

+0

Después de habilitar la función Jetty 8 "anotaciones", descubrí que Jetty usa una versión de Jasper de GlassFish que omite intencionalmente el Mojarra ConfigureListener definido en el archivo TLD. Además, Mojarra FacesInitializer no registrará Mojarra ConfigureListener si FacesServlet está definido en web.xml. Sin embargo, lo hice funcionar registrando un ServletContainerInitializer personalizado. Para obtener más información, consulte [Implementación de portlets JSF en Jetty] (http://www.liferay.com/community/wiki/-/wiki/Main/Deploying+JSF+Portlets+on+Jetty) y [FACES-1668] (http://issues.liferay.com/browse/FACES-1668). –

0

Una resolución más: Recibí este error después de crear archivos java sobre la marcha con CXF desde wsdl.

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

CXF pone su propio cargador de clases (instancia de URLClassLoader) al cargador de clases del hilo. Funciona de la manera normal, hasta que el hilo del usuario entra en FactoryFinder de JSF, que está almacenado en la memoria caché de ClassLoader. Debido a que ClassLoader cambió, se crea un nuevo FactoryManager, que no se puede inicializar, porque las listas de instancias de implementación se eliminan cuando se inicia el FactoryManager original. Debido a esto, las clases de implementación no se encuentran, por lo tanto, se lanza la IllegalStateException.

Solución: haga una copia de seguridad del ClassLoader original antes de createClient de CXF, guarde el URLClassLoader en una variable y vuelva a colocar el ClassLoader original en el Thread. Cuando desee acceder a una clase dinámica desde CXF, búsquela a través del URLClassLoader que coloca en una variable.

Cuestiones relacionadas