[Resolvido] Problema com Runtime java7u21, adaptando ProcessBuilder

4 respostas
A

Olá pessoal,

Eu tinha uma chamada em Runtime que dava start ao serviço do Mysql com a classe Runtime.

Process p = Runtime.getRuntime().exec(caminho + "/MySql Server/bin/mysqld --install MYSQL " + '"' + "--defaults-file=" + caminho + "/MySql Server/my.ini" + '"');

Mas as ultimas atualizações bloquearam essa funcionalidade, explicado na documentação

http://www.oracle.com/technetwork/java/javase/7u21-relnotes-1932873.html#jruntime

Fiz alteração para utilizar a classe ProcessBuilder

String caminho = "C:/Program Files (x86)";
        File fBD = new File(caminho + "/MySql Server/bin/mysqld");
        File fArq = new File(caminho + "/MySql Server/my.ini");

        String[] cmd = new String[4];

            cmd[0] = fBD.getAbsolutePath();
            cmd[1] = "--install";
            cmd[2] = "MYSQL";
            cmd[3] = "--defaults-file=" + fArq.getAbsolutePath() ;

            ProcessBuilder pb = new ProcessBuilder(cmd);

            File dirOut = new File("C:/out.txt");
            File dirErr = new File("C:/err.txt");
            pb.redirectOutput(dirOut);
            pb.redirectError(dirErr);

            Process p = pb.start();

            try {
                p.waitFor();
            } catch (InterruptedException ex) {
                ex.printStackTrace();
                Logger.getLogger(app.class.getName()).log(Level.SEVERE, null, ex);
            }

Mas agora tenho outro problema o serviço é criado só que o caminho binPath fica errado e não start o serviço

“C:\Program Files (x86)\MySql Server\bin\mysqld” “–defaults-file=C:\Program Files (x86)\MySql Server\my.ini” MYSQL

o correto seria,

“C:\Program Files (x86)\MySql Server\bin\mysqld” --defaults-file=“C:\Program Files (x86)\MySql Server\my.ini” MYSQL

quando utilizava a classe Runtime utilizava ‘"’ ou “”" para circundar a instrução --defaults-file, criando corretamente o caminho mas agora esse artificio não funciona no ProcessBuilder e não consigo mas fazer a chamada em Runtime… :shock:

4 Respostas

A

Olá wellington,

Testei com seu código, mas ele não funciona na jvm 7u21 e 6u45 não aceitam mais esses inject de \" não cheguei ler tudo do pq das mudanças, mas acho que foi por motivos de segurança.

String[] cmd2 = new String[]{
                "\"" + fBD.getAbsolutePath() + "\"", //note que coloquei as aspas aqui...
                "--install", "MYSQL",
                "--defaults-file=\"" + fArq.getAbsolutePath() + "\"" //note que coloquei as aspas aqui...
            };


            InputStream in = Runtime.getRuntime().exec(cmd2).getErrorStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(in));

            String linha = "";
            while ((linha = br.readLine()) != null) {
                System.out.println(linha);
            }

ERRO : 130502 10:47:29 [ERROR] C:\Program Files (x86)\MySql Server\bin\mysqld: unknown option '--install'

e o mesmo acontece com ProcessBuilder

String[] cmd2 = new String[]{
                "\"" + fBD.getAbsolutePath() + "\"", //note que coloquei as aspas aqui...
                "--install", "MYSQL",
                "--defaults-file=\"" + fArq.getAbsolutePath() + "\"" //note que coloquei as aspas aqui...
            };

            ProcessBuilder pb = new ProcessBuilder(cmd2);

            File dirOut = new File("C:/out.txt");
            File dirErr = new File("C:/err.txt");
            pb.redirectOutput(dirOut);
            pb.redirectError(dirErr);
            Process p = pb.start();


            try {
                p.waitFor();
            } catch (InterruptedException ex) {
                ex.printStackTrace();
                Logger.getLogger(app.class.getName()).log(Level.SEVERE, null, ex);
            }

O mesmo erro acontece aqui só é direcionado ao dirErr ... Parece que a jvm está interpretando as aspas no parâmetro como um erro de sintaxe ou algo assim e modificando antes de mandar executar ...

Retirando as injeções de aspas eu consigo criar o serviço mas o caminho dele ficava errado e não tinha como startalo, mas estranhamente agora o serviço startou mesmo estando com o caminho errado: ... :?

binPath do serviço:
"C:\Program Files (x86)\MySql Server\bin\mysqld" "--defaults-file=C:\Program Files (x86)\MySql Server\my.ini" MYSQL

vou fazer mais alguns testes aqui, to ficando meio doido ..... vlw pela ajuda.

wellington.nogueira:
Tente desta forma:
//Defina o caminho
		File caminho = new File("c:/Program Files");
		
		//Defina o executavel
		File exec = new File(caminho, "arquivo.ext");
		
		//Defina o arquivo de configuração (aqui presumi que o caminho é o mesmo para ambos.
		File arquivo = new File(caminho, "arquivo2.ext");
		
		//Crie o comando
		String[] cmd = new String[] {
			"\"" + exec.getAbsolutePath() + "\"", 	//note que coloquei as aspas aqui...
			"--arg01", 
			"--arg02=\"" + arquivo.getAbsolutePath() + "\""	//note que coloquei as aspas aqui...
		};

		//Execute teu método
		metodo(cmd);
E

Um jeito maroto de você fazer isso é você mudar o diretório local para “C:\Program Files (x86)\MySql Server” (malditos espaços dos infernos) e então chamar o ProcessBuilder com caminhos relativos, como se o comando fosse este aqui:

bin\mysqld --defaults-file=my.ini MYSQL
A

Olá entanglement,

Morri de rir quando li “Um jeito maroto de fazer isso” muito bom. Sim o problema todo de ter que fazer esse malabarismo é os espaços.

Mas no meu caso o problema é a passagem de parâmetros queria ver uma forma de circundar a instrução com aspas “–defaults-file=”" + fArq.getAbsolutePath() + “”" ,
mas pelo jeito não tem como.

Assim fica sem eu circundar a instrução …

“C:\Program Files (x86)\MySql Server\bin\mysqld” “–defaults-file=C:\Program Files (x86)\MySql Server\my.ini” MYSQL

o correto seria assim, circundando a instrução e garantindo os parâmetros corretos

“C:\Program Files (x86)\MySql Server\bin\mysqld” --defaults-file=“C:\Program Files (x86)\MySql Server\my.ini” MYSQL

O que ta me deixando louco é que agora esta funcionando algo que não funcionava a umas 2 horas atrás, estou me convencendo que coloquei algum parâmetro errado mesmo.

vlw pela resposta.

WellingtonRamos

Tente desta forma:

//Defina o caminho
		File caminho = new File("c:/Program Files");
		
		//Defina o executavel
		File exec = new File(caminho, "arquivo.ext");
		
		//Defina o arquivo de configuração (aqui presumi que o caminho é o mesmo para ambos.
		File arquivo = new File(caminho, "arquivo2.ext");
		
		//Crie o comando
		String[] cmd = new String[] {
			"\"" + exec.getAbsolutePath() + "\"", 	//note que coloquei as aspas aqui...
			"--arg01", 
			"--arg02=\"" + arquivo.getAbsolutePath() + "\""	//note que coloquei as aspas aqui...
		};

		//Execute teu método
		metodo(cmd);
Criado 2 de maio de 2013
Ultima resposta 2 de mai. de 2013
Respostas 4
Participantes 3