7

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:

/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:

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!");
4

3 回答 3

6

构造函数要求外部程序的ProcessBuilder每个参数都是独立的(以数组或 s 的形式ListString。您收到的第一条异常消息,

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"

不是抱怨它可以找到一个名为/usr/bin/libreoffice. 它抱怨它找不到具有非常长且特殊名称“ /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

代替

command.add("--convert-to pdf:'writer_pdf_Export' --outdir " + getDestinationDirectory(order) + " " + getInvoiceFilename() + ".fodt")

等等,将每个参数拆分为自己的调用List.add

command.add("--convert-to");
command.add("pdf:writer_pdf_Export");

command.add("--outdir");
command.add(getDestinationDirectory(order).toString());

command.add(getInvoiceFilename() + ".fodt");

请注意,“writer_pdf_Export”周围没有撇号,因为它们是 shell 元字符,并且在您构建要在exec没有中间 shell 的情况下传递的数组时不需要。

于 2013-05-10T12:49:44.920 回答
1

我已经尝试了这个线程中提出的所有解决方案,但它不起作用。

在我的应用程序(在 linux 中使用 TOMCAT 的 java webapp)中,它只能用于创建一个 shell 脚本并执行该脚本。但是你得把绝对路径放在脚本里,不然不行($HOME不行)。此外,您可以传递参数。

例子:

Runtime.getRuntime().exec("/home/user/myscript.sh param1");
于 2014-02-12T18:24:58.473 回答
1

试试这个(保持简单)......

Process p = Runtime.getRuntime().exec("/usr/bin/libreoffice --headless --convert-to pdf:'writer_pdf_Export' --outdir "+ getDestinationDirectory(order)+" "+getInvoiceFilename()+".fodt");

完全...

    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!");
于 2013-05-10T12:53:08.797 回答