Xml解析校驗引起的依賴問題

假期結束,開始收心回來繼續工作。晚上有一個項目要發佈,公司的同事突然打手機給我,說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:

<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作版本控制和服務器搭建,在長遠來看還是有一定的好處的,只是說根據各自的需求來做這樣的工作。


後續
問題出現的當天,我其實晚上就一直比較擔心,因爲如果問題不解決,那麼將會影響到很多項目組(框架被使用的越廣泛,自己所要承擔的責任越重大)。其實也是由於自己上次對於這個問題的不上心,導致了問題的再次出現。刨根問底是件好事,做我們這行的還是需要多問一些爲什麼,這樣就會少不少危急時刻的怎麼辦了。
很多時候爲什麼程序員自己喜歡什麼都自己做,因爲掌握在自己手中的事情總是能夠解決,但是現在項目中對於第三方的依賴越來越多,在選擇和控制上必須慎之又慎,有時候依賴也是雙刃劍。
發佈了47 篇原創文章 · 獲贊 4 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章