在一個運營系統(tǒng)中,如果出現(xiàn)業(yè)務(wù)方法變更,而我們使用的應(yīng)用服務(wù)器不支持熱部署的話,那么重啟可能是更新的唯一選擇。目前多數(shù)應(yīng)用服務(wù)器不支持熱部署,包括生產(chǎn)模式下的weblogic。之所以說是生產(chǎn)模式,weblogic在開發(fā)模式下是支持這種動態(tài)更新的,即我們只要替換部署目錄下的類文件,重新訪問時可以看到新業(yè)務(wù)方法生效,而且即使在生產(chǎn)模式下,weblogic也能"支持"動態(tài)更新,但做法上比較麻煩,需要使用version信息控制應(yīng)用,這個功能weblogic9就開始提供,但好像很少有客戶這么用過。如果應(yīng)用服務(wù)器不支持動態(tài)更新,我們有什么方法可以滿足這種需求嗎? 這就是我們這篇文章要講述的,通過TI(更準(zhǔn)確地說是JDI),我們可以實現(xiàn)。
為了能夠正確的做到動態(tài)更新,我們首先需要attach到target JVM上,具體方法參考
http://www.tkk7.com/fjin/archive/2009/09/10/294443.html
連接上target JVM后,我們可以就可以利用vm提供的redefineClasses()將新的類文件注入到JVM中,替代原有的class信息。
1 public void reloadClasses(List toReloads){
2 Map toReloadMap = new HashMap();
3 for (Iterator iterator = toReloads.iterator(); iterator.hasNext();)
4 {
5 String toReload = (String) iterator.next();
6 InputStream is = VMDebugger.class.getClassLoader().getResourceAsStream(toReload.replace('.', '/') + ".class");
7 if (is == null) {
8 throw new RuntimeException("Class " + toReload + " is not found in current classpath");
9 }
10 List classes = vm.classesByName(toReload);
11 if (classes == null || classes.isEmpty()) {
12 throw new RuntimeException("Class: " + toReload + " is not found in target JVM");
13 } else {
14 ReferenceType ref = (ReferenceType) classes.get(0);
15 try{
16 toReloadMap.put(ref, toByteArray(is));
17 }catch(Exception e){
18 e.printStackTrace();
19 }
20 }
21 }
22 vm.redefineClasses(toReloadMap);
23 }
上面的方法有如下幾個注意的地方:
1:確保要更新的類在當(dāng)前classpath下(也就是啟動VMDebugger的classpath)。
2:確保要更新的類在target JVM已被加載。
3:不同的VM實現(xiàn)上不一樣,有的可能不允許動態(tài)更新,可以使用
canRedefineClasses()
判斷一下。
posted on 2009-09-11 00:04
走走停停又三年 閱讀(2779)
評論(5) 編輯 收藏 所屬分類:
Java Technology