Reputation: 65
My goal is to restore a Mysql dump using mysql command.
I'm having a clear difference of behaviour between a code using ProcessBuilder and Apache Commons Exec (1.3).
This code works perfectly fine
List<String> params = new ArrayList<>();
params.add("sh");
params.add("-c");
params.add("mysql -uroot -proot < /tmp/the_dump.sql");
ProcessBuilder pb = new ProcessBuilder(params);
Process p = pb.redirectErrorStream(true).start();
int exitValue = p.waitFor();
But this one (with Apache Commons Exec)
CommandLine cmdLine = new CommandLine("/usr/bin/sh");
cmdLine.addArgument("-c");
cmdLine.addArgument("mysql -uroot -proot -e 'source /tmp/the_dump.sql'");
PumpStreamHandler streamHandler = new PumpStreamHandler(System.out, System.err, System.in);
Executor executor = new DefaultExecutor();
executor.setStreamHandler(streamHandler);
int exitValue = executor.execute(cmdLine);
crashed with the following error :
Note the missing ' at the end of the command as interpreted by Apache Commons Exec.
Does anyboday has an idea how to make it work with Apache Commons Exec ?
Thanks a lot for your help, Sylvain
Upvotes: 0
Views: 104
Reputation: 106
The sh shell is interpreting mysql -uroot -proot -e 'source /tmp/the_dump.sql'
as a single file and trying to find that file to execute. You need to pass the command to sh by writing to its input stream.
The sh shell usually accepts commands from the stdin stream. If you launch sh in a terminal window the keyboard is stdin. In this case, you're starting a subprocess, so Java has access to the input and output streams of the subprocess. In Java you can write your command to sh's stream by doing the following:
CommandLine cmdLine = new CommandLine("/usr/bin/sh");
byte[] buf = "mysql -uroot -proot -e 'source /tmp/the_dump.sql'".getBytes();
ByteArrayInputStream is = new ByteArrayInputStream(buf);
PumpStreamHandler streamHandler = new PumpStreamHandler(System.out, System.err, is);
Executor executor = new DefaultExecutor();
executor.setStreamHandler(streamHandler);
int exitValue = executor.execute(cmdLine);
Note that by using System.out
and System.err
in your PumpStreamHandler, you will be handling the output and error streams of the java process, not the sh subprocess.
Upvotes: 1