将基于 Maven 的 JSF 项目部署到 Tomcat 会导致 java.lang.ClassNotFoundException:javax.faces.webapp.FacesServlet [重

Posted

技术标签:

【中文标题】将基于 Maven 的 JSF 项目部署到 Tomcat 会导致 java.lang.ClassNotFoundException:javax.faces.webapp.FacesServlet [重复]【英文标题】:Deploying Maven based JSF project to Tomcat results in java.lang.ClassNotFoundException: javax.faces.webapp.FacesServlet [duplicate] 【发布时间】:2014-09-11 06:01:50 【问题描述】:

我一直在尝试在 Apache Tomcat 8 上部署 JSF 组件。每次重新启动和部署服务器时,我都会收到 ClassNotFoundException。

日志

Jul 20, 2014 10:31:35 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-nio-8080"]
Jul 20, 2014 10:31:35 PM org.apache.tomcat.util.net.NioselectorPool getSharedSelector
INFO: Using a shared selector for servlet write/read
Jul 20, 2014 10:31:35 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["ajp-nio-8009"]
Jul 20, 2014 10:31:35 PM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
INFO: Using a shared selector for servlet write/read
Jul 20, 2014 10:31:35 PM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 1451 ms
Jul 20, 2014 10:31:35 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Catalina
Jul 20, 2014 10:31:35 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/8.0.9
Jul 20, 2014 10:31:35 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-nio-8080"]
Jul 20, 2014 10:31:35 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-nio-8009"]
Jul 20, 2014 10:31:35 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 191 ms
Connected to server
[2014-07-20 10:31:35,659] Artifact Java:war exploded: Artifact is being deployed, please wait...
Jul 20, 2014 10:31:36 PM org.apache.catalina.core.ApplicationContext log
INFO: Marking servlet Faces Servlet as unavailable
Jul 20, 2014 10:31:36 PM org.apache.catalina.core.StandardContext loadOnStartup
SEVERE: Servlet  threw load() exception
java.lang.ClassNotFoundException: javax.faces.webapp.FacesServlet
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1324)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1177)
    at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:550)
    at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:531)
    at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:150)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1105)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1041)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4932)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5218)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:724)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:700)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:714)
    at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1588)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:463)
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:413)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1466)
    at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)
    at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1307)
    at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1399)
    at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:828)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323)
    at sun.rmi.transport.Transport$1.run(Transport.java:178)
    at sun.rmi.transport.Transport$1.run(Transport.java:175)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:174)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:557)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:812)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:671)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

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"
         id="WebApp_ID" version="2.5">

    <display-name>JavaServerFaces</display-name>

    <!-- JSF mapping -->
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- Welcome page -->
    <welcome-file-list>
        <welcome-file>\index.xhtml</welcome-file>
    </welcome-file-list>

    <!-- Map these files with JSF -->
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.faces</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>

</web-app>

这里是maven依赖

pom.xml

 <!-- JSF dependency -->
 <dependency>
    <groupId>javax.faces</groupId>
    <artifactId>jsf-api</artifactId>
    <version>2.1</version>
    <scope>compile</scope>
 </dependency>

我后来在尝试使用 GlassFish 部署时添加了这个依赖项

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-web-api</artifactId>
    <version>7.0</version>
</dependency>

我也尝试使用 GlassFish 4.0,但无法解决问题。

编辑

我用这些依赖项更新了 POM

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-web-api</artifactId>
    <version>7.0</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.faces</artifactId>
    <version>2.2.7</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>7.0</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>com.sun.faces</groupId>
    <artifactId>jsf-api</artifactId>
    <version>2.2.7</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>com.sun.faces</groupId>
    <artifactId>jsf-impl</artifactId>
    <version>2.2.7</version>
    <scope>provided</scope>
</dependency>

<dependency>
     <groupId>javax.servlet</groupId>
     <artifactId>javax.servlet-api</artifactId>
     <version>3.1.0</version>
     <scope>provided</scope>
</dependency>

但我仍然无法使用 Tomcat 8.0.9 进行部署。当我使用 tomcat 的控制台管理器进行部署时,每个页面上都会出现 XML 解析错误。

【问题讨论】:

【参考方案1】:

对于 tomcat,您必须同时拥有 jsf-api 和 jsf-impl,因为 tomcat 没有捆绑 JSF。请添加以下依赖项

<dependency>
   <groupId>com.sun.faces</groupId>
   <artifactId>jsf-api</artifactId>
   <version>2.1.7</version>
</dependency>
<dependency>
   <groupId>com.sun.faces</groupId>
   <artifactId>jsf-impl</artifactId>
   <version>2.1.7</version>
</dependency>

将版本更新到您需要的任何版本。

【讨论】:

我按照你说的更新了,还更新了 POM 和问题。请回复。 您在提供的范围内添加。删除范围标签并尝试。 这很像编译,但表示您希望 JDK 或容器在运行时提供依赖项。例如,在为 Java Enterprise Edition 构建 Web 应用程序时,您可以将 Servlet API 和相关 Java EE API 的依赖设置为提供的范围,因为 Web 容器提供了这些类。此范围仅在编译和测试类路径上可用,并且不可传递。 但是我现在可以使用 glassfish 4 进行部署,tomcat 仍然存在问题。 Tomcat 给出 404。 如上所述,tomcat 没有捆绑 JSF,要么您必须将 JSF jar 捆绑到您的 WEB-INF/lib 中,要么您必须将 JSF jar 复制到 /lib 中。检查weblogs.java.net/blog/cayhorstmann/archive/2009/12/29/…

以上是关于将基于 Maven 的 JSF 项目部署到 Tomcat 会导致 java.lang.ClassNotFoundException:javax.faces.webapp.FacesServlet [重的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 Maven 正确安装和配置 JSF 库?

将基于 JSF 1.2 的 Web 应用程序部署到 JBoss EAP 7.0

JSF 和 Maven 项目的区别

Maven tomcat:run 目标和基于 jsf 注解的组件/转换器/验证器扫描

部署 JSF 复合组件以供共享使用

IDEA创建maven各种原型项目汇总