Como não permitir a abertura de programas ao mesmo tempo? [RESOLVIDO]

Bom dia pessoal

Suponham que eu tenho vários sistemas, o A, o B e o C.

Eu não posso permitir que mais de um deles seja aberto ao mesmo tempo, ou seja, ou o kra usa o A, ou o B ou o C. E só uma vez cada um, enfim, só pode ter um deles aberto a cada vez.

Andei lendo sobre isso aqui no GUJ, as soluções que vi que foram sugeridas foram:

  • usar uma porta específica e qdo entrar no programa abrir esta porta, o próximo que for entrar verifica se a porta já está aberta e não entra nesse caso.

  • usar um arquivo no HD, de forma que ele seja bloqueado qdo um tiver rodando, e ai o outro não consegue bloquea-lo e não starta a aplicação

Só que essas duas opções no meu caso não podem ser usadas de forma alguma.

Por favor, alguém tem mais alguma idéia de como posso fazer esse controle?! Em Delphi lembro que eu tinha como pegar no windows quais os programas que estavam rodando e por ai eu podia fazer essa verificação. Em java tem como fazer isso?! E no linux?! Tem jeito?!

Tô aceitando qq “pista”! :roll:

Grata,
Renata

Blz?

todos os programas tem login e senha?

Se tiverem vc pode controlar por usuário logado. Não é muito elegante, mas deve funcionar…

t+

Estou com o mesmo problema. Então fço votos para que algum santo nos indique o caminho para salvação.

Olá

Use sockets. Ao entrar na aplicação tente abrir um ServerSocket com uma porta maluca qualquer&gt 1024. Só vai abrir da primeira vez. Veja:

http://www.guj.com.br/posts/list/19037.java#99463

http://www.guj.com.br/posts/list/30/19037.java#100341

http://www.guj.com.br/posts/list/30/19037.java#100347

[]s
Luca

Olá

Isto funciona

Isto só dá dor de cabeça

Neste caso use a solução de Login do Tiago Monteiro

[]s
Luca

Então, só que a idéia de usuário logado complica…

Por ex, eu não disse que os sistemas estão acessando o msm banco, as vezes eles não estão a propósito!

Além do mais, mesmo que estivessem, isso não travaria abrir dois programas na msma máquina mas sim abrir dois programas pelo mesmo usuário!

Ai o peão abre um com cada usuário na mesma máquina e ferra todo meu controle… :cry:

Será que não tem nenhuma outra forma? Não tem como eu capturar quais programas estão rodando na máquina? Puxa, se em delphi dava será que java não tem? Não pode ser!

Grata

Outra sugestão seria ter um procedimento nos programas q ao iniciar, deve"varrer" a lista de processos que estão sendo executados no momento.
Nesse loop verificaria se determinado programa (A,B,ou C) já estão no ar…
Se sim encerra o processo, se não continua a execução…
Abraços

[quote=ckitano]Outra sugestão seria ter um procedimento nos programas q ao iniciar, deve"varrer" a lista de processos que estão sendo executados no momento.
Nesse loop verificaria se determinado programa (A,B,ou C) já estão no ar…
Se sim encerra o processo, se não continua a execução…
Abraços[/quote]

Era exatamente isso que eu queria!
Mas não sei como fazer em java, e muito menos como fazer pra windows e linux (tenho que ter essas duas opções).

Alguém me dá uma pista?!

Olá

[quote=ckitano]Outra sugestão seria ter um procedimento nos programas q ao iniciar, deve"varrer" a lista de processos que estão sendo executados no momento.
Nesse loop verificaria se determinado programa (A,B,ou C) já estão no ar…
Se sim encerra o processo, se não continua a execução…
Abraços[/quote]

Isto não é bom no caso dos programas A, B e C serem em Java. Primeiro porque precisa usar JNI + C/C++ para acessar a lista de processos se usar Windows. Depois porque um programa Java não aparece na lista de modo facilmente reconhecível.

É importante lembrar que a solução precisa tratar o caso de uma das aplicações ser abortada prematuramente. Portanto não adianta usar soluções que dependam da aplicação tomar alguma atitude ao encerrar. Portanto, caso seja criado um login, é preciso de tempos em tempos confirmar o login por debaixo dos panos para que possa ser considerado expirado caso sem confirmação por algum tempo e assim permitir reabrir em caso de aplicaçãp abortada.

[]s
Luca

Olá…pesquisando um pouco achei isso:
http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jps.html
Nunca utilizei, mais na teoria lista os processos java que estao sendo executados…
Alguem já utilizou e sabe se pode ser utilizado nesse caso?
[]´s

Olá

Mas é claro que no login você armazenaria o Mac Address (só o IP não serve). Mas de qualquer maneira precisaria de um thread ficar revalidando o login a cada 5 segundos por exemplo. Assim, em caso de travamento, o login seria liberado por timeout.

[]s
Luca

ola amigos,

no linux, vc podeira dar um ps | grep alguma coisa e ver se os processos estao rodado.
Uma solucao tb, nao sei se é a + elegante, é usar um objeto singleton como controle,
tomando cuidado com questoes de sincronizacao. Aí, uma app só poderia startar
se possuir o controle desse objeto.

abraços

Olá

Sim, depois basta fazer parse no resultado. Mas é como eu disse, nem sempre os processos Java aparecem de forma bem clara.

No Windows também há coisas semelhantes, principalmente para quem usa o PsList do pacote PSTools

Não é dificil fazer isto em C e acessar por JNI como citei em uma mensagem anterior. Até fui rebuscar lá no meu antigo pacote de informações do sistema e vi que com apenas 10 instruções de C se pode acessar às informações do Windows que listam os processos.

[]s
Luca

Particularmente concordo com o luca…
vc nao esta usando nenhum servidor de aplicacao?
se estiver usando jboss ou algo, vc poderia usar algum esquema com JNDI!
isso se os 3 programs forem em java!
vc poderia fazer algum esquema de guardar um objeto la com alguma informacao especifica da maquina…
se ja estiver nao instancia nada!
soh fazer um esquema dai pra quando sair do programa ele faz unbind do objeto no jndi :smiley:
e tem um esquemao pra se o objeto nao responde por um tempo ele faz unbind!
espero ter ajudado!

Você pode fazer o seguinte …

não fi\ para linux por que não tenho como testar agora … mais se precisar posta ai

[code] public boolean isApplicationRunning(String application){
Process process = null;
Pattern pattern = null;
StringBuffer sb = null;
try {
if (((String)System.getProperties().get(“os.name”)).startsWith(“Windows”)){
process = Runtime.getRuntime().exec(“cmd /c taskList”);
pattern = Pattern.compile("[a-zA-Z]+?\.exe");
}else{
// TODO CASE LINUX IMPLEMENT.
}

		InputStream ips = process.getInputStream();
		BufferedReader bfr = new BufferedReader(new InputStreamReader(ips));
		
		String line =  bfr.readLine();
		sb = new StringBuffer();
		while ((line = bfr.readLine()) != null){
			sb.append(line + "\n");
		}
	} catch (IOException e) {
		//TODO : Tratar Exceção
	}
	
	Matcher matcher =  pattern.matcher(sb.toString());
	while(matcher.find()){
		System.out.println(matcher.group()); 
		if (matcher.group().equalsIgnoreCase(application)){
			return true;
		}
	}
	return false; 
}[/code]

Olá

Insisto, se A, B e C são programas Java, listar os processos pode não ajudar em quase nada.

Já usei a solução dos sockets em applets rodando dentro de browser e neste caso, é preciso um cuidado a mais para dar permissão para a applet abrir sockets.

[]s
Luca

Olá,

Se é o que entendi na solução do dipeloco haverá uma inconsistência já que o cmd /c tasklist retornará das as aplicações em execução, porém para cada execução java é aberto um java.exe/javaw.exe então fica díficil saber qual destes processos e a aplicação a ser verificada. É o que sei no momento, se houver como fazer essa checagem peço a gentileza de postarem.

Existe outra ferramenta do próprio java que é a JPS.

Segue método que criei para fazer a verificação:

public static boolean isRunning(String applicationName) {
		try {
			Process process = null;
			process = Runtime.getRuntime().exec("jps -l");
			InputStream ips = process.getInputStream();
			BufferedReader bfr = new BufferedReader(new InputStreamReader(ips));
			String line = null;
			List<String> javaProcesses = new ArrayList<String>();
			while ((line = bfr.readLine()) != null) {
				String []splited = line.split(" ");
				javaProcesses.add(splited[1]);
			}
			Iterator<String> it = javaProcesses.iterator();
			Integer count = 0;
			while (it.hasNext()) {
				if (it.next().equals(applicationName)) {
					count++;
				}
			}
			return count >= 2;
		} catch (IOException e) {
			return false;
		}
	}

Exemplo de uso deste método:

public class Janel extends JFrame {

	public static void main(String[] args) {
		if (isRunning(Janel.class.getName())) {
			System.out.println("Aplicação está em execução");
		} else {
			Janel janel = new Janel();
		}
	}

	
	...implementação
	
}

Espero ter ajudado e por favor se alguém souber de outra solução, compartilhe… heheheh Valeu!!!

Um abraço.

Olá

O que você disse procede. Vários programas java são reconhecidos como … java e não pelo nome da classe com o método Main.

Porém, o JPS citado pelo ckitano reconhece esta classe com o método Main e a solução que você postou está excelente. Eu gostei!

[]s
Luca

Obrigada meninos!!!

Testei por aqui e parece que está tudo como eu precisava! Depois farei novos testes…

Obrigada pela ajuda de TODOS!

Por fim, a solução que foi postada pelo Hendris foi a que chegou no que eu queria.

Vlw!!! :lol:

Olá,

Estou com o mesmo problema da Renata, fui implementar a solução Hendris, mas ele não esta reconhecendo jps como um comando valido. Estou usando o jdk 6

O que pode estar acontecendo, segue o erro que ele me retorna:

java.io.IOException: Cannot run program “jps”: CreateProcess error=2, O sistema não pode encontrar o arquivo especificado at java.lang.ProcessBuilder.start(Unknown Source)