0

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.

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for your help but now I'm getting java.lang.NullPointerException for Process p = pb.start(); I can edit the initial question with the code you wrote and I used if you want
Done, please check it
From the JavDocs NullPointerException - if an element of the command list is null
I found the null pointer but the problem now is it gets stuck, for some reason, when doing while((in = is.read()) != -1) and it does not output anything... I know a dump may take a while doing but this database is small and doing by hand on the command line it doesn't take more than a couple of seconds. While on the java it gets stuck there "forever" (I've been waiting minutes and nothing comes up". The file is created tho but it is empty.
If the file is empty then I assume the process has not completed. Have you tried running the command from the command line to see what it actually prints?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.