代码之家  ›  专栏  ›  技术社区  ›  Christian Kuetbach

Java进程是否可以删除已加载的JAR?

  •  3
  • Christian Kuetbach  · 技术社区  · 14 年前

    你好,我有以下问题:

    在卸载过程中,我加载一个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仍然存在。

    我读过,如果类加载是GC,那么加载的jar可以被删除。

    2 回复  |  直到 10 年前
        1
  •  5
  •   Jonathan    14 年前

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

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

        2
  •  2
  •   ehird    13 年前

    这个问题在Java7中已经修复;使用 close() 中的方法 ClassLoader 上课。对于旧版本,有几个选项:

    • 编写自定义类加载器,例如。 like this

    • 使用反射并全部关闭 JarFile 实例;它们驻留在 sun.misc.URLClassPath

        3
  •  0
  •   runholen    6 年前

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

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

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