Saber se Minha aplicação/jar já está rodando

13 respostas
E

Tem como eu saber se minha aplicação Swing já está rodando na maquina.

No caso eu queria impedir que o cara abrisse mais de uma vez meu programa na mesma máquina

13 Respostas

L

Olá

Procure aqui no GUJ. A minha solução é abrir um socket com determinada porta. Uma 2a tentativa terá sucesso. Eu até já postei um código completo.

[]s
Luca

P

Alguém tem esse exemplo usando Socket, tinha feito o controle usando um arquivo mas tive sérios problemas.

C

Nao tem muito o que exemplificar:

  • Abra um socket listener numa porta qualquer
  • Ao iniciar a aplicacao, verifique se tem alguem escutando naquela porta (tente conectar la)

:slight_smile:

P

Predrosa,

Vc. poderia descrever seus “Sérios Problemas” ?
Em princípio, o uso de um arquivo tem até a ventagem em relação ao método do socket de não permitir a exclusividade por usuário, e não global.

A seqüência correta para implementar um lock é :

  1. Criar arquivo temporário no mesmo diretório do arquivo de lock
  2. Tentar renomear o arquivo temporário para o arquivo de lock,
  3. Se o rename falhar, o arquivo de lock já existe

Problema adicional a ser resolvido: Se a aplicação morrer via kill, o arquivo de lock fica para trás. Solução: Usar o “evitor pattern”: Sua aplicação deve manter o lock “fresco”, atualizando seu conteúdo de tempos em tempos. Outros processos podem determinar que o processo que criou o lock morreu olhando a data de alteração do arquivo.

P

Então cara, meus sérios problemas ocorriam pois quando eu iniciava a aplicação criava um arquivo local e deletava ao fechar a aplicação mas a mesma quando era fechada por ctrl + alt + del não deletava o arquivo, o processo falhava.

Ao chamar a classe inicial eu perguntava existe o arquivo, caso retorna-se true eu fechava, mas achei interessante esse seu esquema, poderia dar mais detalhes com exemplos?

cv, consigo abrir uma socket mais como saber se alguém esta escutando essa porta?

P

Sua abordagem inicial tinha dois problemas:

  1. O que vc. viu, ou seja, se houver crash na máquina o arquivo de lock não será removido.

  2. Existe a possibilidade de uma “corrida” entre duas instâncias disparadas simultaneamente. A seqüência testa-se-existe-se-não-existir-roda é o caso típico para o qual foi criada a instrução TAS(test-and-set) nas CPUs… Vc. precisa executar esta seqüência de forma atômica, algo que o Java não vai te dar no contexto inter-processos. Por outro lado, a operação de rename de um arquivo é atômica e, em plataforma (win)dos, falha quando o arquivo destino já existe.

Para o evitor, use o método "setLastModified em um Timer.

Última coisa, se for usar o Socket, é só tentar criar um ServerSocket em uma porta conhecida. Se vc. conseguir criar o socket, então não havia ninguem ativo. Caso contrário já havia alguem a ouvir.

C

Tenta abrir uma conexao nela, uai!

P

O que preciso adaptar nesse método:

import java.io.IOException;
import java.net.ServerSocket;

/**
 * @author fabio.pedrosa
 * 
 */
public class ControlaAbertura {

	public static synchronized boolean isOpen() {
		ServerSocket serv = null;
		
		//Declaro a Stream de saida de dados
		try {
			//Cria o socket com o recurso desejado na porta especificada
			serv = new ServerSocket(7000);
			return true;
	
			//Trata possíveis exceções
		} catch (IOException e) {
			System.out.println("Algum problema ocorreu ao criar ou enviar dados pelo socket.");
			return false;
		} finally {
			try {
				//Encerra o socket cliente
				if(serv!=null){
					serv.close();
				}	
							} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		System.out.println("isOpen " + isOpen());
	}

No construtor da tela inicial da minha aplicação eu chamo esse método, mas não esta funcionando, esta sempre retornando true.

P

Alguma sugestão?

C

Voce nao esta mandando o ServerSocket escutar. Da uma lida no javadoc ou em algum exemplo por ai :wink:

P

Olhei o javadoc e não achei, alguém pode me ajudar, qual método devo usar para saber se uma porta do Socket esta sendo usada, o meu código sempre retorna true.

public class ControlaAbertura {

	public static synchronized boolean isOpen() {
		ServerSocket serv = null;
		
		//Declaro a Stream de saida de dados
		try {
			//Cria o socket com o recurso desejado na porta especificada
			serv = new ServerSocket(7000);
			System.out.println("ISBOUND " + serv.isBound());
			System.out.println("getSoTimeout " + serv.getSoTimeout());
			System.out.println("getLocalPort " + serv.getLocalPort());
			System.out.println("getReuseAddress " + serv.getReuseAddress());
			return true;
	
			//Trata possíveis exceções
		} catch (IOException e) {
			System.out.println("Algum problema ocorreu ao criar ou enviar dados pelo socket.");
			return false;
		} finally {
			try {
				//Encerra o socket cliente
				if(serv!=null){
					System.out.println("serv !=NULL");
					serv.close();
				}	
				//return false;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		System.out.println("isOpen " + isOpen());
	}
}
L

Olá

Como eu já disse, este assunto já foi discutido várias vezes aqui no GUJ e você insiste em não usar as buscas.

Apesar do CV já ter explicado tudo, mesmo assim vou dar mais uma dica:

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

E leia as 3 páginas do tópico

Leia também: http://www.guj.com.br/posts/list/22646.java

[]s
Luca

P

Show Luca, extremamente simples e muito funcional!

Criado 16 de setembro de 2006
Ultima resposta 16 de out. de 2006
Respostas 13
Participantes 5