2
votes

we are trying to deploy a JSF2.0 web application into Apache Tomcat/7.0.23. and we are getting the following error:


INFO: Initializing Mojarra 2.0.4 (FCS b09) for context '/WSNzControl'
Dec 13, 2012 9:54:28 AM com.sun.faces.config.ConfigureListener contextInitialized
SEVERE: Critical error during deployment: 
java.lang.NoClassDefFoundError: com/sun/faces/spi/DiscoverableInjectionProvider
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:247)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1675)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1533)
    at com.sun.faces.util.Util.loadClass(Util.java:291)
    at com.sun.faces.spi.InjectionProviderFactory.getProviderFromEntry(InjectionProviderFactory.java:315)
    at com.sun.faces.spi.InjectionProviderFactory.findProviderClass(InjectionProviderFactory.java:283)
    at com.sun.faces.spi.InjectionProviderFactory.createInstance(InjectionProviderFactory.java:114)
    at com.sun.faces.application.ApplicationAssociate.<init>(ApplicationAssociate.java:209)
    at com.sun.faces.application.ApplicationImpl.<init>(ApplicationImpl.java:210)
    at com.sun.faces.application.ApplicationFactoryImpl.getApplication(ApplicationFactoryImpl.java:107)
    at com.sun.faces.config.processor.AbstractConfigProcessor.getApplication(AbstractConfigProcessor.java:130)
    at com.sun.faces.config.processor.ApplicationConfigProcessor.process(ApplicationConfigProcessor.java:252)
    at com.sun.faces.config.processor.AbstractConfigProcessor.invokeNext(AbstractConfigProcessor.java:114)
    at com.sun.faces.config.processor.LifecycleConfigProcessor.process(LifecycleConfigProcessor.java:116)
    at com.sun.faces.config.processor.AbstractConfigProcessor.invokeNext(AbstractConfigProcessor.java:114)
    at com.sun.faces.config.processor.FactoryConfigProcessor.process(FactoryConfigProcessor.java:216)
    at com.sun.faces.config.ConfigManager.initialize(ConfigManager.java:338)
    at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:226)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4765)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5260)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:866)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:842)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:615)
    at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1095)
    at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1617)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ClassNotFoundException: com.sun.faces.spi.DiscoverableInjectionProvider
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    ... 44 more

The application deploys fine in Tomcat v7.023 in our local (Win) but fails when deploying in the Tomcat v7.023 in a Linux server: Apache Tomcat/7.0.23 JVM 1.6.0_26-b03 Sun Microsystems Inc. Red Hat 4.4.6-3

JSF libraries are version mojarra-2.0.4-FCS and we included both jsf-api.jar and jsf-impl.jar in the WEB-INF\lib folder of the web app.

Here's the web.xml:


    <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_3_0.xsd" version="3.0">
  <display-name>WSNzControl</display-name>
  <welcome-file-list>
    <welcome-file>faces/resources/views/Main.xhtml</welcome-file>
  </welcome-file-list>
  <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>
  <context-param>
    <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
  </context-param>
  <context-param>
    <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
    <param-value>resources.application</param-value>
     </context-param>
   <listener>
   <listener-class>
   com.sun.faces.config.ConfigureListener
   </listener-class>
   </listener> 
   </web-app>

Any hint on what could be causing this error?

1

1 Answers

4
votes

This can happen when the Tomcat instance in question has by itself already JSF libraries bundled in its /lib folder or elsewhere which is covered by Tomcat's common classloader or maybe even the bootstrap classloader (which would however be a very bad setup).

You could confirm this by removing the JSF libraries from your webapp and deploying it. If it works, then contact the responsible server admin why Tomcat is configured like that. There's namely no way to tell Tomcat to not load its bundled JSF, so if you intend to deploy with a newer JSF version along the WAR, then you're totally stuck and dependent on the server admin. In fuller fledged Java EE containers like Glassfish and JBoss, it's namely possible to override the container-provided JSF implementation by a WAR-provided JSF implementation by a simple config entry.