3

您好我有以下问题:

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

    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 仍然存在。

作为一种解决方法,我创建了一个临时文件,并将 Jar 复制到该临时文件中。但是现在临时文件不会被删除。

我读过,如果 ClassLoad 是 GC,则可以删除加载的 jar。

有没有人有想法,如何删除这个文件?

4

3 回答 3

5

这取决于操作系统。Windows 不会让您删除正在使用的文件,但 Linux 会。

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

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

于 2010-10-22T14:48:23.713 回答
2

此问题已在 Java 7 中修复;使用类close()中的方法ClassLoader。对于旧版本,有几个选项:

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

  • 使用反射并关闭所有JarFile实例;他们居住在sun.misc.URLClassPath

于 2010-10-22T15:21:50.777 回答
0

因为我想杀死 java11 所需的类路径上的 jar 文件,但导致 java 1.8 或更低版本出现问题;我使用的一种解决方案,无需启动另一个进程来终止 jar 文件,只需将文件设为 0 字节

FileOutputStream out = new FileOutputStream(f);
out.write(new byte[0]);
out.flush(); out.close();

下次应用程序启动此代码时,它会设法将其删除,即使 0 字节文件仍在清单中:

if (f.exists()){
    if (f.delete() == false) f.deleteOnExit();
}
于 2019-05-21T08:29:57.677 回答