加载spring的xsd文件失败,导致发布失败
1.事故现象
某个项目在发布生产的失败,回滚以前tag同样发布失败,错误信息,如下
rg.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document 'http://www.springframework.org/schema/beans/spring-beans-3.2.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>. at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195) ~[?:1.6.0_45] ...... [ERROR][20-03-04 15:34:45,197]-traceId:[]ContextLoader:308-Context initialization failed org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Failed to import bean definitions from relative location [dubbo-common.xml] Offending resource: class path resource [application.xml]; nested exception is org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 5 in XML document from class path resource [dubbo-common.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'beans'. at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:68) ~[spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE] ... 详细错误见发布平台启动日志
2.事故原因
首先需要了解xsd文件加载的过程,spring在加载xsd文件时总是先试图在本地查找xsd文件(spring的jar包中已经包含了所有版本的xsd文件),如果没有找到,才会转向去URL指定的路径下载。在很多spring的jar包里,在META-INF目录下都有一个spring.schemas,这个文件就是spring关于xsd文件在本地存放路径的映射,spring就是通过这个文件在本地(也就是spring的jar里)查找xsd文件的。那么,查找不到的原因排除URL输入有误之外,可能就是声明的xsd文件版本在本地不存在。一般来说,新版本的spring jar包会将过去所有版本(应该是自2.0以后)的xsd打包,并在spring.schemas文件中加入了对应项,出现问题的情况往往是声明使用了一个高版本的xsd文件,如3.0,但依赖缺失低版本的spring的jar包,此时就会导致spring去站点下载目标xsd文件,如遇断网或是目标站点不可用,上述问题就发生了。
本图中,通过点击连接,会跳转到本地的xsd文件。
经排查secooCrm中使用的是“http://www.springframework.org/schema/beans/spring-beans-3.2.xsd“,而j项目中使用的版本为spring-xx-3.1.1,程序加载时,无法在本地的jar中找到spring-beans-3.2.xsd,所以只能从spring官网进行下载。
3.解决方案
1.保持本地jar与xsd的版本一致。(不推荐)
2.删除xsd版本号的引用。(推荐)
如使用http://www.springframework.org/schema/beans/spring-beans-3.2.xsd,变为http://www.springframework.org/schema/beans/spring-beans.xsd。