Java-Process可以删除加载的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仍然存在。
作为一个workarround,我创建了一个临时文件,并将Jar复制到该tempfile。 但是现在Tempfile不会被删除。
我读过,如果ClassLoad是GC,可以删除加载的jar。
有没有人有想法,如何删除此文件?
这取决于操作系统。 Windows不会让你删除正在使用的文件,但Linux会删除。
一种解决方案是启动第二个进程,等待你的JVM死掉然后删除文件,因为即使你清除所有对使用它的类加载器的引用,也不能保证它们会释放文件。 没有办法强制对象的垃圾收集(甚至完成)。
另一个解决方案是编写加载Jar的类加载器。 这样,当你想摆脱它时,你可以确定jar子是关闭的。 如果打开它的唯一对象是您的类加载器,那么您可以确定它是免费的并且应该是可删除的。
此问题已在Java 7中修复; 在ClassLoader
类中使用close()
方法。 对于旧版本,有几种选择:
-
编写自定义类加载器,例如像这样
-
使用reflection并关闭所有
JarFile
实例; 它们位于sun.misc.URLClassPath