Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 替换动态加载的jar_Java_Jar - Fatal编程技术网

Java 替换动态加载的jar

Java 替换动态加载的jar,java,jar,Java,Jar,我已经从其他jar文件动态加载了jar,然后在某个时候,我想删除这个jar并用新版本替换它,在linux上它工作正常,而在windows上,当我尝试将文件移动到备份目录时,我得到另一个进程异常正在使用的文件 public void loadJarAndClass() { URL[] jarUrl = new URL[1]; jarUrl[0] = jarFile.toURI().toURL(); classLoader = new URLClassLoader (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));
我的问题是delete抛出异常“进程无法访问该文件,因为它正被另一个进程使用”

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

尝试使用方法

这是Oracle链接的摘录

在JavaSE7中,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)); 
    }
}

请尝试在“卸载”类加载器之前关闭它

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()!
(参见示例)

可能会有所帮助。您似乎在某个地方有一个指向动态加载的JAR文件的某些资源的强引用。在windows上,这可能会阻止正确关闭JAR,因此不允许重新/移动JAR文件itself@shd,我用一个示例测试更新了答案,在这个测试中,我能够成功地在Windows上删除jar文件。仅供参考。如果没有调用close()方法,我无法删除jar文件,但是在URLClassLoader上调用close()方法时,我可以删除它。另外,我在JDK8上也试过