Question

I'm trying to use mysqldump with java to create a dump for my database.

I've done the code but the condition if(processCompleted == 0) never happens for some reason that I can not understand. And I say this because on the console there is no exception but it always prints

"Error doing dump!"

which leads me to conclude that if(processCompleted == 0) is never meet.

Can someone please explain me what I'm doing wrong here?

public boolean backupDatabase(String path, String whichServer)
{
    String cmd;
    Process runtimeProcess;

    if(whichServer.equalsIgnoreCase("local"))
    {
        cmd = "mysqldump -u " + getSourceUsername() + " -p" + getSourceServerPassword()
            + " --add-drop-database -B " + getSourceDatabase() + " -r " + path;
    }         
    else if(whichServer.equalsIgnoreCase("remote"))
    {
        cmd = "mysqldump -u " + getDestinationUsername() + " -p" + getDestinationServerPassword()
            + " --add-drop-database -B " + getDestinationDatabase() + " -r " + path;
    }
    else
    {
        System.out.println("Input server incorrect");
        return false;
    }

    try{

        String[] cmdArray = new String[]{"C:\\wamp\\bin\\mysql\\mysql5.5.24\\bin\\mysqldump.exe", cmd};
        System.out.println("Preparing for dump.");
        runtimeProcess = Runtime.getRuntime().exec(cmdArray);

        int processCompleted = runtimeProcess.waitFor();

        if(processCompleted == 0)
        {
            System.out.println("Dump done!");
            return true;
        }
        else
        {
            System.out.println("Error doing dump!");
        }

    } catch(Exception ex)
    {
        System.out.println("Exception -> " + ex.getMessage());
    }
    return false;

}

Here's my code using @MadProgrammer suggestion:

public boolean backupDatabase(String path, String whichServer) 
{

    List<String> args = new ArrayList<String>();
    args.add("C:\\wamp\\bin\\mysql\\mysql5.5.24\\bin\\mysqldump.exe");

    args.add("-u");
    args.add(getSourceUsername());
    args.add("-p");
    args.add(getSourceServerPassword());
    args.add("--add-drop-database");
    args.add("-B");
    args.add(getSourceDatabase());
    args.add("-r");
    args.add(path);

    try{
        ProcessBuilder pb = new ProcessBuilder(args);
        pb.redirectError();
        Process p = pb.start();

        InputStream is = p.getInputStream();

        int in = -1;

        while((in = is.read()) != -1)
        {
            System.out.println((char) in);
        }

        int proccessCompleted = p.waitFor();

        if(proccessCompleted == 0)
        {
            System.out.println("Dump done!");
            return true;
        }
        else
        {
            System.out.println("Error doing dump!");
            return false;
        }
    }
    catch(IOException | InterruptedException ex)
    {
        System.out.println("Exception exportDB -> " + ex.getMessage() + "|" + ex.getLocalizedMessage());
    }
    return false;
}

PS; where you wrote "//? Is this a single command?" -p is the command for the password and getSourceServerPassword() is the method to get the password.

Was it helpful?

Solution

I suspect because you've separated the cmdArray into only two elements that mysqldump is treating the second array element as a single command line argument.

Also, you've not paying attention to the output of the process which makes it really difficult for your to ascertain what the processing is trying to tell.

You "base" command also includes mysqldump...

"mysqldump -u " + getSourceUsername() + " -p" + getSourceServerPassword()
        + " --add-drop-database -B " + getSourceDatabase() + " -r " + path;

as part of the command, which means you are effectively calling mysqldump mysqldump...

Instead of using a String, place all your commands into some kind of list instead.

Remember, if it's separated by a space on the command line, it's a separate command/element

List<String> args = new ArrayList<String>
args.add("C:\\wamp\\bin\\mysql\\mysql5.5.24\\bin\\mysqldump.exe");
//...
args.add("-u");
args.add(getSourceUsername());
args.add("-p" + getSourceServerPassword()); //?? Is this a single command?
args.add("--add-drop-database");
args.add("-B");
args.add(getSourceDatabase());
args.add("-r");
args.add("path);
//...

Then use ProcessBuilder

ProcessBuilder pb = new ProcessBuilder(args);
pb.redirectError();
Process p = pb.start();

InputStream is = p.getInputStream();
int in = -1;
while ((in = is.read()) != -1) {
    System.out.print((char)in);
}

int processCompleted = p.waitFor();

Remember, you should never ignore the output from a process, even if you don't care, you should attempt to consume the content from the InputStream as some processes will hang if there output stream is not read.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top