如何通过 Java 的 Runtime.getRuntime().exec 方法调用此命令?

How do I call this command via Java's Runtime.getRuntime().exec method?

以下命令 运行 在我的 Linux 终端中正确执行:

java -Djava.library.path=/home/john/native_so_libraries/linux-64 -cp '/home/john/NetBeansProjects/SendReceive/dist/SendReceive.jar:/home/j‌​ohn/Desktop/Dropbox/Libjitsi_linux_64/*' Main "send"

此命令为本机 .so 库指定一个文件夹(通过 Djava.library.path=/...),一个名为 "SendReceive.jar" 的应用程序 JAR 文件,一个用于 JAR 库的文件夹(通过 -cp class 路径选项),还有一个主要的 class,其中包含 运行 的主要方法,一个名为 "Main" 的 class。它有一个用引号括起来的命令行参数,即 "send" 参数。此命令有效,并且 运行 是来自终端的 Java 进程,但我不知道如何让它与来自另一个进程的 Runtime.getRuntime().exec 一起工作。

请注意,我正在尽最大努力遵循本教程中提供的说明:http://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html?page=2 - 这意味着我正在使用线程来使用进程中的标准输入和标准错误流。尽管如此,当我将该终端命令变成如下字符串时,该过程不会启动:

Process process = Runtime.getRuntime().exec("java -Djava.library.path=/home/john/native_so_libraries/linux-64 -cp '/home/john/NetBeansProjects/SendReceive/dist/SendReceive.jar:/home/j‌​ohn/Desktop/Dropbox/Libjitsi_linux_64/*' Main \"send\"");

如何通过 Runtime.getRuntime().exec 执行此命令 运行?

简短的回答是不要。请改用 ProcessBuilder。它允许您将每个命令行参数分隔到它自己的 String 中,这将作为单独的 "argument" 出现在进程中。这使得它对于处理其中包含空格的路径非常有用,例如...

ProcessBuilder pb = new ProcessBuilder(
                "java", 
                "-Djava.library.path=/home/johnmichaelreed/Desktop/Dropbox/Libjitsi_linux_64/lib/native/linux-64", 
                "-cp", 
                "/home/johnmichaelreed/NetBeansProjects/SendReceive/dist/SendReceive.jar:/home/j‌​ohnmichaelreed/Desktop/Dropbox/Libjitsi_linux_64", 
                "Main", 
                "\"send\"");

pb.redirectErrorStream(true);
try {
    Process p = pb.start();
    try (InputStream is = p.getInputStream()) {
        int in = -1;
        while ((in = is.read()) != -1) {
            System.out.print((char)in);
        }
    }
    int exitCode = p.exitValue();

    System.out.println("Process exited with " + exitCode);
} catch (IOException ex) {
    ex.printStackTrace();
}

它还允许您将 stderr 重定向到 stdout,这样更容易阅读。

您还应该阅读标准输出并检查退出值以获得更好的 digansotics

您需要做的第一件事是执行 glob (represented by * in your classpath). You can also use a ProcessBuilder - 用于创建操作系统进程。 并且 List<String>或命令,以及 StringBuilder 来执行 glob。像,

public static void main(String[] args) {
    String home = System.getProperty("user.home");
    System.out.println(home);
    List<String> command = new ArrayList<>();
    command.add("java");
    command.add("-Djava.library.path=" + home
            + "/native_so_libraries/linux-64");
    StringBuilder cp = new StringBuilder();
    cp.append(home + "/NetBeansProjects/SendReceive/dist/SendReceive.jar");
    try {
        File dir = new File(home + "/Desktop/Dropbox/"
                + "Libjitsi_linux_64/");
        for (File f : dir.listFiles()) {
            if (f.isFile()) {
                cp.append(":").append(f.getCanonicalPath());
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    command.add("-cp");
    command.add(cp); // <-- shouldn't need literal
                    // single quotes.
    command.add("Main");
    command.add("send"); // <-- shouldn't need literal double quotes.
    ProcessBuilder pb = new ProcessBuilder(command);
    pb.inheritIO();
    try {
        Process p = pb.start();
        System.exit(p.waitFor());
    } catch (Exception e) {
        e.printStackTrace();
    }
}