pom.xml不添加servlet-api依赖,那么项目直接就会报错,因为你创建的是一个servlet的子类,编译也无法通过,会报找不到类错误,英文我就不说了。但pom.xml中引入这个依赖,tomcat容器启动没问题,但你访问的时候就出现了上面的错误。这就是jar包冲突了,那么怎么冲突的呢?首先,我们在pom.xml中引入了servlet-api这个依赖,但是我们使用了tomcat7插件,我们看一下tomcat7插件依赖哪些。根据tomcat7插件的坐标,我们找到在仓库中的位置,看到有个文件,




maven jar包冲突排查 maven中jar包冲突怎么解决_cmd运行jar包报错找不到主类


OK,我们打开这个文件,会发现,它依赖了


maven jar包冲突排查 maven中jar包冲突怎么解决_android jar包冲突_02


,我们继续找,然后发现这个tomcat-servlet-api和我们自己在pom.xml引入的servlet-api有什么区别呢,看下图:


maven jar包冲突排查 maven中jar包冲突怎么解决_cmd运行jar包报错找不到主类_03


到这里,发现jar包冲突了。我们编译时使用的3.0的,运行期加载的也是3.0,但是加载这个类的类加载器权限比较低,对于整个web容器里的资源,加载的这个类可能访问不到,导致出现这个问题。(注意,tomcat的类加载机制和JAVA默认的的不太一样,它先加载WEB项目的)。

解决方式一:什么都不用动,给我们自己引入的servlet-api加一个作用域


maven jar包冲突排查 maven中jar包冲突怎么解决_maven安装本地jar包_04


如果你不加,那么这个依赖的作用域默认是<scope>compile</scope>,作用域什么意思呢?如下:

compile:默认值,适用于所有阶段(表明该jar包在编译、运行以及测试中路径俊可见),并且会随着项目直接发布。

provided:编译和测试时有效,并且该jar包在运行时由服务器提供。如servlet-api.

runtime:运行时使用,对测试和运行有效。如jdbc.

test:只在测试时使用,在编译和运行时不起作用。发布项目时没有作用。

system:不依赖maven仓库解析,需要提供依赖的显式的置顶jar包路径。对项目的移植来说是不方便的。

作用域变成provided后,我们编译用的是我们自己引入的,而在运行时只能加载到tomcat容器的。