我从其他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 :(得分: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()?)