在另一个Java应用程序中执行JAR文件

时间:2011-02-11 16:57:33

标签: java jar cmd external

我正在尝试运行一个外部Jar文件,而不是实际将它插入我的jar本身。因为jar文件需要与主jar文件位于同一文件夹中。

所以,在主jar文件中我想执行其他可执行jar文件,而且我需要能够知道jar文件何时结束以及当你关闭主jar文件时,启动的jar文件jar文件需要关闭,

我目前使用此代码执行此操作:

public void LaunchLatestBuild()
  {
    try {
      String path = new File(".").getCanonicalPath() + 
        "\\externaljar.jar";
      List commands = new ArrayList();
      commands.add(getJreExecutable().toString());
      commands.add("-Xmx" + this.btd_serverram + "M");
      commands.add("-Xms" + this.btd_serverram + "M");
      commands.add("-jar");
      commands.add(path);

      int returnint = launch(commands); //It just waits and stops the tread here. And my Runtime.getRuntime().addShutdownHook doesn't get triggerd.

      if (returnint != 201) //201 is a custom exit code I 'use' to know when the app needs a restart or not.
      {
        System.out.println("No restart needed! Closing...");
        System.exit(1);
      }
      else
      {
        CloseCraftBukkit();

        Launcher.main(new String[] { "" });
      }
    }
    catch (Exception e)
    {
      System.out.println(e.toString());
      e.printStackTrace();
    }
  }
  public int launch(List<String> cmdarray) throws IOException, InterruptedException
  {
    byte[] buffer = new byte[1024];

    ProcessBuilder processBuilder = new ProcessBuilder(cmdarray);
    processBuilder.redirectErrorStream(true);
    this.CBProcess = processBuilder.start();
    InputStream in = this.CBProcess.getInputStream();
    while (true) {
      int r = in.read(buffer);
      if (r <= 0) {
        break;
      }
      System.out.write(buffer, 0, r);
    }

    return this.CBProcess.exitValue();
  }

此代码的限制:

  • 不关闭我的externaljar.jar java 主要退出的过程 应用
  • 如果主控制台无法将输入重定向到外部jar。

这是我需要的最重要的事情。

我希望有人能告诉我应该怎么做。

目前的源代码位于: http://code.google.com/p/bukkit-to-date/

1 个答案:

答案 0 :(得分:2)

为什么你不能只设置你的类路径以便它包含第二个jar,然后你可以简单地将它用作库?您甚至可以手动调用MainClass.main()方法,如果您确实希望执行该方法,则可以在同一个虚拟机内并且不会生成单独的进程。

编辑:如果您在启动应用程序时不知道jar文件的名称,但是您只能在运行时解决该问题,为了调用它,请创建一个URLClassLoader jar文件的路径,然后:

URLClassLoader urlClassLoader = new URLClassLoader(
        new File("/path/to/your/jar/file.jar").toURI().toURL() );

ClassLoader cl = Thread.currentThread().getContextClassLoader();
// switch to your custom CL
Thread.currentThread().setContextClassLoader(urlClassLoader);
// do your stuff with the other jar
// ....................
// now switch back to the original CL
Thread.currentThread().setContextClassLoader(cl);

或者只是在另一个jar中获取对类的引用并使用反射:

Class<?> c = urlClassLoader.loadClass("org.ogher.packag.ClassFromExternalJar");