当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《在单独的进程中执行Java应用程序》经验,为你挑选了3个好方法。

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

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

Process process = Runtime.getRuntime().exec( COMMAND );

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


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

EXECUTE.application( CLASS_TO_BE_EXECUTED );

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



1> hallidave..:

这是已经提供的一些其他答案的综合.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();
    }

}

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

int status = JavaProcess.exec(MyClass.class);

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


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

2> stepancheg..:

两个提示:

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(":").
File.some_constant而不是:(你可以查找some_constant :-)
http://java.sun.com/j2se/1.4.2/docs/api/java/io/File.html#pathSeparatorCha

3> andrej..:

扩展@ 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);
    }
}

推荐阅读
TXCWB_523
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有