2013-05-17 90 views
1

我正在編寫一個應用程序,需要在運行時重新加載以前加載的類。原因是該類是在運行時自動生成的,而新的實現會改變應用程序的工作方式。我只生成上述類的一個對象,並從所有依賴中剝離它,但是它定義了常量值的接口。在重新加載時重新設置任何或所有成員的值都沒有問題。我確切知道它何時發生變化,我可以控制它。我唯一的問題是重新加載。如何重新加載在運行時更改的以前加載的類?

從我讀的,我應該使用ClassLoader。我試圖這樣做,但我無法使它工作。

我試過如下:

  • 獲取當前的ClassLoader(myClassObject.getClass().getClassLoader()),並用它來重新加載類 - 不工作。它可能會不斷加載舊的實現。
  • 生成我自己的(從修改後的AKA複製粘貼) - 不起作用,因爲我生成的ClassLoader不同於生成該類的類(例外:myClass不能被轉換爲myClass)。
  • 創建一個設置超類ClassLoader的構造函數似乎沒有任何效果。
  • 使用我的新ClassLoader生成myClassObject作爲成員的類解決了myClassObject的ClassLoader不匹配問題,但創建了一個新的不匹配級別。我每次都使用getClassLoader(),我發現它們不匹配。
  • 我試着添加-Djava.system.class.loader=com.test.Reoader com.test.myMainClass使它成爲我的默認重裝器,但是我從編譯器中得到一個錯誤。
  • 谷歌一直指着我回到我已經讀過的東西。
  • 編輯:我試着創建一個接口並重新加載實現它的類。這也沒有解決它。

我知道我應該重寫默認的ClassLoader,但我沒有做任何事情似乎成功了。

我的ClassLoader:

public class Reloader extends ClassLoader { 

    public Reloader(){ 
     super(Reloader.class.getClassLoader()); 
    } 

    @Override 
    public Class<?> loadClass(String s) { 
     return findClass(s); 
    } 

    @Override 
    public Class<?> findClass(String s) { 
     try { 
      byte[] bytes = loadClassData(s); 
      return defineClass(s, bytes, 0, bytes.length); 
     } catch (IOException ioe) { 
      try { 
       return super.loadClass(s); 
      } catch (ClassNotFoundException ignore) {} 
      ioe.printStackTrace(java.lang.System.out); 
      return null; 
     } 
    } 

    private byte[] loadClassData(String className) throws IOException { 
     File f = new File("out\\production\\ManoCPU\\" + className.replaceAll("\\.", "/") + ".class"); 
     int size = (int) f.length(); 
     byte buff[] = new byte[size]; 
     FileInputStream fis = new FileInputStream(f); 
     DataInputStream dis = new DataInputStream(fis); 
     dis.readFully(buff); 
     dis.close(); 
     return buff; 
    } 
} 

非常感謝任何人都可以提供幫助。

+0

該班如何自動生成? – nakosspy

+0

我有一個編譯器讀取模板文件並將其編譯爲java代碼。模板文件可以在應用程序中更改和編譯。 – YMI

+0

它是否經常發生?我的意思是班級可以重新編譯多少次? – nakosspy

回答

1

您只能加載一次類(每個類加載器的實例)。這意味着你必須拋棄已經加載類的類加載器,併爲你的類的更新版本實例化一個新類。

當處理多個類加載器時也會記住,如果您使用多個類加載器加載相同的類,那麼它們不會被識別爲相同的類。

+0

謝謝。我在任何地方看過同樣的東西,但我怎麼扔掉舊的東西?這是我無法弄清楚的。我不需要它是同一個類,它只是實現了一些功能發生變化的方法,只要調用一個方法就會更新唯一的兩個成員。 – YMI

+0

我會建議尋找一些涉及多個類加載器的開源插件框架的源代碼。 tomcat源代碼也可能是可能的。 – mschenk74

相關問題