Linux, Runtime.getRuntime().exec(...) and quotes
String command = “java -jar "/path/to/some/jar/foo.jar"”;
Here is an interesting problem I ran into while doing some work: why is Runtime.getRuntime().exec(command) reporting that it couldn’t access a jar file I was directly trying to invoke in code on Linux but worked no problem on Windows? The generated command was identical on Windows and Linux and copying the command and running it in a terminal executed as it should. WHY DO YOU HATE ME JAVA AND LINUX?
Turns out that it was really only Java hating on me. After playing around with the command, I finally figured out that removing the quotes around the jar path fixed it:
String command = "java -jar /path/to/some/jar/foo.jar";
worked but
String command = "java -jar \"/path/to/some/jar/foo.jar\"";
didn’t.
So what is going on? Unfortunately I don’t know why, but in Linux (at least Ubuntu), the quotes are taken as part of the name. Take this example:
Process p = Runtime.getRuntime().exec("\"ls\"");
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
System.out.println(br.readLine());
tries to actually execute the file named “ls” not ls. From the terminal, you can actually type out “ls” and ls will be executed as you’d expect:
Exception in thread "main" java.io.IOException: Cannot run program ""ls"": java.io.IOException: error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:460)
at java.lang.Runtime.exec(Runtime.java:593)
at java.lang.Runtime.exec(Runtime.java:431)
at java.lang.Runtime.exec(Runtime.java:328)
at RuntimeTest.main(RuntimeTest.java:9)
Caused by: java.io.IOException: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.(UNIXProcess.java:148)
at java.lang.ProcessImpl.start(ProcessImpl.java:65)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:453)
... 4 more
Definitely something to keep in mind if you are developing software and the environments are varied. OS X and Linux behave the same way in this regard. Windows is different.