1 问题描述
Maven Web项目,每次使用Eclipse M2E插件对Project进行刷新,然后部署到Tomcat后都会提示ClassNotFoundException,究其原因,是Deployment Assembly中没有Maven Dependencies。如下图所示:
2 原因
Dynamic Web Module的版本与web.xml中指定的版本不同。
后面细细道来。
3.1 查看Dynamic Web Module版本
这里可以看到使用的是3.1版本。
3.2 查看web.xml中指定的版本
可以看到是3.0版本,所以就是这两个版本不一致导致的。
3.3 修改Dynamic Web Module的版本为3.0
直接项目右键Properties->Project Facets:
结果发现改不了。提示Cannot change version of project Dynamic Web Module to 3.0.如下图所示:
没关系,这个配置在文件(/.settings/org.eclipse.wst.common.project.facet.core.xml)中也有保存:
修改为3.0版本后保存。
修改Dynamic Web Module的方式还可以这样:
取消对Dynamic Web Module的勾选->Apply->勾选Dynamic Web Module->Apply,具体操作可以看下参考链接。
注意:Dynamic Web Module的不同版本对JDK的版本有要求,所以也有可能你需要把JDK版本也改掉。
Dynamic Web Module 版本 | JDK版本 |
2.2 | Java 1.3 or newer |
2.3 | Java 1.3 or newer |
2.4 | Java 1.3 or newer |
2.5 | Java 1.5 or newer |
3.0 | Java 1.6 or newer |
3.1 | Java 1.7 or newer |
4.0 | Java 1.8 or newer |
3.4 Update Maven Project
3.5 验证结果
先看看是不是真的把Dynamic Web Module改成3.0版本了。
确定Deployment Assembly中是否包含Maven Dependencies。
4 原因分析
4.1 Dynamic Web Module是什么?
如果一个Project有Dynamic Web Module加持,那么这个Project就是归类为是一个Web Project。
另外,看下Project Facts中Dynamic Web Module的描述信息:
Adds support for the Java Servlet API, for generation of dynamic Web page content.
其含义为:添加对Servlet API的支持,加它干嘛呢?生成动态Web页面的内容。
4.2 这个Dynamic Web Module的版本是什么?
是servlet api的版本。具体如下:
2.2-2.5版本
这里可以看出,在3.0版没有正式发布的时候,artifact做了修改(因为Oracle收购Sun?)。所以Servlet API的依赖要这样写(注意artifactId的变化):
<!-- Servlet API 3.0 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<!-- Servlet API 2.5 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
4.3 3.0这个特殊的版本
上面也能看到artifact在3.0的第一个alpha版本到release版本就变了,所以会有什么影响呢?
举个例子来说:如果Dynamica Web Module的版本是3.1,那么直接把web.xml中的版本改成3.1是不是也能解决Deployment Assembly中丢失Maven依赖的问题?
直接改成3.1,web.xml会报错:
错误如下:
The errors below were detected when validating the file "web-app_3_1.xsd" via the file "web.xml". In most cases these errors can be detected by validating "web-app_3_1.xsd" directly. However it is possible that errors will only occur when web-app_3_1.xsd is validated in the context of web.xml.
原因是http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd这个XSD文件根本不存在。那么怎么才能找出来正确的?
方式1:注意到xsi:schemaLocation中指定了http://java.sun.com/xml/ns/javaee了吗?
直接访问看看是什么:
哇,各种java的xml schema合集啊,并且说了最新的schema的location是:http://xmlns.jcp.org/xml/ns/javaee/。直接访问这个地址的话,也还会重定向到当前这个页面。继续往后看,可以看到各种schema的URL及描述:
web-app_3_1.xsd找到了:http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/javaee/web-app_3_1.xsd
前面说过:http://xmlns.jcp.org/xml/ns/javaee/会重定向到http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/javaee。
所以,地址改成http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd,试了下可以访问。再把xmlns由老的http://java.sun.com/xml/ns/javaee改成新的http://xmlns.jcp.org/xml/ns/javaee/,就会变成这样:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>111111</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
方式2:直接在Eclipse中建一个Dynamic Web Project,选择Dynamic Web Module Version为3.1
得到的web.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>111111</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
参考
1.[解决Cannot change version of project facet Dynamic web module to 2.5](https://blog.csdn.net/steveguoshao/article/details/38414145)
2.[Eclipse 下载 开源项目 maven依赖丢失和 Deployment Assembly 丢失](https://blog.csdn.net/achenyuan/article/details/78434848)
3.[Eclipse里每次使用maven的update projects时,Web Deployment Assembly中添加maven dependencies时自动消失的问题](https://blog.csdn.net/achenyuan/article/details/78434848)
4.[Java EE: XML Schemas for Java EE Deployment Descriptors](http://xmlns.jcp.org/xml/ns/javaee/)