2010-10-22 185 views
3

您好,我有以下問題:Java進程可以刪除加載的JAR嗎?

在卸載過程中,我加載了一個JAR(jdbc-driver)。

URL pDriverJar = jarToDelete.toURI().toURL(); 
    URL[] lURLList = new URL[]{pDriverJar}; 
    URLClassLoader lLoader = new URLClassLoader(lURLList, Thread.currentThread().getContextClassLoader()); 
    Thread.currentThread().setContextClassLoader(lLoader); 
    Class<?> aClass = Class.forName("jdbc.Driver"); // was Oracle: oracle.jdbc.OracleDriver but should not be important 

    if(jarToDelete.delete()){ 
     System.out.println("deleted"); 
    }else { 
     jarToDelete.deleteOnExit(); 
    } 

JVM終止後,jar仍然存在。

作爲一個工作周,我創建了一個臨時文件,並將Jar複製到該臨時文件。但是現在Tempfile不會被刪除。

我讀過,如果ClassLoad是GC,加載的罐子可以被刪除。

有沒有人有想法,如何刪除此文件?

回答

5

這取決於操作系統。 Windows不會讓你刪除正在使用的文件,但Linux會。

一個解決方案是啓動第二個進程,等待您的JVM死掉然後刪除文件,因爲即使您清除對使用它的類加載器的所有引用,也不保證它們將釋放該文件。沒有辦法強制對象的垃圾收集(甚至是最終化)。

另一種解決方案是編寫加載Jar的類加載器。那樣,當你想擺脫它時,你可以確定罐子是封閉的。如果打開它的唯一對象是你的類加載器,那麼你可以肯定它是免費的,應該是可刪除的。

2

此問題已在Java 7中修復;使用ClassLoader類中的close()方法。對於舊版本,有幾種選擇:

  • 編寫自定義類加載器,例如, like this

  • 使用反射並關閉所有JarFile實例;他們居住在sun.misc.URLClassPath

相關問題