Может ли загруженный JAR быть удален Java-процессом? - PullRequest
3 голосов
/ 22 октября 2010

Здравствуйте, у меня есть следующая проблема:

В процессе удаления я загружаю 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 в этот временный файл. Но теперь Tempfile не будет удален.

Я читал, что если ClassLoad это GC, загруженные банки могут быть удалены.

У кого-нибудь есть идея, как удалить этот файл?

Ответы [ 3 ]

5 голосов
/ 22 октября 2010

Это зависит от операционной системы.Windows не позволит вам удалить файлы, которые используются, но Linux сделает это.

Одним из решений будет запуск второго процесса, который ожидает смерти вашей JVM, а затем удалит файл, даже если вы очиститеВсе ссылки на загрузчики классов, использующие его, не гарантируют, что они выпустят файл.Не существует способа принудительного сбора мусора (или даже завершения) объекта.

Другим решением было бы написать загрузчик классов, который загружает Jar-файл.Таким образом, когда вы хотите избавиться от него, вы можете быть уверены, что банка закрыта.Если единственным объектом, который открыл его, был ваш загрузчик классов, то вы можете быть уверены, что он бесплатный и должен быть удаляемым.

2 голосов
/ 22 октября 2010

Эта проблема была исправлена ​​в Java 7;используйте метод close() в классе ClassLoader.Для более старых версий есть несколько вариантов:

  • Написать пользовательский загрузчик классов, например, как этот

  • Использовать отражение изакрыть все JarFile экземпляры;они проживают в sun.misc.URLClassPath

0 голосов
/ 21 мая 2019

Поскольку я хотел уничтожить jar-файл на пути к классам, который мне нужен для java11, но привел к проблемам в 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();
}
...