简体   繁体   English

ProcessBuilder - 没有这样的文件或目录(但Runtime.exec()有效)

[英]ProcessBuilder - No such file or directory (but Runtime.exec() works)

Why am I experiencing different behavior in these 2 cases? 为什么我在这两种情况下会遇到不同的行为? Have I missed something out? 我错过了什么吗?

Command: 命令:

new ProcessBuilder().directory(
                    Paths.get(System.getProperty("user.dir")).toFile())
                    .command("/usr/bin/java -Djava.library.path=/Users/myusername/myproject/lib/DynamoDBLocal_lib/ -jar /Users/myusername/myproject/lib/DynamoDBLocal.jar  -sharedDb").start();

Stack Trace: 堆栈跟踪:

Exception in thread "main" java.lang.RuntimeException: java.io.IOException: Cannot run program "/usr/bin/java -Djava.library.path=/Users/myusername/myproject/lib/DynamoDBLocal_lib/ -jar /Users/myusername/myproject/lib/DynamoDBLocal.jar  -sharedDb" (in directory "/Users/myusername/myproject"): error=2, No such file or directory
    at com.comcast.tvx.app.xreserver.Main.exec(Main.java:47)
    at com.comcast.tvx.app.xreserver.Main.main(Main.java:16)
Caused by: java.io.IOException: Cannot run program "/usr/bin/java -Djava.library.path=/Users/myusername/myproject/lib/DynamoDBLocal_lib/ -jar /Users/myusername/myproject/lib/DynamoDBLocal.jar  -sharedDb" (in directory "/Users/myusername/myproject"): error=2, No such file or directory
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
    at com.comcast.tvx.app.xreserver.Main.exec(Main.java:44)
    ... 1 more
Caused by: java.io.IOException: error=2, No such file or directory
    at java.lang.UNIXProcess.forkAndExec(Native Method)
    at java.lang.UNIXProcess.<init>(UNIXProcess.java:248)
    at java.lang.ProcessImpl.start(ProcessImpl.java:134)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
    ... 2 more

Environment in failing case: 失败案例中的环境:

{PATH=/usr/bin:/bin:/usr/sbin:/sbin
JAVA_STARTED_ON_FIRST_THREAD_1074=1
SHELL=/bin/zsh
SECURITYSESSIONID=186a4
USER=myusername
JAVA_MAIN_CLASS_25188=com.comcast.tvx.app.xreserver.Main
APP_ICON_1074=../Resources/Eclipse.icns
COMMAND_MODE=unix2003
TMPDIR=/var/folders/t_/dlj2wfdj0bx2xl6mnnqmxyhj99pf4b/T/
SSH_AUTH_SOCK=/tmp/launch-Bhd1It/Listeners
DISPLAY=/tmp/launch-PuSx66/org.macosforge.xquartz:0
__CF_USER_TEXT_ENCODING=0x529B388B:0:0
Apple_PubSub_Socket_Render=/tmp/launch-hB7zpQ/Render
__CHECKFIX1436934=1
LOGNAME=myusername
HOME=/Users/myusername}

More information 更多信息

When I do it with Runtime.exec() the environment looks identical but I don't get the error: 当我使用Runtime.exec()执行此操作时,环境看起来完全相同但我没有收到错误:

Command: 命令:

Runtime.getRuntime().exec("/usr/bin/java -Djava.library.path=/Users/myusername/myproject/lib/DynamoDBLocal_lib/ -jar /Users/myusername/myproject/lib/DynamoDBLocal.jar  -sharedDb")

Environment in succeeding case: 成功案例中的环境:

{PATH=/usr/bin:/bin:/usr/sbin:/sbin
JAVA_STARTED_ON_FIRST_THREAD_1074=1
SHELL=/bin/zsh
JAVA_MAIN_CLASS_25360=com.comcast.tvx.app.xreserver.Main
SECURITYSESSIONID=186a4
USER=myusername
APP_ICON_1074=../Resources/Eclipse.icns
COMMAND_MODE=unix2003
TMPDIR=/var/folders/t_/dlj2wfdj0bx2xl6mnnqmxyhj99pf4b/T/
SSH_AUTH_SOCK=/tmp/launch-Bhd1It/Listeners
DISPLAY=/tmp/launch-PuSx66/org.macosforge.xquartz:0
__CF_USER_TEXT_ENCODING=0x529B388B:0:0
Apple_PubSub_Socket_Render=/tmp/launch-hB7zpQ/Render
__CHECKFIX1436934=1
LOGNAME=myusername
HOME=/Users/myusername}

Try to change this line: 尝试更改此行:

.command("/usr/bin/java -Djava.library.path=/Users/myusername/myproject/lib/DynamoDBLocal_lib/ -jar /Users/myusername/myproject/lib/DynamoDBLocal.jar  -sharedDb").start();

to (scroll all the way to the right to see the difference): to(向右滚动以查看差异):

.command("/usr/bin/java -Djava.library.path=/Users/myusername/myproject/lib/DynamoDBLocal_lib/ -jar /Users/myusername/myproject/lib/DynamoDBLocal.jar  -sharedDb".split("\\s+")).start();

Explanation: the input to command() should be an array (or list) of strings each of which is another argument (or "token"). 说明: command()的输入应该是字符串的数组(或列表),每个字符串都是另一个参数(或“标记”)。 It should not contain whitespaces! 它不应该包含空格!

From the docs : 来自文档

a command, a list of strings which signifies the external program file to be invoked and its arguments, if any. 一个命令,一个字符串列表,表示要调用的外部程序文件及其参数(如果有)。 Which string lists represent a valid operating system command is system-dependent. 哪个字符串列表表示有效的操作系统命令取决于系统。 For example, it is common for each conceptual argument to be an element in this list, but there are operating systems where programs are expected to tokenize command line strings themselves - on such a system a Java implementation might require commands to contain exactly two elements. 例如,每个概念参数通常都是此列表中的元素,但是有些操作系统需要程序对命令行字符串本身进行标记 - 在这样的系统上,Java实现可能需要命令才能包含两个元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM