Java进程可以删除加载的JAR吗?

Java进程可以删除加载的JAR吗?,java,jar,classloader,delete-file,Java,Jar,Classloader,Delete File,你好,我有以下问题: 在卸载过程中,我加载一个JAR(jdbc驱动程序) URL pDriverJar=jarToDelete.toURI().toURI(); URL[]lurlist=新URL[]{pDriverJar}; URLClassLoader lLoader=新的URLClassLoader(lurlist,Thread.currentThread().getContextClassLoader()); Thread.currentThread().setContextClassL

你好,我有以下问题:

在卸载过程中,我加载一个JAR(jdbc驱动程序)

URL pDriverJar=jarToDelete.toURI().toURI();
URL[]lurlist=新URL[]{pDriverJar};
URLClassLoader lLoader=新的URLClassLoader(lurlist,Thread.currentThread().getContextClassLoader());
Thread.currentThread().setContextClassLoader(lLoader);
Class aClass=Class.forName(“jdbc.Driver”);//是Oracle:Oracle.jdbc.OracleDriver,但不应该很重要
if(jarToDelete.delete()){
系统输出打印项次(“删除”);
}否则{
jarToDelete.deleteOnExit();
}
JVM终止后,jar仍然存在

作为一名工作人员,我创建了一个临时文件,并将Jar复制到该临时文件中。但是现在临时文件将不会被删除

我已经读到,如果类加载是GC,那么加载的JAR可以被删除


有人知道如何删除此文件吗?

这取决于操作系统。Windows不允许删除正在使用的文件,但Linux将允许删除

一种解决方案是启动第二个进程,等待JVM死亡,然后删除该文件,因为即使清除了对使用它的类加载器的所有引用,也不能保证它们会释放该文件。无法强制对象的垃圾收集(甚至终结)


另一个解决方案是编写装入Jar的类加载器。这样,当你想摆脱它时,你可以确定罐子是关闭的。如果打开它的唯一对象是你的类加载器,那么你可以确定它是免费的,应该是可删除的。

这个问题在Java 7中得到了解决;使用
ClassLoader
类中的
close()
方法。对于旧版本,有几个选项:

  • 编写一个自定义类加载器,例如

  • 使用反射并关闭所有
    JarFile
    实例;它们位于
    sun.misc.URLClassPath


因为我想消除java11所需的类路径上的jar文件,但导致了Java1.8或更低版本中的问题;我使用的一个解决方案是,不必启动另一个进程来终止jar文件,只需通过

FileOutputStream out = new FileOutputStream(f);
out.write(new byte[0]);
out.flush(); out.close();
下一次应用程序启动时,即使0字节文件仍在清单中,该代码也会设法将其删除:

if (f.exists()){
    if (f.delete() == false) f.deleteOnExit();
}
if (f.exists()){
    if (f.delete() == false) f.deleteOnExit();
}