[英]java.io.IOException: Cannot run program “…”: java.io.IOException: error=2, No such file or directory
I need to execute an external program from Java (to convert a fodt file to pdf using libreoffice, it so happens) I know the precise command-line I need for the program:我需要从 Java 执行一个外部程序(使用 libreoffice 将fodt文件转换为pdf ,它确实发生了)我知道我需要该程序的精确命令行:
/usr/bin/libreoffice --headless --convert-to pdf:'writer_pdf_Export' --outdir /home/develop/tomcat/mf/ROOT/private/docs/0/ /home/develop/tomcat/mf/ROOT/private/docs/0/35_invoice.fodt
and that works perfectly from the command line.这在命令行中完美运行。 But it does not work in Java using a ProcessBuilder
:但它在使用ProcessBuilder
Java 中不起作用:
java.io.IOException: Cannot run program "/usr/bin/libreoffice --headless --convert-to pdf:'writer_pdf_Export' --outdir /home/develop/tomcat/mf/ROOT/private/docs/0 /home/develop/tomcat/mf/ROOT/private/docs/0/35_invoice.fodt": java.io.IOException: error=2, No such file or directory
I tried some different approaches without success.我尝试了一些不同的方法但没有成功。 Here is a sample of the last test这是上次测试的示例
List<String> command = new ArrayList<String>();
command.add("/usr/bin/libreoffice");
command.add("--headless");
command.add("--convert-to pdf:'writer_pdf_Export' --outdir " + getDestinationDirectory(order) + " " + getInvoiceFilename() + ".fodt");
ProcessBuilder builder = new ProcessBuilder(command);
Process process = null;
try {
process = builder.start();
} catch (IOException ex) {
Logger.getLogger(Documents.class.getName()).log(Level.SEVERE, null, ex);
}
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
try {
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException ex) {
Logger.getLogger(Documents.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Program terminated!");
The ProcessBuilder
constructors require each argument of the external program to be separate (in the form of an array or List
of String
s). ProcessBuilder
构造函数要求外部程序的每个参数都是独立的(以数组或String
List
的形式)。 The first exception message you got,你得到的第一条异常消息,
Cannot run program "/usr/bin/libreoffice --headless --convert-to pdf:'writer_pdf_Export' --outdir /home/develop/tomcat/mf/ROOT/private/docs/0 /home/develop/tomcat/mf/ROOT/private/docs/0/35_invoice.fodt"
is not complaining that it can find a program named /usr/bin/libreoffice
.并没有抱怨它可以找到一个名为/usr/bin/libreoffice
。 It is complaining that it can not find a program with the very long and peculiar name " /usr/bin/libreoffice --headless --convert-to pdf:'writer_pdf_Export' --outdir /home/develop/tomcat/mf/ROOT/private/docs/0 /home/develop/tomcat/mf/ROOT/private/docs/0/35_invoice.fodt
", because you concatenated the arguments into one String
.它抱怨它找不到一个名字很长很奇特的程序“ /usr/bin/libreoffice --headless --convert-to pdf:'writer_pdf_Export' --outdir /home/develop/tomcat/mf/ROOT/private/docs/0 /home/develop/tomcat/mf/ROOT/private/docs/0/35_invoice.fodt
",因为您将参数连接成一个String
。
Instead of代替
command.add("--convert-to pdf:'writer_pdf_Export' --outdir " + getDestinationDirectory(order) + " " + getInvoiceFilename() + ".fodt")
and such like, split each of the arguments into its own call to List.add
诸如此类,将每个参数拆分为自己对List.add
的调用
command.add("--convert-to");
command.add("pdf:writer_pdf_Export");
command.add("--outdir");
command.add(getDestinationDirectory(order).toString());
command.add(getInvoiceFilename() + ".fodt");
Note that there are no apostrophes around "writer_pdf_Export" since those are shell meta-characters and are not required when you're constructing an array to pass to exec
without an intermediating shell.请注意,“writer_pdf_Export”周围没有撇号,因为它们是 shell 元字符,并且在构建数组以传递给没有中间 shell 的exec
不需要。
Try this (keep it simple) ...试试这个(保持简单)...
Process p = Runtime.getRuntime().exec("/usr/bin/libreoffice --headless --convert-to pdf:'writer_pdf_Export' --outdir "+ getDestinationDirectory(order)+" "+getInvoiceFilename()+".fodt");
Fully ...完全...
Process process = null;
try {
process = Runtime.getRuntime().exec("/usr/bin/libreoffice --headless --convert-to pdf:'writer_pdf_Export' --outdir "+ getDestinationDirectory(order)+" "+getInvoiceFilename()+".fodt");
} catch (IOException ex) {
Logger.getLogger(Documents.class.getName()).log(Level.SEVERE, null, ex);
}
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
try {
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException ex) {
Logger.getLogger(Documents.class.getName()).log(Level.SEVERE, null, ex);
}
br.close();
System.out.println("Program terminated!");
I have tried every solution proposed in this thread and it does not work.我已经尝试了这个线程中提出的所有解决方案,但它不起作用。
In my app (java webapp using TOMCAT in linux) it only works to create a shell script and execute the script.在我的应用程序(在 linux 中使用 TOMCAT 的 java webapp)中,它只能创建一个 shell 脚本并执行该脚本。 But you have to put the absolute path in the script, if not, it does not work ($HOME does not work).但是你必须在脚本中放置绝对路径,如果没有,它不起作用($HOME 不起作用)。 Besides, you can pass it arguments.此外,您可以向它传递参数。
Example:例子:
Runtime.getRuntime().exec("/home/user/myscript.sh param1");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.