利用動態類加載技術調式ECLIPSE插件
eclipse平臺提供runtime方式調試插件和RCP項目,但隨著插件項目越寫約復雜,啟動時間也越來越長,特別是集成了諸如 Hibernate和Spring之類的容器級框架的時候。僅僅為了調試代碼中一些瑣碎的片段而頻繁的重啟項目實在是一件異常煩人的工作。
即使重啟了項目也許還沒完。為了使項目處于某個特定的狀態下以方便測試,每次都要重新操作一遍前面業務流程,這同樣是十分令人厭倦的。
eclispe使用了OGSI作為微內核,引入了一些動態特性。但是OSGI的動態特性是在保持平臺運行的情況下動態更新Bundle,也就是說需要重啟插件才能完成動態加載的過程。有沒有一些更加細粒度的動態載入方案呢?
在Tomcat下開發過web項目的人都知道,使用調試模式來部署項目即”熱部署”可以實現動態載入class文件,讓程序員得以動態調試項目。今天向大家提供的這個jar包使得這種效果可以在eclipse runtime上實現。
這是我在自己的插件平臺項目——SCOOP框架中使用的幾個包。
它可以非常好的解決動態類載入的問題,包括內部類的動態載入都可以很好解決。
其他的幾個包還進行了以下嘗試
1. 使用元數據標注的辦法解決SWT UI 線程的種種問題
2. 還提供了eclipse流程框架的簡單實現,以規范插件開發。特別是提出了一個面向業務而不是面向技術的工作流概念,使得編碼粒度變大,并得以提高效率。另外這個簡單的流程框架還將前面的兩種機制很好的結合起來,并且可以和eclipse平臺的一些復雜機制解耦,為復雜流程的開發測試提供了方便。為將來實現自定義腳本語言(比如某個類似于BPEL的工作流語言)開發eclise插件項目甚至使用圖形化的開發奠定了一定的基礎。
我給出了一個完整的示例——JAXB插件。很多框架同jaxb一樣提供了code generation工具,可以在這個例子的基礎上經過簡單修改為這些框架提供插件,比如CXF插件、AXIS2插件等等。
動態類載入編碼原則
使用動態類載入機制來進行調試在編碼上有一定限制。
首先是要進行動態載入的實例不要在非動態域進行引用。只有這樣,當一個流程結束時此實例才會在jvm中得以釋放。當然,非要在其他地方進行引用從而長久的在運行時保持這個實例也是有解決方案的(可以使用代理類技術來實現,具體解決辦法不在本文之內)。
其次是進行接口同實現類的分離或父類同子類的分離,以隔離不同的class load scope。接口由父類載入器載入,不同的實現(比如修改后的實現)由不同的子類載入器載入。使得最終同一個類型由同一個類載入器載入,這樣才能符合jvm的類載入規范。在父類載入域的父類型的方法的參數類型及返回值類型也不能在動態域中。
最后,那些注冊在擴展點上的類如ActionDelegate和WorkbenchPart等是不能夠動態載入的,他們必須由eclipse提供的類載入器載入(平臺會自動載入并管理其生命周期)。如果需要讓這些類也動態載入,就需要在平臺提供的動態注冊機制基礎上使用代理或像EJB2.0一樣使用侵入式編譯來實現代理機制,這個話題同樣不在本文之內。
下面就舉例說明使用方法
因為時間有限我無法詳盡的完成此文,請感興趣的朋友自己閱讀示例源碼。
1. 幾種動態類載入的辦法
(1) 使用手動編碼進行類載入
因為會使二次開發人員產生迷惑,故未舉例
(2) 在調試時使用spring文件配置動態類載入域
Spring配置文件同樣也是動態的,而且會使調試開發工作變得更加清晰,推薦使用
(3) 使用Flow框架來進行動態類載入
2. 使用元數據標注解決UI線程訪問的問題
使用三個元數據及動態代理類解決SWT及Eclipse的線程問題。
3. 同eclipse內部機制解耦以方便開發和測試
開發插件項目很多時候需要實現Eclipse內部的一些回調接口來實現功能,這對程序員的水平是一種考驗,也使得插件開發工作更加復雜化。比如在實現progressMonitor的時候,就需要實現它的回調接口,將業務邏輯放置在其指定的回調接口——runable接口來實現,這是非常不方便的。我們需要是一種可以提供功能的工具類,像調用一個普通javaBean一樣來調用它,而不是將我們的業務代碼變形撕碎去融入到Eclipse的種種機制中去。
這樣做的另外一個壞處就是很難進行單元測試,比如脫離eclipse平臺,使用一些mock類來進行簡單有效的單元測試。
我在這方面也進行了一些嘗試——”反客為主”,將必須遵守eclipse的回調要求變為必須遵守業務開發簡單快捷的要求。同樣是在progressMonitor上面,使用工廠類來創建delegate,然后可以在回調機制的外部向調用javaBean一樣來使用平臺給我們提供的這個功能。
這種嘗試是有一定難度的,要使用到不同的設計模式,處理各種線程問題。更重要的一點是eclipse平臺本身有這樣的潛力,它也在等待著我們這樣做。
4. 使用Flow規范插件項目開發
我的scoop項目最終擱淺,到最后我發現實現它已經超出了我當時的能力。我原本是想開發一個統一的插件開發及部署平臺。這樣很多中小軟件企業,特別是像我原來工作的那家公司就可以擁有自己的eclipse插件集,以適應自己特殊的要求。我還想提供一套面向插件開發業務的接口,而不再面向技術也屏蔽各種技術細節,使得可以非常方便的擴展、修改甚至移植插件。我只是心里有想念就去實現而已,當最終認識到它有多么困難的時候不得不放棄了。最后雖然失敗了,但并不覺得氣餒。因為知道了要努力的方向,同時也積累了豐富的經驗。最后就將這個jar包命名為SCOOP已示紀念。
演示文檔及框架JAR包如下
/Files/jonenine/Eclipse_Dynamic_Classload.rar