Running "ProcessBuilder.start" on Docker fails

Viewed 67

Installation of libreoffice package in Docker container.

I'm trying to convert a JAVA application from Excel to a PDF file, but an error occurs. (The container is running on Google Cloud Run.)

The Dockerfile is below.

FROM maven:3.8-jdk-11

RUN apt-get -y update
RUN apt-get -y install libreoffice
RUN mvn package

FROM adoptopenjdk/openjdk11:alpine-jre
CMD ["java", "-jar", "/app.jar"]

The java code running in the container is below.

ProcessBuilder builder = new ProcessBuilder("/bin/sh", "-c", "soffice --headless -convert-to pdf --outdir '/out' '/out/file.xlsx'");
Process process = builder.start();

The error message that is output is as follows.

line 1: soffice:not found

After installing the package in the Dockerfile, when I executed the which command, usr/bin/libreoffice existed, so I think the path is correct. (I may be wrong)

I'm thinking that there might be information that's missing but I'm not so sure since I'm a newbie with Docker.

Any help would be greatly appreciated.

1 Answers

The error says that /bin/sh does not know where the binary soffice is. The "soffice" binary must be on the PATH for /bin/sh. Launch a shell and check with which soffice, you may be able to fix your shell profile to include the correct PATH directories for soffice before your code will work:

ProcessBuilder builder = new ProcessBuilder("/bin/sh", "-c", "soffice --headless -convert-to pdf --outdir '/out' '/out/file.xlsx'");

But if you know the fully qualified path to the soffice binary you should be able to eliminate the use of sub-process shell and separate the command line arguments:

String soffice = "/full/path/to/soffice"; // eg /usr/lib/libreoffice/program/soffice.bin
// Check with:
System.out.println(soffice +" exists: "+new File(soffice).exists());
ProcessBuilder builder = new ProcessBuilder(soffice, "--headless", "-convert-to pdf", "--outdir", "/out", "/out/file.xlsx");

If "soffice" is in the PATH provided to your JVM, then launch without sub-process shell and path ought to work. You may be able to check which soffice before launching your Java application to see if this may work:

String soffice = "soffice"; 
ProcessBuilder builder = new ProcessBuilder(soffice, "--headless", "-convert-to pdf", "--outdir", "/out", "/out/file.xlsx");
Related