Executing JAR file within another java application

2019-05-25 06:10发布

I'm trying to run a External Jar file, without actually inserting it into my jar itself. Because the jar file needs to be located in the same folder as the main jar file.

So, Within the main jar file I want to execute the other executable jar file, And I need to be able to know when the jar file is ended AND when you close the main jar file, the jar file that is started within the jar file needs to be closed to,

I currently do that by using this code:

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();
  }

Limitations of this code:

  • Doesn't close my externaljar.jar java process on exit of the main application.
  • Cannot redirect input if main console, to external jar.

That are the most Important things I need.

I hope someone can tell me how I should do this.

Current source code is available at: http://code.google.com/p/bukkit-to-date/

1条回答
Fickle 薄情
2楼-- · 2019-05-25 07:08

Why can't you just set your classpath so that it includes the second jar, and then you can simply use it as a library ? You can even invoke the MainClass.main() method manually, if you really want that to be executed, but from within the same VM and without spawning a separate process.

EDIT: If you don't know the name of the jar file when your application is launched, but you'll only figure that out at runtime, in order to invoke it, create a URLClassLoader provided with the path to your jar file and then:

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);

Or simply grab a reference to a class in that other jar and make use of reflection:

Class<?> c = urlClassLoader.loadClass("org.ogher.packag.ClassFromExternalJar");
查看更多
登录 后发表回答