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.
-
Apliquei o famoso 777 no Ruindows para o usuário Todos (Everyone);
-
A aplicação não travou mais porém, ainda aparece a mensagem de erro na importação do SQL;
-
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;
-
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.
1 curtida