2015-06-22 62 views
0

我已經從其他jar文件中動態加載了jar,然後在某些時候,我想刪除這個jar,並用新版本代替它,在linux上它工作正常,而在Windows上當我嘗試移動該文件備份目錄我得到的文件被另一個進程異常使用。替換動態加載的罐子

public void loadJarAndClass() { 
    URL[] jarUrl = new URL[1]; 
    jarUrl[0] = jarFile.toURI().toURL(); 
    classLoader = new URLClassLoader (jarUrl, this.getClass().getClassLoader()); 
    classToLoad = Class.forName ("Burner.MainWindow", true, classLoader); 

} 

public void unloadJarAndClass() { 
     /* all object must be collected in order to reload jar */ 
     jarFile = null; 
     dukeClassLoader = null; 
     classToLoad = null; 
     System.gc(); 

    } 

我的主:

jarPath = currentPath.getAbsolutePath() + File.separator + JAR_NAME; 
jarFile = new File(jarPath); 
loadJarAndClass(); 
unloadJarAndClass(); 
Files.delete(FileSystems.getDefault().getPath(jarPath)); 

我的問題是「因爲它正由另一個進程的進程無法訪問文件」

我怎麼能繞過它拋出異常刪除這個異常並關閉任何處理程序打開?

+0

[此鏈接](http://stackoverflow.com/questions/7487952/how-do-i-close-a-classloader)可能會有所幫助。您似乎在某處指向您的動態加載的JAR文件的某些資源的強引用。在Windows上,這可能會阻止正確關閉JAR,因此不會允許重新/死of JAR文件本身 –

回答

0

嘗試使用Classloader.close()方法,

下面是從Oracle鏈接提取物,

在Java SE 7中,URLClassLoader的close()方法有效無效裝載機,所以沒有新的類可以從它加載。它還關閉由加載器打開的所有JAR文件。這允許應用程序刪除或替換這些文件,並在必要時使用新的實現方式創建新的加載程序。

以下是可能達到目的的代碼的簡化版本,

public class Example { 

    public static void main(String[] args) throws IOException, ClassNotFoundException { 
     String jarPath = "C:\\example.jar"; 
     File jarFile = new File(jarPath); 
     URL[] jarUrl = new URL[1]; 
     jarUrl[0] = jarFile.toURI().toURL(); 
     URLClassLoader classLoader = new URLClassLoader (jarUrl, Example.class.getClassLoader()); 
     Class classToLoad = Class.forName ("DataGenerator", true, classLoader); 
     classLoader.close(); 
     Files.delete(FileSystems.getDefault().getPath(jarPath)); 
    } 
} 
+0

沒有幫助,仍然得到相同的錯誤 – shd

+0

@shd,我已經更新了答案,能夠成功刪除Windows上的jar文件。僅供參考。如果不調用close()方法,但無法刪除jar文件,但可以在URLClassLoader上調用close()方法時將其刪除。此外,我已經嘗試過JDK8 – Sathish

0

請嘗試關閉的類加載器之前,你卸載'吧。

public void unloadJarAndClass() throws IOException { 
     dukeClassLoader.close(); 

     /* all object must be collected in order to reload jar */ 
     jarFile = null; 
     dukeClassLoader = null; 
     classToLoad = null; 
     // System.gc(); don't do this unless you're really 
     // sure you have to ! 
    } 

我建議不要明確調用System.gc()! (例如參見Why is it bad practice to call System.gc()?

+0

沒有幫助,仍然得到相同的錯誤 – shd