mnementh64
mnementh64

Reputation: 65

Fail to execute mysql command to restore dump with Apache Commons Exec

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 :

Error with Apache Commons Exec

Note the missing ' at the end of the command as interpreted by Apache Commons Exec. command line as interpreted

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

Answers (1)

SciFiDryer
SciFiDryer

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

Related Questions