Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 加载的JAR不会在关闭时释放所有资源_Java_Multithreading_Jar - Fatal编程技术网

Java 加载的JAR不会在关闭时释放所有资源

Java 加载的JAR不会在关闭时释放所有资源,java,multithreading,jar,Java,Multithreading,Jar,我有两个可运行的JAR文件。主JAR运行主应用程序,次JAR是应用程序的插件 我在主应用程序中使用Oracle定义的JarClassLoader来加载插件,并向main方法发送一个参数shutdown或startup 一旦插件关闭,我希望能够删除JAR文件或用其他东西替换它。然而,即使所有插件线程都关闭了,类加载器上调用了.close方法,并且对类加载器的所有引用都设置为null,该插件的JAR仍然由java使用,并由Windows锁定 如何删除此文件上的锁 primaryjar/MainApp

我有两个可运行的JAR文件。主JAR运行主应用程序,次JAR是应用程序的插件

我在主应用程序中使用Oracle定义的JarClassLoader来加载插件,并向main方法发送一个参数shutdown或startup

一旦插件关闭,我希望能够删除JAR文件或用其他东西替换它。然而,即使所有插件线程都关闭了,类加载器上调用了.close方法,并且对类加载器的所有引用都设置为null,该插件的JAR仍然由java使用,并由Windows锁定

如何删除此文件上的锁

primaryjar/MainApp.java

public class MainApp
{
  static PluginHandler ph;
  public static void main(String[] args) 
  {
    ph = new PluginHandler(System.getProperty("user.dir"));
    ph.startupPlugin();
    Thread.sleep(20000);
    ph.shutdownPlugin();
    Thread.sleep(20000);
    ph.startupPlugin();
  }
}
primaryjar/PluginHandler.java

public class PluginHandler
{
  private static JarClassLoader jcl = null;
  private String dir;

  public PluginHandler(String dir)
  { this.dir = dir;  
  }

  public void startupPlugin()
  {
    try 
    {
      jcl = JarClassLoader.generateFromString(dir + "plugin.jar");
      String name = jcl.getMainClassName();
      String[] newArgs = { "-startup" };
      jcl.invokeClass(name, newArgs);
    }
    catch (Exception e)
    {
    }
  }

  public void shutdownPlugin()
  {
    try 
    {
      jcl = JarClassLoader.generateFromString(dir + "plugin.jar");
      String name = jcl.getMainClassName();
      String[] newArgs = { "-shutdown" };
      jcl.invokeClass(name, newArgs);
      jcl.close();
      jcl = null;
    }
    catch (Exception e)
    {
    }
  }
}
pluginsjar/PluginMain.java

public class PluginMain {
    static ScheduledThreadPoolExecutor ste; 

    public static void main(String[] args) throws Exception
    {
      //startup arg
      if(args[0].equals("-startup"))
      {
          ste = new ScheduledThreadPoolExecutor(3);
          Task t1 = new Task("Hello");
          Task t2 = new Task("Salutations");
          Task t3 = new Task("Stuff");
          ste.scheduleWithFixedDelay(t1, 0, 5, TimeUnit.SECONDS);
          ste.scheduleWithFixedDelay(t2, 0, 5, TimeUnit.SECONDS);
          ste.scheduleWithFixedDelay(t3, 0, 5, TimeUnit.SECONDS);
      }

      else if (args[0].equals("-shutdown"))
      {
          ste.shutdown();
          ste.awaitTermination(10000, TimeUnit.SECONDS);
      }
    }
}

class Task implements Runnable
{
    String word; 
    int invoke = 0;
    public Task(String word)
    {
        this.word = word;
    }
    public void run() {
        invoke++;
        System.out.println("Words " + invoke + ": " + word);
    }
}
找到了另一条线索,在那里我做了一些研究和玩弄,但找不到有效的解决方案

编辑:我添加了一个方便的方法来创建一个JarClassLoader,就像我在上面链接的JarClassLoader文档的“JarRunner”类中所做的那样

public static JarClassLoader generateFromString(String path) 
            throws MalformedURLException
    {
      File pluginDir = new File(path);
      URL loadPath = pluginDir.toURI().toURL();
      return new JarClassLoader(loadPath);
    }

MainApp中的System.exit0。JAR文件被锁定的简单解释是,您的进程或某个进程打开了它,但未能关闭它。看起来唯一将jar作为文件处理的代码是这个JarClassLoader类,因此filehandle泄漏将出现在那里或调用JarClassLoader的东西中。您没有包括您的JarClassLoader源代码,google也没有打开任何包含generateFromString或close方法的JCL实现。@我不想退出主应用程序,我希望主应用程序在插件关闭时继续执行。@Kenster close没有在JarClassLoader中实现,它正在调用其父应用程序。generateFromString是我完全忘记自己制作的东西,但它只是JarClassLoader文档中的“JarRunner”逻辑。我现在就编辑它。