Caused by: java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addServlet

一:启动tomcat后加载servlet项目后出现下面异常信息,其中红字和蓝字中表示同信息两种不同的情况,对此有两种解决思路

四月 20, 2016 12:50:09 下午 org.apache.catalina.loader.WebappClassLoader validateJarFile
信息: validateJarFile(D:\Java\apache-tomcat-7.0.57\webapps\day03\WEB-INF\lib\el-api.jar) - jar not loaded. See Servlet Spec 3.0, section 10.7.2. Offending class: javax/el/Expression.class
四月 20, 2016 12:50:09 下午 org.apache.catalina.loader.WebappClassLoader validateJarFile
信息: validateJarFile(D:\Java\apache-tomcat-7.0.57\webapps\day03\WEB-INF\lib\servlet-api.jar) - jar not loaded. See Servlet Spec 3.0, section 10.7.2. Offending class: javax/servlet/Servlet.class
四月 20, 2016 12:50:09 下午 org.apache.tomcat.util.digester.Digester endElement
严重: End event threw exception

严重: Parse error in application web.xml file at jndi:/localhost/day03/WEB-INF/web.xml

org.xml.sax.SAXParseException; systemId: jndi:/localhost/day03/WEB-INF/web.xml; lineNumber: 8; columnNumber: 13; Error at (8, 13) : org.apache.catalina.deploy.WebXml addServlet
    at org.apache.tomcat.util.digester.Digester.createSAXException(Digester.java:2711)
    at org.apache.tomcat.util.digester.Digester.createSAXException(Digester.java:2743)
    at org.apache.tomcat.util.digester.Digester.endElement(Digester.java:1066)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at org.apache.tomcat.util.digester.Digester.parse(Digester.java:1561)
    at org.apache.catalina.startup.ContextConfig.parseWebXml(ContextConfig.java:1825)
    at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1263)
    at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:889)
    at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:386)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5380)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.startup.HostConfig.reload(HostConfig.java:1484)
    at org.apache.catalina.startup.HostConfig.checkResources(HostConfig.java:1462)
    at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1646)
    at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:328)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
    at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1374)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1546)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1556)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1524)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addServlet
    at org.apache.tomcat.util.IntrospectionUtils.callMethod1(IntrospectionUtils.java:849)
    at org.apache.tomcat.util.digester.SetNextRule.end(SetNextRule.java:201)
    at org.apache.tomcat.util.digester.Digester.endElement(Digester.java:1063)
    ... 30 more
四月 20, 2016 12:47:58 下午 org.apache.catalina.startup.ContextConfig parseWebXml
严重: Occurred at line 8 column 13
四月 20, 2016 12:47:58 下午 org.apache.catalina.startup.ContextConfig configureStart
严重: Marking this application unavailable due to previous error(s)
四月 20, 2016 12:47:58 下午 org.apache.catalina.core.StandardContext startInternal
严重: Error getConfigured
四月 20, 2016 12:47:58 下午 org.apache.catalina.core.StandardContext startInternal

严重: Context [/day03] startup failed due to previous errors


二、分析过程

 信息: validateJarFile(D:\Java\apache-tomcat-7.0.57\webapps\day03\WEB-INF\lib\el-api.jar) - jar not loaded. See Servlet Spec 3.0, section 10.7.2. Offending class: javax/el/Expression.class

问题分析&&解决方案:


1、项目的WEB-INF/lib下有servlet-api.jar。


2、项目的WEB-INF/lib下

有包含javax.servlet包的JAR包(如WebLogic8.1的weblogic.jar),造成与Tomcat自身的servlet-api.jar的冲突。

因为Tomcat的WebappClassLoader加载JAR包时会进行校验。



 


 

A、针对第一种情况,项目的servlet-api.jar不要放在WEB-INF/lib下,可以放在工程下的一个专门的目录(如lib)下面,然后通过Eclipse导入到工程中。

 

B、针对第二种情况,暂时没有想到简单的解决办法,在我的项目中由于某种特殊的需求,weblogic.jar是通过自定义的类加载器加载的,而不是由Tomcat的WebappClassLoader加载,所以上述问题也就不存在了。如果您遇到同样的问题,可以借鉴此种方案。



Caused by: java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addServlet

问题分析

首先,你需要了解一下JVM的Classloader机制(详细请自行google之)。
简而言之,JVM的classloader加载继承关系分为BootstarpClassLoader --> ExtClassLoader --> SystemClassLoader,应用的WebAppClassLoader继承自SystemClassLoader,在加载具体某个类时,一般会先委托给父类ClassLoader,当父类ClassLoader无法加载成功时,才会再由子类ClassLoader尝试加载,这就是所谓的delegate机制。

其次,Tomcat在jvm的ClassLoader机制上增加了几个继承层次。
SystemClassLoader --> CommonClassLoader -->(ServerClassLoader | SharedClassLoader --> WebAppClassLoader)。
CommonClassLoader用来加载${CATALINA_HOME}/conf/catalina.properties中common.loader配置目录下的类文件,一般是用来加载${CATALINA_HOME}/lib下的文件。该loader加载的类为tomcat服务器和tomcat下面的所有webApp所共享。
ServerClassLoader用来加载${CATALINA_HOME}/conf/catalina.properties中server.loader配置目录下的类文件,一般是用来加载${CATALINA_HOME}/server下的文件。该loader加载的类为tomcat服务器所独有核心类,tomcat下面的WebApp无法访问。
SharedClassLoader用来加载${CATALINA_HOME}/conf/catalina.properties中shared.loader配置目录下的类文件,一般是用来加载${CATALINA_HOME}/shared下的文件。该loader加载的类为tomcat下面的所有webApp所共享。
WebAppClassLoader用来加载${CATALINA_HOME}/webapps/目录下每个WebApp应用的/WEB-INF/class,/WEB-INF/lib的类文件,每个WebApp对应一个WebAppClassLoader,用来加载其所需要的类文件。

最后,说一下delegate配置的意义。
True,表示tomcat将遵循JVM的delegate机制,即一个WebAppClassLoader在加载类文件时,会先递交给SharedClassLoader加载,SharedClassLoader无法加载成功,会继续向自己的父类委托,一直到BootstarpClassLoader,如果都没有加载成功,则最后由WebAppClassLoader自己进行加载。
False,表示将不遵循这个delegate机制,即WebAppClassLoader在加载类文件时,会优先自己尝试加载,如果加载失败,才会沿着继承链,依次委托父类加载。

默认情况为false

在此说一下配置为False需要注意的问题:一旦配置为False,如果你在WebApp中自己定义了一个java.lang.String,则这个String类会有可能覆盖掉jdk中的String类,这也许不是你想要的结果。另外对于多个WebApp公用jar包,你可能会放到${CATALINA_HOME}/shared目录中共享,但是一不小心在应用的/WEB-INF/lib中也包含了一个同名的但版本不一致的jar的话,这就有可能会导致很多奇怪的问题。

解决方案(最有效的解决方案)

在D:\Java\apache-tomcat-7.0.57\conf/context.xml中

在tomacat的context.xml里加上<Loader delegate="true" />


  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值