Olá (denovo :D)
Então, estou com esse problema que parece bem simples, mas ta complicando aqui…
Eu tenho uma aplicação que chama outros aplicativos pelo Runtime.getRuntime().exec(comando). E logo após eu chamar a aplicação, eu fico esperando resposta do cliente pelo Socket. Ou seja, o programa trava todo esperando a resposta do aplicativo.
Mas o que eu não consigo fazer é verificar se o programa abriu corretamente. Se ele não abrir, eu não quero esperar a resposta do cliente.
[code]Process proc = Runtime.getRuntime().exec(comando);
InputStream stderr = proc.getErrorStream();
InputStreamReader isr = new InputStreamReader(stderr);
BufferedReader br = new BufferedReader(isr);
String line = null;
System.out.println("");
line = br.readLine()
System.out.println(line);
System.out.println("");
int exitVal = proc.waitFor();
System.out.println("Process exitValue: " + exitVal);
if(exitVal > 0){
JOptionPane.showMessageDialog(Main.getJanelaPrincipal(), line);
} else {
Main.setJogoAtivo(Main.getJogos().get(i).getNome());
Main.iniciarServidor();
}[/code]
Nesse código, funciona quando tem um erro. Consigo pegar o erro e não roda o socket. Mas quando eu vou rodar com sucesso, o programa abre antes sem eu abrir o socket (pelo fato do proc.waitFor() estar “travando” a aplicação)
Dai se eu colocar o servidor pra iniciar antes, ele trava a aplicação, esperando resposta do cliente, e eu não posso fecha-lo quando vejo que a aplicação não iniciou.
Alguem ai tem uma ideia de como eu posso fazer isso melhor? Ja pesquisei varios lugares e foi o unico jeito que eu achei pra ver se não executou.
Obrigado.
quando você abre o socket ou server socket, a thread corrente fica travada até que a conexão seja bem sucedida (ou que ocorra um timeout no caso do socket).
se eu bem me lembro de a mais de um ano atras quando eu mechi com runtime, ele também travava a thread até terminar de executar quando você usava o waitFor.
o que você pode fazer é deixar cada um em uma thread e ir gerenciando-as, para uma com wait, quando a outra for executar da um notify nela… confesso que não intendi bem o que você quer, me pareceu que você quer abrir um outro programa via runtime, depois disso abrir um socket no qual o cliente enviará o retorno (e nem abrir o socket se o programa não tiver aberto corretamente), ai tendo aberto depois disso você abre o socket…
faça o seguinte, crie duas classes herdando Thread, uma para fazer cada uma das coisas que você quer no método run, a classe que usa o Runtime deve ter um flag informando se houve erro (que deve ser setado caso tenha o erro mesmo).
ai você cria o objeto da thread do runtime, starta ele, da um sleep da thread corrente de uns 50 ms, acessa o getter deste flag, caso esteja sem erros vocÊ starta a thread do socket também para abri-lo. Se for isso é claro.
Então… Eu acho que to fazendo mais ou menos isso que você ta dizendo… Só que eu só testei com 2 jogos (um bem leve, e outro um pouco mais pesado). Estou usando um sleep de 50ms, caso o programa ja esteja fechado nesse tempo, ele nem abre, e se ele estiver aberto, eu abro a conexão do socket…
O problema é que pode ser que esse programa não funcione com jogos super leves, que possam abrir em menos de 50ms… Bom, é meio improvavel (ou não é?), mas pode acontecer… Acho essa solução meio gambiarra, mas não consigo pensar em nada melhor, até porque a espera de conexão trava todo o programa, não tendo como eu “verificar” depois de um tempo de espera se ja houve resposta do cliente…
Mas vou deixar o código aqui, caso alguém tenha esse problema. Mas se alguem tiver uma solução melhor, sera muito bem vinda 
[code]Process proc = Runtime.getRuntime().exec(comando);
InputStream stderr = proc.getErrorStream();
InputStreamReader isr = new InputStreamReader(stderr);
BufferedReader br = new BufferedReader(isr);
System.out.println("");
//System.out.println(br.readLine()); //mostra mensagem de erro. caso esteja dando erro de execução, descomente pra ver o erro. duplique essa linha pra ver mais linhas de erro.
System.out.println("");
try{
Thread.sleep(50);
int exitVal = proc.exitValue();
System.out.println("Process exitValue: " + exitVal);
JOptionPane.showMessageDialog(Main.getJanelaPrincipal(), “Erro ao carregar o jogo”);
} catch(Exception ex){
Main.setJogoAtivo(jogo.getNome());
Main.iniciarServidor();
}[/code]
Tem outra coisa também… Eu estou executando o comando “python /jogos/CampoMinado/cm.py”. Nessa pasta (CampoMinado) tem várias imagens. Quando eu executo o programa por fora, roda muito bem. Mas quando eu executo pelo java, ele busca as imagens de onde esta o programa java, e não da pasta CampoMinado. Eu acredito que eu tenha que executar o comando de dentro da pasta campominado, mas não sei como fazer isso. Alguem pode dar uma luz?
bom… no penultimo comentário antes desse meu sobre o socket travar a aplicação, ele não vai travar se estiver em uma thread separada, quanto ao software executar na pasta onde estão as imagens, acredito que vocÊ possa no runtime primeiro mudar para a pasta onde estão as imagens e depois executar o jogo, da mesma forma que seria feito em um arquivo em lotes, um script .bat ( acho que seria algo do tipo cd <endereço>;jogo.exe).
Consegui resolver ambos problemas.
No primeiro, eu usei o servidor como uma Thread mesmo, assim deu pra correr o aplicativo pra verificar se estava aberto ou não.
E no caso do runtime, o Runtime tem um método que tem 3 parametros: comando, lista de argumentos e o caminho pra executar. No caso eu apenas passei a lista de argumentos como null e coloquei o caminho pra executar e deu certo 
Muito obrigado pela ajuda 
PS: Finalmente terminei esse projeto. Até o próximo pra mais um turbilhão de tópicos de ajuda.