【问题标题】:Runtime.getRuntime().exec() results in java.io.IOException: Cannot run program ... no such file or directoryRuntime.getRuntime().exec() 导致 java.io.IOException: Cannot run program ... no such file or directory
【发布时间】:2016-09-03 17:06:54
【问题描述】:

您好,我在 Java 和 Spring 框架中使用 openssl 生成证书和密钥,

以下是我的代码

String[] cmds = new String[4];
cmds[0] = String.format("openssl genrsa -out %s.key 2048", path+name);
cmds[1] = String.format("openssl req -new -key %s.key -out %s.csr", path+name, path+name);
cmds[2] = String.format("openssl x509 -req -in %s.csr -CA %s.pem -CAkey %s.key -CAcreateserial -out %s.crt -days 365 -sha512 -extensions mysection -extfile conf.cnf", path+name, path+rootName, path+rootName, path+name);
cmds[3] = String.format("openssl pkcs12 -export -out %s.pfx -inkey %s.key -in %s.crt", path+name, path+name, path+name);

Runtime r = Runtime.getRuntime();
Process p = null;
try {

    p = r.exec(cmds);

} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

作为回报,我得到了关注

java.io.IOException:无法运行程序“openssl genrsa -out /home/lalani/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/api-server/WEB-INF/applications/certificate/Riksof.key 2048": error=2, 没有这样的文件或目录

请指导我哪里做错了?

还请建议我如何在异步任务中运行这个Runtime.getRuntime().exec()

【问题讨论】:

  • 错误很简单,没有找到key。为什么不尝试一个简单的钥匙位置。你是在 linux 上,那么简单的 /home/username/Riksof.key。在异步任务中运行它是什么意思。你运行它的方式已经是异步的,当linux命令执行时,你不知道它什么时候结束,除非你调用waitFor()方法。
  • 这里的pathname 是什么?您是否经过正确的位置?
  • 是的,上面的错误/home/lalani/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/api-server/WEB-INF/applications/certificate/是路径,Riksof是名称
  • 这也不是问题,因为从技术上讲,此文件不存在此命令openssl genrsa -out Riksof.key 2048 旨在在当前位置生成名称为Riksof.key 的密钥文件
  • 我也可以使用 cd 访问此目录/home/lalani/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpw‌​ebapps/api-server/WEB-INF/applications/certificate/,因此该目录确实存在

标签: java spring process openssl runtime


【解决方案1】:

题为“无法执行Runtime.getRuntime()”的问题,但这里的问题不是无法执行Runtime.getRuntime(),而是在执行p = r.exec(cmds);时,由于

Cannot run program "openssl genrsa -out /home/lalani/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/api-server/WEB-INF/applications/certificate/Riksof.key 2048": error=2, No such file or directory

【讨论】:

  • 我把标题改成更合适的了
  • 是的,你答案的前半部分是正确的,但第二部分是错误的,标题应该改变,但which means the file cannot be found in that location 部分不是这里的情况,命令r.exec 看起来有点像对于文件而不是命令,这是这里的问题
【解决方案2】:

Java 找不到程序openssl。您必须提供openssl 可执行文件的完整路径,或确保openssl 的路径位于Java 程序可用的路径中。

【讨论】:

  • 我在 linux ubuntu 上运行,如何给出 openssl 的路径?
  • 执行 which openssl 并在您的 Java 代码中使用完整路径。或者确保which openssl显示的路径在你运行Java程序的路径中。
  • 实际上,@yshavit 的回答也适用......我错过了您试图一次传递所有命令。你至少有两个问题。
  • 我认为没有任何证据表明 Java 找不到 openssl。一旦OP修复了代码以实际调用它,它可能就能够做到;例如,在 Unix 类型的系统(Linux、Mac)上,只要 openssl 在 PATH 上,它就可以工作。
  • 是的,简单的命令r.exec(String.format("openssl genrsa -out %s.key 2048", path+name));实际上是生成密钥,所以不是这样的
【解决方案3】:

Runtime.exec 不需要运行命令数组。它需要一个描述单个命令的数组。

这意味着取决于系统,但通常数组中的第一个元素将是要运行的命令,随后的元素描述其参数。例如,如果您想将foo.txt 复制到bar.txt,您将:

String[] cmd = { "cp", "foo.txt", "bar.txt" };
p = r.exec(cmd);

所以你的代码试图做的是调用一个名为openssl genrsa -out /home/lalani/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/api-server/WEB-INF/applications/certificate/Riksof.key 2048的程序。它试图向该程序传递三个参数,对应于数组的最后三个元素。但是那个程序不存在——如果它存在,那将是一个非常奇怪的程序!

要执行数组中的第一个命令,您需要一个类似的数组:

String[] cmd1 = { "openssl", "genrsa", "-out", path + name + ".key", "2048" };
p = r.exec(cmd1);

当然,其他三个命令也需要这样做。

文本在您的终端中起作用的原因是外壳实际上取行,将其解析为它的组件(基本上通过分割空格,考虑引用的文本),将第一个标记(openssl)视为程序,其余的标记作为它的参数。但该功能是外壳的一部分,而不是底层操作系统; Runtime.exec 与操作系统对话,因此您需要自己进行拆分。

【讨论】:

  • 不,你需要将它放在一个数组中,每个标记(程序名称和每个参数)作为一个单独的元素。我更新了我的答案以显示第一个命令的外观。
  • 实际上,最初导致我将所有命令分解为数组的问题是生成密钥的第一个命令有效,但使用此密钥并生成证书的第二个命令永远不会有效,因为这个函数是异步的,不要等待完成它执行第二个命令,在这种情况下,它找不到生成证书的密钥文件
  • 在这种情况下,听起来您只需要等待第一个命令完成,然后再运行第二个命令。取回的 Process 对象有一个方法to do just that
  • waitFor(); 的问题是它在第一个命令后挂起,没有输出没有错误,它在第一个命令中创建键并在边缘挂断
  • 我对最初的问题提出了新问题,请您也看看,stackoverflow.com/q/37113161/2552551
【解决方案4】:

只需完整路径您将运行的 cmd: 例如:“node -e index.js”==>“/path/to/node -e /path/to/index.js” 它为我修复, 就我而言,节点在 PATH 中,但我不知道为什么它不起作用

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-22
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多