这两天发现到一个很奇怪的问题,就是应用有时候在启动的时候,会报

o.s.b.f.x.XmlBeanDefinitionReader.warning[2015-07-30 14:19:05]         : Ignored XML validation warningorg.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document 'http://www.springframework.org/schema/rabbit/spring-rabbit-1.4.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:203)
	at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.warning(ErrorHandlerWrapper.java:99)
	at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:433)
	at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:347)
	at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaErr(XSDHandler.java:4166)
	at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaWarnin

这类错误,但有时候却不会报。当时自己在内网启动时及部署到生产环境的时候,没有报错,所以当时也就没有注意到这个问题。昨晚更新到外网时和今天,自己启动应用的时候,偶尔会报这个错,才意识到是真的有问题。

原因

这是因为 XSD 文件在访问的时候,由于网络原因导致访问不了。比如上面的http://www.springframework.org/schema/rabbit/spring-rabbit-1.4.xsd,时好时坏。

在与同事讨论的时候,才发现最终的原因。是由于他将 http://www.springframework.org/schema/rabbit/spring-rabbit-1.1.xsd 升级为了 http://www.springframework.org/schema/rabbit/spring-rabbit-1.4.xsd,而且相对应的pom.xmlspring-rabbit的依赖没有同步升级,导致应用每次启动的时候,都会使用网络的方式去访问这个地址的文件来加载解析。 如果有网络问题的话, 上面的错误就会发生了。而且还有一点不好的地方,就是XSD的文件与jar包的版本没有一致的问题。这样子有可能会有潜在的Bug,只是还没有遇到而已。

解决办法

一般情况下,第三方的Jar包里,已经自带了XSD文件,并且已经放在了Jar文件里的,所以每次启动时,就可以避免每次都访问网络来加载解析XSD文件了。 这次出现的问题,是由于同事升级了XSD文件的版本号,而Jar包的版本并没有同步过来,所以才会导致在Jar包找不到,而不得不去访问网络了。

所以切记, 必须要将Jar包的版本与XSD文件的版本号要一致。

当时同时说,可以下载XSD文件到本地,然后修改下XSD文件的访问URL为本地。但是极不推荐这种方式。一是不够优雅,让人困惑。二是修改起来比较麻烦。除非没有其他选择,不然都不要使用这种方式。