今天遇到一个比较诡异的问题, 我们的应用在JBoss下可以正常部署, 到Jetty环境下则部署失败,并提示如下信息:
2011-06-14 18:14:34.812:WARN::Failed startup of context runjettyrun.HSFJettyWebAppContext@1f21c50{/,src/main/webapp} org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 37 in XML document from ServletContext resource [/WEB-INF/webx.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'services:webx-configuration'. at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:404) <中间略去若干行> 2011-06-14 18:14:34.814:WARN::Nested in org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 37 in XML document from ServletContext resource [/WEB-INF/webx.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'services:webx-configuration'.: org.xml.sax.SAXParseException: cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'services:webx-configuration'. at org.apache.xerces.parsers.DOMParser.parse(Unknown Source) at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source) at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:75) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:396) <中间略去若干行> 2011-06-14 18:14:34.829:INFO::Started [email protected]:80
上面花了大篇幅粘贴错误日志,只是想留个纪念。
出现这个问题,首先怀疑到的是环境是不是有问题。检查了一会儿,没有头绪。换个思路看看,瞅瞅这两天有哪些文件变更。(小注:之前一直运行正常)。通过观察SVN日志,发现最近有新引入了一个包(且记为A.jar)。或许这就是问题所在。
我们的工程是用Maven进行依赖管理的,所以接着我在POM中将新引入的A.jar移除,再次部署应用,果然正常启动。但是A.jar可能别的同事在用,不能草率的移除了事。并且我断定不是A.jar本身,而是其带来的间接依赖导致上述的问题。
紧接着我需要做的是揪出A带来的间接依赖中的哪一个导致XML解析失败。
首先我打印出了增加A.jar和移除A.jar后的依赖树,命令如下:
mvn dependency:tree > with_a
mvn dependency:tree > without_a
然后用BeyondCompare比对with_a和without_a两个文件的差异内容,因为A的依赖关系很复杂,所以单纯肉眼,分辨不出哪个依赖出了问题,只好放弃了这条路子。
后面又仔细阅读了一遍错误日志,然后缩小搜索范围,因为从字面上看,不外乎与XML和Spring相关。于是排查了Spring版本是否正常,并确定和Spring无关。那只能是XML相关的依赖导致问题了。
再次查看工程依赖树,和XML解析相关的包大致有:xml-apis、xml-resolver、xmlParserAPIs、xercesImpl等。这回还真有所收获,发现因为A的引入,导致了xercesImpl的版本降级。在引入A之前的xercesImpl版本为2.9.1、引入A后则变为2.4.0. 赶紧排除A中的xercesImpl,部署应用,正常启动,搞定收工。
这也解释了为什么Jboss可以正常部署,因为Jboss自带了xercesImpl-2.7.1.
By Mr.Chris