Tutorial Deleting a loaded plugin Jar file

Discussion in 'Resources' started by RcExtract, Aug 6, 2018.

  1. Offline

    RcExtract

    I don't know if anyone has done this.

    Basically, when a plugin is loaded, its corresponding jar file will be used by the server, hence the file lock is acquired and you cannot delete the file in anyway in Java. Here is how to release the corresponding resources.

    ONLY DO THIS WHEN THE PLUGIN IS LOADED.

    Obtain the responsible ClassLoader
    First, obtain the class loader that is used to load the main class of the plugin, and cast it to URLClassLoader. If the action is done within the main class, do the following:
    Code:java
    1. URLClassLoader loader = (URLClassLoader) this.getClassLoader();

    Otherwise, obtain the instance of the main class and do the following:
    Code:java
    1. URLClassLoader loader = plugin.getClass().getClassLoader();

    The actual type of the class loader is PluginClassLoader. However, it is only accessible within org.bukkit.plugin.java, so we will cast the class loader to its superclass, URLClassLoader.

    Then, you have two options:

    Close with reflection
    Using this method allows us to release only and the exact resources we want to. However, it may reduce performance insignificantly.
    Code:java
    1. ((JarFile) loader.getClass().getField("jar").get(loader)).close();


    Close with the overrided close() method
    Using this method also closes the class loader, which is not what we want to do.
    Code:java
    1. loader.close()


    How this works?
    Take a look at the source code of the type of the class loader responsible for loading a plugin, PluginClassLoader:
    Code:java
    1. private final JarFile jar;
    2. @Override
    3. public void close() throws IOException {
    4. try {
    5. super.close();
    6. } finally {
    7. jar.close();
    8. }
    9. }

    What we actually want to do is to close the JarFile of the plugin jar file, instead of the class loader. Unfortunately, the jar field is private, so the only ways to close the JarFile is to invoke the overrided close() method, or to access the JarFile using reflection, then directly close it.

    Consequences?
    I currently cannot find any places after the plugin being loaded that will make use of the JarFile after we close it. If you find any, please tell me.
     
    Zombie_Striker likes this.
  2. Online

    timtower Ninja on the waves Moderator

    @RcExtract And why would somebody want to do this?
     
  3. Offline

    RcExtract

    I just want to share what i know no similar things were shared before. Or in case someone needs this, idk.
     
  4. Online

    timtower Ninja on the waves Moderator

    deleteOnExit might be easier then.
     
  5. Offline

    RcExtract

    I tried. If you dont close the JarFile deleteOnExit does not work.
     
  6. Online

    timtower Ninja on the waves Moderator

    deleteOnExit does not run right away. That is the thing.
    It runs when the server stops.
     
  7. Offline

    RcExtract

    Ofc ik. But did not work on exit.
     

Share This Page