2010-06-20 29 views
4

我最近發了一個帖子Update Java code during runtime過了幾個小時,不同的例子代碼,閱讀教程左右擺弄我遇到了以下問題重裝代碼:Java的問題,使用的ClassLoader

通過使用一個ClassLoader我已經能夠在運行時使用代碼http://www.exampledepot.com/egs/java.lang/reloadclass.html將類別MyVar1中的局部變量從類MyVar1更改爲類MyVar2,但我一直無法用MyVar2的另一個版本替換該類MyVar2

MyVar1MyVar2都實現了接口VarInterface。主類使用VarInterface類型保存變量的一個實例。

我讀過幾個其他聲稱是正確的實現,但我無法得到這個工作。任何人都可以看到我在這裏做錯了嗎?

主類的循環:

while(true){ 
     i++; 
     Thread.sleep(1000); 
     ui.ping(); 
     if(i > 3) 
      replaceVar(); 
    } 

replaceVar:

ClassLoader parentClassLoader = MyClassLoader.class.getClassLoader(); 
    MyClassLoader classLoader = new MyClassLoader(parentClassLoader); 
    Class newClass = classLoader.loadClass("MyVar2"); 
    ui = (VarInterface)newClass.newInstance(); 

MyClassLoader.loadClass:

public Class<?> loadClass(String what){ 
    // Get the directory (URL) of the reloadable class 
    URL[] urls = null; 
    try { 
     // Convert the file object to a URL 
     File dir = new File(System.getProperty("user.dir") 
       +File.separator+"dir"+File.separator); 
     URL url = dir.toURL(); 
     urls = new URL[]{url}; 
    } catch (MalformedURLException e) { 
    } 

    // Create a new class loader with the directory 
    ClassLoader cl = new URLClassLoader(urls); 

    // Load in the class 
    Class cls = null; 
    try { 
     cls = cl.loadClass("MyVar2"); 
    } catch (ClassNotFoundException e) { 
     e.printStackTrace(); 
    } 

    return cls; 
} 

對於第3次迭代MyVar1.ping()被調用時,該MyVar2.ping()被稱爲廣告後無限,即使我替換MyVar2.classMyVar2.java文件。

+0

只是要清楚的問題 - 讓我們說'MyVar2.ping()'打印'你好',當'i == 10'你改變類打印'再見',你的問題是,你仍然看到'你好'不管改變什麼,對吧? – RonK 2010-06-20 21:09:00

+0

種類。我沒有用另一個版本替換MyVar2的內部觸發器(例如i == 10),我只是直接替換文件或在eclipse中編輯並保存。 – Glader 2010-06-20 21:28:41

回答

1

我猜你正在使用兩個類裝載機。一個是系統類加載器,其中包含大量代碼。您的自定義類加載器使用系統類加載器作爲其父類。您試圖讓自定義類加載器替換系統類加載器中的類。事實上,自定義類加載器將委派給父類,優先於加載它自己的類。

你需要做的是確保系統類加載器不加載該類的實現。創建一個類加載器,加載該類的實現並委託給系統類加載器。要更改實現,請創建類加載器的另一個實例。

(使用java.net.URLClassLoader.newInstance可能是更容易的創建自己的類加載器實現)。

+0

我創建了一個新的類加載器實例,就像你在replaceVar函數中看到的那樣。 「大部分代碼」由循環以及MyVar類中的'ping()'函數組成,因爲這只是當前的沙箱實驗。 – Glader 2010-06-21 08:52:35

1

我設法解決這個問題。我忘了將這些文件放在類路徑之外,這使得ClassLoader只有在實現相同接口的不同類時纔會讀取新實例,而不是在用不同版本替換類時。

所以基本上:通過從項目中刪除文件並在外部編輯它們來解決問題。

+0

如果這是決議,你應該自己接受它,所以你的問題已經得到了回答(儘管你自己)。 – 2010-06-25 00:38:27