首先看看我前幾天的一篇blog
spring 與 osgi的第一個障礙
eclipse3.1, spring2.0.1,將spring.jar放到一個插件中,在另一個插件中去使用。 最簡單的例子,在context.getBean的時候就報了一個異常:
Caused?by:?org.xml.sax.SAXParseException:?cvc
-
elt.
1
:?Cannot?find?the?declaration?of?element?
'
beans
'
.
先是搜了一遍,沒有發現很有幫助的內容。然后跟了一下,發現還是因為xsd的映射找不到。而造成這個問題的原因, 是在 spring.jar當中的META-INF/spring.schemas 這個找不到。
而這個找不到的最根本原因,是因為在eclipse當中,META-INF目錄是不能夠被其他插件找到的。也就是說,META-INF 目錄是擁有spring.jar的那個插件所獨占的,而其他插件就算依賴于這個插件,也是無法找到META-INF目錄下的文件, 從而拋出這個異常。
解決問題的辦法有幾個,最簡單的莫過于拷貝spring.schemas文件到需要的插件中,另一個辦法是把spring的context 裝載就放在spring.jar所在的插件中,或者改eclipse的代碼。 :(
這個問題解決之后,緊接著第二個問題就是
Unable?to?locate?NamespaceHandler?
for
?namespace?http:
//
www.springframework.org/schema/aop
造成這個的原因和第一個類似,將spring.handlers拷貝到META-INF目錄下就ok了。
上面是我以前的一個經驗,今天仔細研究了一下,發現自己掉進了 經驗主義的圈套。
這個經驗是這樣積累起來的:在剛開始嘗試使用eclipse的時候,用的是3.0和3.1Mx系列,當時 不知道osgi是個什么東西 :$ 創建的幾個插件,都沒有創建osgi bundle manifest。也就是說, 只有plugin.xml,而沒有META-INF/MANIFEST.MF文件的。但是在運行期,eclipse會自動的 從plugin.xml當中讀取信息,生成臨時的MANIFEST.MF文件,放在 runtime的 configuration/org.eclipse.osgi/manifests 目錄下。而生成這個MANIFEST.MF文件,是 通過 PluginConverterImpl 這個類來實現的,在它的 isValidPackageName 方法中,所有的 META-INF或者以META-INF開頭的目錄,都不會被自動的export出去,從而在臨時生成的MANIFEST.MF 文件中,永遠不會有META-INF目錄的export。
當時剛開始接觸eclipse和osgi,根本不知道自己當時最佳的解決方案就是創建一個 bundle manifest, 然后在其中將META-INF目錄export出來。而是通過盲目的修改代碼來繞過這個彎。后來這個彎繞過去了, 留給我的經驗就是:META-INF這個目錄,是插件獨享的,別的插件不允許訪問的。
于是,在前幾天,當spring.jar當中的幾個META-INF目錄下的文件訪問不了時,我也認為這個經驗有用, 差點就去改eclipse的代碼了。幸好嘗試了一下,把spring.jar所在的插件中,將META-INF目錄共享出來, 居然就好了。仔細查了一下,發現屏蔽META-INF的代碼只出現在PluginConverterImpl這個類當中。 回頭想了想,終于明白自己這次是掉在經驗主義的坑里面了。
經驗主義害死人啊。唉。
主站: http://blogsite.3322.org/