maven中使用tomcat7插件servlet-api的jar包冲突

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/luojishan1/article/details/81159975

一、错误日志

    tomcat容器启动正常,访问时报出如下错误:

配置如下:

maven的pom.xml配置

Java Build Path -->Libraries配置

原因分析:

        想必到这里很多小伙伴已经明白了,但截图都到这了,还是说一下,因为有些同学还是搞不清楚。你可能会遇到如下问题:pom.xml不添加servlet-api依赖,那么项目直接就会报错,因为你创建的是一个servlet的子类,编译也无法通过,会报找不到类错误,英文我就不说了。但pom.xml中引入这个依赖,tomcat容器启动没问题,但你访问的时候就出现了上面的错误。这就是jar包冲突了,那么怎么冲突的呢?首先,我们在pom.xml中引入了servlet-api这个依赖,但是我们使用了tomcat7插件,我们看一下tomcat7插件依赖哪些。根据tomcat7插件的坐标,我们找到在仓库中的位置,看到有个文件,

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

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

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

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

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

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

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

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

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

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

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

解决方式二:将我们自己引入的servlet-api去除,而是在Java Build Path -->Libraries配置中添加Server Runtim,如下:

这样的目的是,编译阶段可以使用tomcat容器中的servlet-api了,运行时也是tomcat7容器中的servlet-api。

总结:

程序中使用到javax.servlet.http.HttpServletRequest等类内容,然而这些类是依赖于tomcat容器lib包下的jar包,工程中导入这两个jar包后就会和tomcat产生冲突。

javax包下都是jdk提供接口规范,由第三方服务器厂商自己来实现。

工程中导入的目的是为了能顺利使用这两个jar包,包含正确编译、使用等。

 解决方式:

   1.在tomcat的context.xml中添加一段配置,这段配置的作用就是采用jvm的代理模式,优先使用父类包含的jar包。

  <Loader delegate="false"/>

        delegate值为true时,使用代理模式,加载前先访问上级loader。 false代表从本web应用程序中查找,不推荐。        

    2.如果使用maven,可以将依赖jar包的作用域调成provide,作用就是只在编译、测试环境下使用,发布时jar包会由JDK或容器提供,不会发布此jar包。换言之,provide作用于不具有传递性。这也是与compile作用域的区别(compile会将jar发布出去)。

    3.编写项目以及发布的时候将两个jar复制到lib并加入buildpath,项目运行之前删掉两个jar。这种方式不方便,但是能达到效果。(不推荐)。

    4.无需复制jar包,直接将tomcat目录下的jar添加到工程中。到build path中Add Library →User Library,将tomcat/lib下servlet-api.jar和jsp-api.jar放到User Library中,buildPath给工程就OK,Servelt Runtime的方式就比较粗暴。

猜你喜欢

转载自blog.csdn.net/luojishan1/article/details/81159975
今日推荐