[RESOLVIDO] Restaurar Arquivo SQL via Java Swing

Minha aplicação possui um botão para executar um JFileChooser(). Consigo localizar o arquivo desejado, capturar o .getSelectedPath() e jogar dentro de uma JTextField().

private void btnBuscaArquivoActionPerformed(java.awt.event.ActionEvent evt) {                                                
    String path = null;
    JFileChooser chooser = new JFileChooser(path);
    chooser.setDialogTitle("Selecione o arquivo SQL desejado:");
    chooser.showOpenDialog(chooser);

    File file = chooser.getSelectedFile();
    path = file.getPath();
    v_Caminho.setText(path);
}

Em seguida, tenho outro botão para CONFIRMAR a restauração das tabelas do MySQL. Nele, tenho este código:

private void restauraBackup(String fileSQL) { 
    // recebo o caminho correto por parâmetro após executar o TRUNCATE 
    // das tabelas antigas. Funcionando perfeitamente.

    fileSQL = fileSQL.replace("\\", "/");

    if (fileSQL == null) {
        msg.aviso("Localize um arquivo SQL para executar a restauração.");
    } else {
        String restoreCmd = "mysql.exe -uroot -proot dadostemporarios < " + fileSQL ;
        try {
            Process process = null;
            process = Runtime.getRuntime().exec(restoreCmd);
            int processCom = process.waitFor();

            if (processCom == 0) {
                msg.sucesso("Restauração concluída com êxito.");
            } else {
                msg.falha("Falha na restauração do arquivo SQL.");
            }

        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Neste momento a aplicação trava e no Gerenciador de Tarefas, a aplicação cria o processo do mysql.exe mas não executa nada. O que estou fazendo de errado?

Quando eu precisei fazer restore de um DB MySQL utilizei uma String de comandos um pouco diferente da sua e me atendeu perfeitamente!

Exemplo:

String[] restoreCmd = new String[]{"mysql", "--user=root", "--password=root", "meuDatabase", "-e", " source caminhoDoArquivoDeRestore"};

@Jonathan_Medeiros Obrigado pela ajuda… Infelizmente também não deu certo. A Aplicação continua travada, com um subprocesso do mysql.exe ativo. Quando finalizo apenas o subprocesso, a aplicação exibe a mensagem de SUCESSO no procedimento porém, no BD, nada aconteceu.

Pra ilustrar melhor o que acontece:


O mysql.exe aparece junto com o Host de Console quando clico no botão RestaurarBackup.

Quando você utiliza a classe Runtime para executar um programa externo que espera parâmetros, você precisa utilizar o método exec que recebe um array de String.
O primeiro elemento do array tem que ser o programa em si e cada elemento seguinte tem que ser um parâmetro.

String restoreCmd = new String[] { "mysql.exe", "-uroot", "-proot", "dadostemporarios", "<", fileSQL };
try {
    Process process = Runtime.getRuntime().exec(restoreCmd);
    int processCom = process.waitFor();

DICA:

Evite códigos como este:

Process process = null;
process = Runtime.getRuntime().exec(restoreCmd);

Faça simplesmente assim:

Process process = Runtime.getRuntime().exec(restoreCmd);

Olá @staroski… Obrigado por ajudar. O Código em si não deu erro nem lançou Exception com o try / catch porém, a aplicação se manteve travada. Do mesmo jeito… Tentei dar um sout no processCom antes de entrar no IF mas ele travou antes.

Pessoal, percebi que mudando o arquivo SQL para a o diretório padrão do JFileChooser() [C:\Users\fulano\arquivo.sql] o procedimento funciona. Logo imaginei: “então deve ser permissão de acesso no diretório oficial. Onde o arquivo NECESSITA estar”. Resumindo: por conta de padronização da aplicação eu não posso mudar o diretório do arquivo SQL.

  1. Apliquei o famoso 777 no Ruindows para o usuário Todos (Everyone);

  2. A aplicação não travou mais porém, ainda aparece a mensagem de erro na importação do SQL;

  3. Quando vou no diretório padrão do JFileChooser() e faço a importação do arquivo copiado, tudo flui perfeitamente até a mensagem final de sucesso aparecer;

  4. O arquivo.sql precisa estar obrigatoriamente no drive W:/backup-anual/arquivo.sql.

Será que ainda devo configurar alguma coisa no JFileChooser() ???

Pessoal… Consegui resolver. Finalmente… Uma coisinha boba que só percebi na hora de tentar executar a importação via DOS.

O código final ficou assim:

private void restauraBackup(String fileSQL) {
    fileSQL = fileSQL.replace("\\", "/");

    if (fileSQL == null) {
        msg.aviso("Localize um arquivo SQL para executar a restauração.");
    } else {

        String linhaCmd = "cmd /c mysql.exe -uroot -proot dadostemporarios < \"" + fileSQL + "\"";

        try {
            // PROCESS como ensinado pelo @staroski . VALEU! 
            Process process = Runtime.getRuntime().exec(linhaCmd);

            int processCom = process.waitFor();
            if (processCom == 0) {
                msg.sucesso("Restauração concluída com êxito.");
            } else {
                msg.falha("Falha na restauração do arquivo SQL.");
            }
        } catch (InterruptedException | IOException e) {
            msg.falha("Falha de exceção na tentativa te restaurar o backup.");
        }
    }
}

A solução para forçar a importação funcionar, não era no JFileChooser() mas sim na linha de instrução DOS que eu estava passando. Se fizer manualmente no terminal de comandos, a linha deveria conter ASPAS para especificar a localização do arquivo SQL. Assim:

 mysql -uroot -proot dadostemporarios < "W:/backup-anual/arquivo.sql"

Já no Java, precisei fazer uma saída de caracteres especiais com a \ … Prevendo uma aspas extra antes da usada no fechamento da String. Assim:

String linhaCmd = "cmd /c mysql.exe -uroot -proot dadostemporarios < \"" + fileSQL + "\"";

Obrigado @Jonathan_Medeiros e @staroski por ajudarem.

Você só precisa pôr os caminhos entre aspas, se houver algum arquivo ou diretório que tenha espaços em branco no seu nome.
:wink:

1 curtida