0

I'm trying to restore a backed up .sql file using Java program. I'm posting the method below. But when I execute this the program halts for a long time. Then I executed same mysql command in command line(Windows) it's works charmingly.

Puzzled where I missed. What do you think ?

            File file;
         final JFileChooser fc = new JFileChooser();
         int returnVal = fc.showOpenDialog(this);

   if (returnVal == JFileChooser.APPROVE_OPTION) {
                 file = fc.getSelectedFile();

         try {
             System.out.println(file.getCanonicalPath());

        String executeCmd = "mysql -u " + username + " -p" + password +" " + dbName+" < "+" \" "+file.getCanonicalPath()+"\" " ;
         Process runtimeProcess;
           runtimeProcess = Runtime.getRuntime().exec(executeCmd);
         int processComplete = runtimeProcess.waitFor();
         if (processComplete == 0) {

            JOptionPane.showMessageDialog(Interface.mainFrame, "Database Backup restored successfully.", "Netmetering", 1);     
        } else {
            System.out.println("Could not restore the backup");
        }
    } catch (IOException | InterruptedException ex) {}

...

4
  • The process may be waiting for its stdout to be flushed, which you are ignoring. Read the processes input stream till it returns -1 Commented Sep 11, 2013 at 4:59
  • sorry, I'm not sure I understand you. It takes forever to complete. But when I invoked the same command in cmd, it takes about 2 seconds to complete. Commented Sep 11, 2013 at 5:33
  • stackoverflow.com/questions/13227057/… Commented Sep 11, 2013 at 5:36
  • @MadProgrammer I think You are correct. Thanks. Apache Commons Exec library could be a solution. I'll try that. Commented Sep 11, 2013 at 5:37

2 Answers 2

1
String executeCmd = "mysql -u " + username + " -p" + password +" " + dbName+" < "+" \" "+file.getCanonicalPath()+"\" " ;
Process runtimeProcess = Runtime.getRuntime().exec(executeCmd);
InputStream is = runtimeProcess.getInputStream();

// Do one OR the other, but not both ;)

// If you don't care about the output, but I think it's a bit of waste personally...
while (is.read() != -1) {}

// I'd at least dump the output to the console...
int byteRead = -1;
while ((byteRead = is.read()) != -1) {
    System.out.print((char)byteRead );
}

int processComplete = runtimeProcess.waitFor();
if (processComplete == 0) {...}

I would also recommend using ProcessBuilder over creating the Process manually like this, it handles the parameters better - IMHO

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

Comments

1

In general the correct way to run an external program is:

  • build you external program command line
  • build the ProcessBuilder and Process
  • build your own StreamRender
  • execute your external program
  • check the STDOUT and STDERR of your external program
  • verify the exit status of your external program

you can achieve this sequence as described following:

String command = "mysql -u... -p... dbname < file.sql";
ProcessBuilder pb = new ProcessBuilder(command);
Process pr;

try {
  pr = pb.start();
  StreamRender outputStdout = new StreamRender(pr.getInputStream(), StreamRender.STDOUT);
  // your STDOUT output here
  outputStdout.start();

  StreamRender outputStderr = new StreamRender(pr.getErrorStream(), StreamRender.STDERR);
  // your STDERR outpu here
  outputStderr.start();

  pr.waitFor();
  if (pr.exitValue() != 0) {
    // your external program fails
  } else {
    // ok, your external program was executed correctly
  }

} catch (Exception e) {
  // ...
}  finally {
  // ...
}

StreamRender.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class StreamRender extends Thread {

public static final String STDOUT = "STDOUT";
public static final String STDERR = "STDERR";

private InputStream inputStream;
private String inputType;

public StreamRender(InputStream inputStream, String inputType) {
  this.inputStream = inputStream;
  this.inputType = inputType;
}

public void run() {
  try {
    InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
    BufferedReader br = new BufferedReader(inputStreamReader);
    String line = null;
    while ((line = br.readLine()) != null) {
      System.out.println(this.inputType + " > " + line);
    }
  } catch (IOException ioe) {
    ioe.printStackTrace();
  }
}

2 Comments

Be careful using a BufferedReader, not every process will output a new line terminator during the lifecycle process, if you get lucky, it will do so at the end ;)
@Cristian Porta Thank you very much. It was quite helpful.

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.