替换动态加载的jar

时间:2015-06-22 11:21:40

标签: java jar

我从其他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));

我的问题是删除引发异常"进程无法访问该文件,因为它正被另一个进程使用"

如何绕过此异常并关闭所有已打开的处理程序?

2 个答案:

答案 0 :(得分: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)); 
    }
}

答案 1 :(得分: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()?