一尘不染

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

java

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

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

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

…这种方法的主要问题是,此类调用是特定于平台的。

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

EXECUTE.application( CLASS_TO_BE_EXECUTED );

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


阅读 388

收藏
2020-03-12

共2个答案

一尘不染

两个提示:

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

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

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

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

2020-03-13
一尘不染

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

public final class JavaProcess {

    private JavaProcess() {}        

    public static int exec(Class klass, List<String> args) 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();

        List<String> command = new LinkedList<String>();
        command.add(javaBin);
        command.add("-cp");
        command.add(classpath);
        command.add(className);
        if (args != null) {
            command.addAll(args);
        }

        ProcessBuilder builder = new ProcessBuilder(command);

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

}

你将像这样运行此方法:

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

我认为传入实际的类而不是名称的String表示形式是有意义的,因为无论如何该类都必须位于类路径中。

2020-03-13