在单独的进程中执行Java应用程序

And*_*NER 43 java process exec

Java应用程序是否可以使用其名称(而不是其位置)以独立于平台的方式加载到单独的进程中?

我知道你可以通过...执行一个程序

Process process = Runtime.getRuntime().exec( COMMAND );
Run Code Online (Sandbox Code Playgroud)

...这种方法的主要问题是这种调用是特定于平台的.


理想情况下,我将方法包装成简单的方法......

EXECUTE.application( CLASS_TO_BE_EXECUTED );
Run Code Online (Sandbox Code Playgroud)

...并传入应用程序类的完全限定名称CLASS_TO_BE_EXECUTED.

hal*_*ave 67

这是已经提供的一些其他答案的综合.Java系统属性提供了足够的信息来提供java命令和类路径的路径,我认为这是一种独立于平台的方式.

public final class JavaProcess {

    private JavaProcess() {}        

    public static int exec(Class klass) throws IOException,
                                               InterruptedException {
        String javaHome = System.getProperty("java.home");
        String javaBin = javaHome +
                File.separator + "bin" +
                File.separator + "java";
        String classpath = System.getProperty("java.class.path");
        String className = klass.getName();

        ProcessBuilder builder = new ProcessBuilder(
                javaBin, "-cp", classpath, className);

        Process process = builder.inheritIO().start();
        process.waitFor();
        return process.exitValue();
    }

}
Run Code Online (Sandbox Code Playgroud)

你会像这样运行这个方法:

int status = JavaProcess.exec(MyClass.class);
Run Code Online (Sandbox Code Playgroud)

我认为传递实际的类而不是名称的String表示是有意义的,因为类必须在类路径中才能使其工作.

  • 你可能需要在进程构建器上使用`redirectOutput(...)`和`redirectError(...)`(在`start()`之前),如果你想启动某种服务器,否则它可能会挂起你可能无法联系它.不知道为什么...... (4认同)

ste*_*heg 42

两个提示:

System.getProperty("java.home") + "/bin/java" 为您提供java可执行文件的路径.

((URLClassLoader) Thread.currentThread().getContextClassLoader()).getURL() 帮助您重建当前应用程序的类路径.

然后你EXECUTE.application就是(伪代码):

Process.exec(javaExecutable, "-classpath", urls.join(":"), CLASS_TO_BE_EXECUTED)

  • 第三个提示:如果你想独立于平台,请不要使用urls.join(":"). (11认同)
  • File.some_constant而不是:(你可以查找some_constant :-) (3认同)
  • http://java.sun.com/j2se/1.4.2/docs/api/java/io/File.html#pathSeparatorCha (2认同)

and*_*rej 6

扩展@ stepancheg的答案,实际代码看起来如此(以测试的形式).

import org.junit.Test;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.stream.Collectors;

public class SpinningUpAJvmTest {
    @Test
    public void shouldRunAJvm() throws Exception {
        String classpath = Arrays.stream(((URLClassLoader) Thread.currentThread().getContextClassLoader()).getURLs())
                .map(URL::getFile)
                .collect(Collectors.joining(File.pathSeparator));
        Process process = new ProcessBuilder(
                System.getProperty("java.home") + "/bin/java",
                "-classpath",
                classpath,
                MyMainClass.class.getName()
                // main class arguments go here
        )
                .inheritIO()
                .start();
        int exitCode = process.waitFor();
        System.out.println("process stopped with exitCode " + exitCode);
    }
}
Run Code Online (Sandbox Code Playgroud)


Sta*_*Man 5

这对您来说可能有点矫枉过正,但Akuma 项目可以满足您的需求,甚至更多。我通过Kohsuke(Sun 的摇滚入门程序员之一)非常有用的博客中的这篇文章找到了它。