假期结束,开始收心回来继续工作。晚上有一个项目要发布,公司的同事突然打手机给我,说ASF的文件解析又出了上次的问题,希望尽快解决。
问题描述:
上一次问题:
多台机器运行同一个分支的应用,但是有些机器正常,有一台机器始终在启动的时候报文件解析错误,从提示看来,主要是因为解析配置文件的时候校验dtd失效,这台机器无法连接外网。最后降低了我们内部的核心解析包,问题解决(或者让这台机器连接到外网)。(当时由于自己手头工作比较多,也没有在意,既然解决了就随之过去了)
此次问题:
问题的提示和上次的类似,不过这次的机器时连接外网的。
问题查找:
解析出错的文件是ASF(SCA的服务框架)的组件配置文件(composite文件),格式为xml的格式,解析方式是通过StAX标准来实现的。
按照上一次的解决方法,我将内部的tuscany0.998降级到tuscany0.997,解析正常。看了一下我对于这两个版本升级作的修改,主要是支持了SCA框架中的Spring配置文件能够使用import的标签,内签多个标准的spring文件。
跟踪代码内部发现,果然是在解析某几个spring的配置文件时出现了问题,比较了一下ASF的Spring(正常解析)和标准的Spring配置文件,差别主要是在关于Xml的校验申明的区别。ASF的Spring配置文件是由ASF Spring插件来自己解析的(采用Schema申明(固定的Target namingspace),因此早先所有的ASF的Spring我都要求大家采用Schema的校验申明),而对于原来不是ASF的spring都是采用dtd的校验方式申明(互相拷贝导致都是这样)。下面就是两种申明:
Schema:
Dtd:
早先由于在0.997版本中没有支持import,因此也就不会去解析那些不是ASF的Spring文件,而现在因为需求支持了import所以需要解析那些原来不属于ASF的Spring的配置文件。因此降低版本不是解决问题的办法。
进一步跟进问题,发现是在解析Dtd的申明时候出现问题,抛出异常说连接超时。通过IE访问了一下dtd的地址,的却也是有问题,无法连接。看来是Spring的dtd的服务器出现了问题,导致了我们解析文件时候校验无法正常,最终无法正常启动。
问题解决:
这里先说一下最后解决的几个方案,后面会有一些详细的解释和说明。
1. 升级ASF的Spring插件包,去除对于Xml的格式校验。
2. 将Dtd的校验申明修改成为Schema的校验申明。
3. 建立公司的Xml校验服务器,控制管理dtd或者schema,将所有的xml Schema或者dtd申明指向该服务器。
问题延伸开来的思考:
就问题的解决方案来看这个问题的一些值得注意和思考的地方。
方案1:
当前对于XML解析来说,各种框架都已经统一的实现了StAX的标准,同时在jdk6得rt.jar中都已经将StAX API作为基础框架API纳入其内。而通常情况下,如果不配置是否校验Xml,那么都将默认会主动校验Xml,此时就会出现上面我所遇到的问题,如果当你依赖的Xml DTD 或者 Schema服务器出现问题,就会导致你本地应用可能受到影响。在Dtd的申明说明中,<!DOCTYPE rootElement [color=red]PUBLIC "PublicIdentifier" "URIreference"[/color]>红色部分说可以在网络出现问题或者网络速度很慢的时候被部分xml解析器替代URIreference使用,不过我这边没有成功过。我通过自己屏蔽网络连接来模拟环境的情况,都是无法通过的。(Schema比较奇怪,就算无法连接网络还是可以正常的,这个后续需要继续研究看看,或者有朋友对这个问题有了解请告知一下)
方案2:
其实早在2002年就已经有将dtd替换成为schema的趋势了,两者的区别和优劣网上的文章介绍了很多了,这儿不再罗列,其实最更本一点就是schema就是用xml来校验xml,而dtd却采用了另一套规则来校验xml,其本身也是xml,扩展性,可读性,学习曲线等等都次与schema。除了遗留系统,我个人看不出还有什么必要去使用老的dtd来校验xml的格式。Spring的dtd服务的出现问题,也说明了其实对于dtd这种方式的校验,spring也已经不会保证几个9的稳定性。
Xml常常会被作为数据承载中介,使双方能够在跨平台跨语言的情况下松耦合的交互信息,也是现在的SOA的实施基础。那么双方势必需要有协议和数据格式规范来约束,schema作为dtd的新一代替代者已经广为使用。另一方面,xsd也早已独立于wsdl作为数据描述和可重用的数据描述说明被采用到各种互联网应用。
看看国外的Facebook,亚马逊,ebay等公司的REST风格的API,就可以清楚地了解到xsd十分适合作为轻量级的数据交互协议。在后续ASF中融入REST配置的实现中,也需要采用XSD这种Schema描述来实现数据交互解析。
因此替换掉Dtd的配置是迟早要做的一件事情,所以迟作不如早作,更避免拷贝引起的问题放大效果(不过这个问题由于要考虑QA和业务组的项目经理的顾虑,因此我只能做到的是建议)。
方案3:
看看Maven这些年这么火,其实在我们自己公司内部的antx同样都是在做一件事情,就是对于第三方的依赖包的版本控制。对于开源项目依赖的管理其实很重要,作的好项目能够很好的利用已有的成果,管理的不好就会被一些不太稳定的开源项目搞得头破血流。
记得在上次三亚的聚会上谈到了对于Tuscany的依赖,其实对于这个项目来说,如果要作为成熟的产品来说,那么势必要获取一个版本然后就作为稳定的依赖,而不是一味的升级更新,由于我们产品的特殊性以及早期的Tuscany的不成熟,因此我们仅仅只是使用了Tuscany的最核心解析文件框架部分,其他的插件都采取自己设计或者在原有设计上优化和更新的做法。当然这不是说对于所有的第三方依赖都是采取这样的策略,其实如果不是基础框架设计,仅仅只是应用级别的使用,只需要拿来主义就完全可以了。
回过头来看,大家现在对于类库的管理已经都很重视了,但是对于配置性的或者数据格式类的文件还没有引起足够的重视,不过看到很多朋友已经在本地作了这样的工作,不过就我来看,如果能够对dtd,schema作版本控制和服务器搭建,在长远来看还是有一定的好处的,只是说根据各自的需求来做这样的工作。
后续
问题出现的当天,我其实晚上就一直比较担心,因为如果问题不解决,那么将会影响到很多项目组(框架被使用的越广泛,自己所要承担的责任越重大)。其实也是由于自己上次对于这个问题的不上心,导致了问题的再次出现。刨根问底是件好事,做我们这行的还是需要多问一些为什么,这样就会少不少危急时刻的怎么办了。
很多时候为什么程序员自己喜欢什么都自己做,因为掌握在自己手中的事情总是能够解决,但是现在项目中对于第三方的依赖越来越多,在选择和控制上必须慎之又慎,有时候依赖也是双刃剑。
问题描述:
上一次问题:
多台机器运行同一个分支的应用,但是有些机器正常,有一台机器始终在启动的时候报文件解析错误,从提示看来,主要是因为解析配置文件的时候校验dtd失效,这台机器无法连接外网。最后降低了我们内部的核心解析包,问题解决(或者让这台机器连接到外网)。(当时由于自己手头工作比较多,也没有在意,既然解决了就随之过去了)
此次问题:
问题的提示和上次的类似,不过这次的机器时连接外网的。
问题查找:
解析出错的文件是ASF(SCA的服务框架)的组件配置文件(composite文件),格式为xml的格式,解析方式是通过StAX标准来实现的。
按照上一次的解决方法,我将内部的tuscany0.998降级到tuscany0.997,解析正常。看了一下我对于这两个版本升级作的修改,主要是支持了SCA框架中的Spring配置文件能够使用import的标签,内签多个标准的spring文件。
跟踪代码内部发现,果然是在解析某几个spring的配置文件时出现了问题,比较了一下ASF的Spring(正常解析)和标准的Spring配置文件,差别主要是在关于Xml的校验申明的区别。ASF的Spring配置文件是由ASF Spring插件来自己解析的(采用Schema申明(固定的Target namingspace),因此早先所有的ASF的Spring我都要求大家采用Schema的校验申明),而对于原来不是ASF的spring都是采用dtd的校验方式申明(互相拷贝导致都是这样)。下面就是两种申明:
Schema:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:sca="http://www.springframework.org/schema/sca"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/sca http://www.springframework.org/schema/sca/spring-sca.xsd">
Dtd:
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
早先由于在0.997版本中没有支持import,因此也就不会去解析那些不是ASF的Spring文件,而现在因为需求支持了import所以需要解析那些原来不属于ASF的Spring的配置文件。因此降低版本不是解决问题的办法。
进一步跟进问题,发现是在解析Dtd的申明时候出现问题,抛出异常说连接超时。通过IE访问了一下dtd的地址,的却也是有问题,无法连接。看来是Spring的dtd的服务器出现了问题,导致了我们解析文件时候校验无法正常,最终无法正常启动。
问题解决:
这里先说一下最后解决的几个方案,后面会有一些详细的解释和说明。
1. 升级ASF的Spring插件包,去除对于Xml的格式校验。
XMLInputFactory xmlFactory = XMLInputFactory.newInstance();
//add by wenchu.cenwc cancel support dtd check
xmlFactory.setProperty(XMLInputFactory.SUPPORT_DTD, "false");
2. 将Dtd的校验申明修改成为Schema的校验申明。
3. 建立公司的Xml校验服务器,控制管理dtd或者schema,将所有的xml Schema或者dtd申明指向该服务器。
问题延伸开来的思考:
就问题的解决方案来看这个问题的一些值得注意和思考的地方。
方案1:
当前对于XML解析来说,各种框架都已经统一的实现了StAX的标准,同时在jdk6得rt.jar中都已经将StAX API作为基础框架API纳入其内。而通常情况下,如果不配置是否校验Xml,那么都将默认会主动校验Xml,此时就会出现上面我所遇到的问题,如果当你依赖的Xml DTD 或者 Schema服务器出现问题,就会导致你本地应用可能受到影响。在Dtd的申明说明中,<!DOCTYPE rootElement [color=red]PUBLIC "PublicIdentifier" "URIreference"[/color]>红色部分说可以在网络出现问题或者网络速度很慢的时候被部分xml解析器替代URIreference使用,不过我这边没有成功过。我通过自己屏蔽网络连接来模拟环境的情况,都是无法通过的。(Schema比较奇怪,就算无法连接网络还是可以正常的,这个后续需要继续研究看看,或者有朋友对这个问题有了解请告知一下)
方案2:
其实早在2002年就已经有将dtd替换成为schema的趋势了,两者的区别和优劣网上的文章介绍了很多了,这儿不再罗列,其实最更本一点就是schema就是用xml来校验xml,而dtd却采用了另一套规则来校验xml,其本身也是xml,扩展性,可读性,学习曲线等等都次与schema。除了遗留系统,我个人看不出还有什么必要去使用老的dtd来校验xml的格式。Spring的dtd服务的出现问题,也说明了其实对于dtd这种方式的校验,spring也已经不会保证几个9的稳定性。
Xml常常会被作为数据承载中介,使双方能够在跨平台跨语言的情况下松耦合的交互信息,也是现在的SOA的实施基础。那么双方势必需要有协议和数据格式规范来约束,schema作为dtd的新一代替代者已经广为使用。另一方面,xsd也早已独立于wsdl作为数据描述和可重用的数据描述说明被采用到各种互联网应用。
看看国外的Facebook,亚马逊,ebay等公司的REST风格的API,就可以清楚地了解到xsd十分适合作为轻量级的数据交互协议。在后续ASF中融入REST配置的实现中,也需要采用XSD这种Schema描述来实现数据交互解析。
因此替换掉Dtd的配置是迟早要做的一件事情,所以迟作不如早作,更避免拷贝引起的问题放大效果(不过这个问题由于要考虑QA和业务组的项目经理的顾虑,因此我只能做到的是建议)。
方案3:
看看Maven这些年这么火,其实在我们自己公司内部的antx同样都是在做一件事情,就是对于第三方的依赖包的版本控制。对于开源项目依赖的管理其实很重要,作的好项目能够很好的利用已有的成果,管理的不好就会被一些不太稳定的开源项目搞得头破血流。
记得在上次三亚的聚会上谈到了对于Tuscany的依赖,其实对于这个项目来说,如果要作为成熟的产品来说,那么势必要获取一个版本然后就作为稳定的依赖,而不是一味的升级更新,由于我们产品的特殊性以及早期的Tuscany的不成熟,因此我们仅仅只是使用了Tuscany的最核心解析文件框架部分,其他的插件都采取自己设计或者在原有设计上优化和更新的做法。当然这不是说对于所有的第三方依赖都是采取这样的策略,其实如果不是基础框架设计,仅仅只是应用级别的使用,只需要拿来主义就完全可以了。
回过头来看,大家现在对于类库的管理已经都很重视了,但是对于配置性的或者数据格式类的文件还没有引起足够的重视,不过看到很多朋友已经在本地作了这样的工作,不过就我来看,如果能够对dtd,schema作版本控制和服务器搭建,在长远来看还是有一定的好处的,只是说根据各自的需求来做这样的工作。
后续
问题出现的当天,我其实晚上就一直比较担心,因为如果问题不解决,那么将会影响到很多项目组(框架被使用的越广泛,自己所要承担的责任越重大)。其实也是由于自己上次对于这个问题的不上心,导致了问题的再次出现。刨根问底是件好事,做我们这行的还是需要多问一些为什么,这样就会少不少危急时刻的怎么办了。
很多时候为什么程序员自己喜欢什么都自己做,因为掌握在自己手中的事情总是能够解决,但是现在项目中对于第三方的依赖越来越多,在选择和控制上必须慎之又慎,有时候依赖也是双刃剑。