为了账号安全,请及时绑定邮箱和手机立即绑定

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

/ 猿问

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

慕粉4167745 2019-09-21 15:43:34

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


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


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

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



理想情况下,我会将方法包装成像...这样简单的东西。


EXECUTE.application( CLASS_TO_BE_EXECUTED );

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


查看完整描述

3 回答

?
烙印99

两个提示:


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


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


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


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


查看完整回答
反对 回复 2019-09-21
?
慕妹3242003

这是已提供的其他一些答案的综合。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表示形式是有意义的,因为无论如何该类都必须位于类路径中。


查看完整回答
反对 回复 2019-09-21
?
慕婉清6462132

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

    }

}


查看完整回答
反对 回复 2019-09-21

添加回答

回复

举报

0/150
提交
取消
意见反馈 邀请有奖 帮助中心 APP下载
官方微信