Chamando uma aplicação java dentro de outra

6 respostas
L

Para chamar um novo aplicativo java dentro de outro já em execução eu uso o comando

String comando = "java -jar C:\caminho_de_aplicacoes\App2\app2.jar";
Process processo = Runtime.getRuntime().exec(comando);

Mas os dois aplicativos estão em pastas diferentes…
Ex: O aplicataivo mestre está em C:\caminho_de_aplicacoes\App1\app1.jar
e por sua vez o aplicativo que é chamado pelo mestre está em C:\caminho_de_aplicacoes\App2\app2.jar

Meu grande problema é… dentro do app2.jar tem algumas rotinas que busca arquivos de configuração que está dentro do seu próprio diretório… para isso eu uso File fl = new File(“configuracao.properties”)
quando eu executo o app2 separado…ele busca o arquivo certo…mas quando o app1 chama o app2…ele vai buscar o arquivo configuração.properties dentro do diretório do app1 e não dentro do app2 que seria o correto…

dá para ver isso usando o System.getProperty(“user.dir”)… tanto na app1 quando na app2 ele retorna o caminho do app1 (isso quando o app2 é chamado em tempo de execução dentro do app1)…

Tem como fazer o app2 interpretar seu diretorio certo quando chamando de dentro do app1? ou terei que revisar todo o app2 e mudar o comando File fl = new File(“configuracao.properties”) por File fl = new File(“C:\caminho_de_aplicacoes\App2\configuracao.properties”)

Na verdade…seria executar uma nova instância do app2 totalmente separada de app1, mas parece que a vm não interpreta assim, ela leva as propriedades setadas no app1 junto pra app2

6 Respostas

drsmachado

Bom, quando você chama o segundo aplicativo a partir do primeiro, a “instância” do segundo pertence ao primeiro. Ele acaba sendo executado de onde o primeiro está em execução.
Talvez consiga resolver isso criando um novo .bat e chamando o bat, não diretamente o aplicativo dois.

L

e como ficaria isso em linux?

drsmachado

Camarada, eu fiz alguns testes aqui e consegui o seguinte.

Classe que chama:

package main;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		File f = new File(".");//local onde será criado o prompt
		Process proc = null;
		try {
			proc = Runtime.getRuntime().exec("cmd", null, f);
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		if (proc != null) {
			BufferedReader in = new BufferedReader(new InputStreamReader(
					proc.getInputStream()));
			PrintWriter out = new PrintWriter(new BufferedWriter(
					new OutputStreamWriter(proc.getOutputStream())), true);
			out.println("cd diretorio");//acessando o diretório que preciso, caso esteja abaixo, utilize cd .. até chegar no nível de acesso ao outro
			out.println("exec");//nome do .bat
			try {
				String line;
				while ((line = in.readLine()) != null) {
					System.out.println(line);
				}
				proc.waitFor();
				in.close();
				out.close();
				proc.destroy();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

E a classe que é executada

package main;

import java.io.File;

import javax.swing.JOptionPane;

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		File f = new File(".");
		String caminho = f.getAbsolutePath();
		JOptionPane.showMessageDialog(null, caminho);
	}

}

Fiz o seguinte, criei um jar com a primeira, em meus documentos. Depois, criei a pasta “diretorio” e nela coloquei o jar com a segunda classe e o bat chamado exec.bat, que só executa

java -jar chamado.jar

Fui ao prompt de comando, executei, dentro de meus documentos

java -jar chama.jar

E aguardei, a saída trouxe o JOptionPane, com o diretório correto.

L

Ok…obrigado a todos… seguindo as dicas dos amigos acima…deu certo…no inicio eu estava chamando o outro sistema direto do runtime… por isso que ele levava as confiugurações de instancia do java junto,tipo , o user.dir…etc… se executar a partir de um bat…isso não ocorre…
Agora me resta fazer a versão disso pra linux…eu teria que gerar um arquivo .bin em vez de um bat para isso?

drsmachado
File wd = new File("/bin");System.out.println(wd);Process proc = null;try {   proc = Runtime.getRuntime().exec("/bin/bash", null, wd);}catch (IOException e) {   e.printStackTrace();}if (proc != null) {   BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));   PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);   out.println("cd ..");   out.println("pwd");   out.println("exit");   try {      String line;      while ((line = in.readLine()) != null) {         System.out.println(line);      }      proc.waitFor();      in.close();      out.close();      proc.destroy();   }   catch (Exception e) {      e.printStackTrace();   }}

Isso deve resolver teu problema com relação ao linux.
Só lembrando, quando você chama o Runtime e passa como argumentos o “executor”, pode fazer qualquer comando ser executado.
Ou seja, no exemplo que postei antes, se trocar o “exec” por “java -jar nomeDoJar.jar” vai funcionar igual.

P.S.: Crédito: http://www.webmasterworld.com/linux/3613813.htm

L

Ok…funcionou tudo certinho para inicializar…
só que eu estava implementando aqui a rotina…e me veio em mente…que pode acontecer…
de ocorrer algum erro na inicialização do segundo programa chamando pelo principal…
No meu caso…eu teria que fechar o mesmo…

levando em conta que o comando Runtime.getRuntime().exec(comando) retorna um Process… pensei em destruir esse process,
caso ocorra algum erro de inicialização… usando o seguinte comando

process.destroy()

só que o mesmo não finaliza a segunda aplicação chamanda pela aplicação mestre… simplesmente finaliza a instância da mesma na aplicação principal, porém fica rodando ainda no pc… tem como eu finalizar esta segunda aplicação com uma espécie de kill ou algo assim?

Criado 22 de fevereiro de 2012
Ultima resposta 22 de fev. de 2012
Respostas 6
Participantes 2