2

I'm trying to restore a Mysql dump from a Java app. I'm using this code:

    Runtime rt = Runtime.getRuntime();
                try {
                   comando = "mysql -u root -ppass -e \"source " + path + "\\sql\\backup.sql\" legapelis" ; 

                   Process proceso = rt.exec(comando);
                   System.out.println("ejecutando");
                   System.out.println(comando);


                   proceso.getInputStream().close();
                   proceso.getOutputStream().close();
                   proceso.getErrorStream().close();


                   completado = proceso.waitFor();
                   if (completado != 0) {
                       System.out.println("error");
                       addActionError(getText("backup.errcopia") + ": " + String.valueOf(completado));
                       consultarCopias();
                       return "error";
                   }
                   System.out.println("fin");


                } catch (Exception e) {
                    addActionError(e.getLocalizedMessage());
                    consultarCopias();
                    return "error";
                }

But the Mysql process that is opened by this code never ends. It hangs and if I kill it, the Mysql service stops working fine (I must restart it). I've tried a lot of codes: closing streams, reading it... but with the same result.

Any hint?

Excuse me if my English isn't so good.

Thank's

Ps: I've tried to add the -v option to the command to read it from inputstream. It start reading but then it hangs again (and it dosn't finish reading the output of the command: it stops suddenly)

davidrgh
  • 853
  • 2
  • 10
  • 17

2 Answers2

1

JavaDoc for Process:

The created subprocess does not have its own terminal or console. All its standard io (i.e. stdin, stdout, stderr) operations will be redirected to the parent process through three streams (getOutputStream(), getInputStream(), getErrorStream()). The parent process uses these streams to feed input to and get output from the subprocess. Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock.

You need to read from these streams, not close them.

Brian Roach
  • 76,169
  • 12
  • 136
  • 161
  • It is a bit tricky, try to read and test this: https://www.securecoding.cert.org/confluence/display/java/FIO07-J.+Do+not+let+external+processes+block+on+IO+buffers and in general, if possible, try to use ProcessBuilder: http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html – tb- Oct 29 '12 at 00:36
  • tb; I've tried the examples from that link (with Runtime and ProcessBuilder both) and the result is the same. With the redirect solution, for example, it stops at the line "c = is.read()" – davidrgh Oct 29 '12 at 07:11
  • It seems like Inputstream has no data to read and the call blocks the thread. I could run it in a separate thread but I'll have the same problem; if I don't consume the stream, waitFor will block too. – davidrgh Oct 29 '12 at 07:44
0

Well, finally I changed the procedure because I couldn't solve this problem. Now, I read the SQL file and I create an ArrayList with the sentences and I execute them by myself.

Thank's everybody for your support.

davidrgh
  • 853
  • 2
  • 10
  • 17