Como impedir q o programa seja aberto + de 1 vez?

como eu faco pra o meu software soh abrir 1 vez?? tipo, qdo ele ja estiver aberto, c tenta abri ele d novo ele soh recebe focus (como o MSN)

Olá

Crie um ServerSocket com uma porta qualquer (diferente de zero) que seu programa tenha permissão de acessar. Na primeira vez funciona, nas demais dá IOException.

[]s
Luca

Meio gambiarra mas funciona :wink:

Use arquivos com ou sem filelocking.

vc tb pode colocar um ponto na tela quando o programa abrir, dai se o programa abrir e ver q o ponto ta lá dai o programa naum abre. hehehehe

Pultz… a solução do Luca é muito boa! Vou me lembrar dela que, com certeza, um dia será útil!

é mas se por acaso a porta já estiver sendo usado por algum outro programa (o cara tb tem q ter muito azar heim)

n entendi…

Olá

Louds, se vc lembrar já discutimos longamente este tema e as possíveis desvantagens de usar arquivos. Só vou lembrar que no sistema em que usamos ServerSocket antes usávamos arquivos (sem java.nio e portanto sem locking) e deixamos de usar porque em caso de pane no sistema os arquivos davam encrenca. Com sockets nunca deu problema. Mas com java.nio seria possível adotar file locking.

[]s
Luca

Acho q ele quis dizer pra criar um arquivo e abri-lo com o programa, dai se o outra instância do programa tentar abrir o arquivo vai dizer que o arquivo está berto e vc pode tratar isso para naum abrir o programa.

Ou talvez para quando o programa for carregado ver no proprio programa para ver se ele está sendo usado, mas ai eu naum sei se sempre quando ele for abrir ele vai estar sendo usado(porq vai)

naum entendeu? vai comer uma pizza

Na verdade tanto arquivos (com filelocking) e sockets tem problemas.

Bloquear a execução caso a criação de um arquivo falhe pode dar problema se o teu programa travar e o arquivo não for apagado.

Usar filelocking tem o problema de que o arquivo pode ser recriado dependendo da plataforma e o locking ir pro vinagre. Com locking se o programa ou o sistema falharem o lock acaba.

ServerSockets tem o problema de port lingering, quando o SO não permite reutilizar por um período.

Ou seja, não existe opção portavel em java que seja 100%. Mas server sockets e filelocking resolvem na maioria dos casos.

Quem dera java tivesse suporte a primitivas de IPC, como named pipes/mutexes.

usa um Singleton para instanciar seu programa

O jeito mais confiável de fazer isso é seguir a sugestão do louds e ainda seguir um protocolo para verificar se o aplicativo está de pé. Por exemplo, a aplicação deveria escutar neste socket para mandar uma String de volta ao chamador que indica que ela está viva. Assim, caso não seja ela que esteja travando a porta, pode-se exibir uma mensagem mais clara para o usuário de que outra aplicação está utilizando a porta.

certo, vcs esclarecam a abordagem 1 q eu fiz, d travar a inicilizacao do programa, mas ng toco no assunte de:

o programa ja esta aberto? entao de foco nele!

nem sei c da pra faze isso :P, mas td bem, e tipo, alguem podia da um exemplo desse ai usando arquivo plz

vlw

Usa singleton ou então properties (menos confiável)

Olá

Wilker, se o programa já está aberto acho que não é possível passar o foco para ele. Provavelmente isto só funciona no Windows.

Da outra vez que defendi aqui a solução do ServerSocket fui obrigado a postar o trecho de código que usamos no Banco Postal para provar que é viável. Ainda bem que desta vez a turma aceitou mais facilmente. Wilker, dê uma pesquisada que vc acha o código.

Michael, dificilmente há a possibilidade de coincidência de portas. Mas pelo que sei Murphy ainda não morreu! Veja solução gambiarrativa no final desta mensagem.

A solução é um ServerSocket mas é claro que se pode também em caso de IOException, abrir um Socket cliente setando setSoLinger(false, 0) para checar se realmente é a nossa aplicação que detem a porta. Esta verificação não poderia ser feita com os lockings.

Louds, com ServerSocket não dá para setar o linger timeout. Então se não abrir o ServerSocket é porque realmente a porta está em uso e se está bloqueda pelo linger timeout, isto não foi feito por nossa aplicação. Para confirmar se é realmente nossa aplicação se pode abrir o Socket cliente para se comunicar com a outra instância.

A solução gambiarrativa depende de a cada falha na tentativa de abrir o ServerSocket, tentar abrir um Socket cliente e ver se abre comunicação com a outra instância de nossa aplicação. Caso se confirme a possibilidade de coincidência de portas pela falha da troca com o Socket cliente, se pode alterar um arquivo de configuração e gravar um número de porta para o qual se conseguiu abrir com sucesso. Ao começar a aplicação se obtem a porta neste arquivo de propriedades.

Grinvon, singleton não funciona porque um novo aplicativo usa uma outra JVM.

Finalmente java.nio.channels.Pipe não serve como alternativa ao ServerSocket porque só funciona na mesma JVM.

PS: linger timeout é o período que a conexão permanece aberta mesmo depois do socket fechado para garantir que todos os dados são transmitidos. Verifique isto com netstat -a

[]s
Luca

1 curtida

[quote=Wilker]certo, vcs esclarecam a abordagem 1 q eu fiz, d travar a inicilizacao do programa, mas ng toco no assunte de:

o programa ja esta aberto? entao de foco nele!

nem sei c da pra faze isso :P, mas td bem, e tipo, alguem podia da um exemplo desse ai usando arquivo plz

vlw[/quote]

Com o ServerSocket dah pra pegar foco facim facim…

VELO

Singleton não evita que uma nova JVM seja iniciada com uma nova instância da sua aplicação :wink:
A saída é fazer com que sua aplicação faça uso exclusivo de um recurso, como o Luca e o Louds falaram.

Louds, perguntinha: com aquela viagem do projeto Barcelona, vai ser possível criar aplicações exclusivas de maneira portável e não-escrota, não?

Daniel, se tiver algum mecanismo de comunicação inter-isolates, sem dúvida. Um IsolateSocket, por exemplo.

Luca, o linger que eu me referi é ao fato da operação de port binding ter um timeout de 120 segundos na maioria dos unix. Por isso que client sockets pegam uma porta disponivel qualquer.

Mas para o caso do Wilker, a solução do Luca, junto com a “gambiarra” que ele propos, é melhor. Uma vez que o aplicativo pode alem de abrir um server socket aceitar conexões para saber que tem que ganhar foco.

[quote=Wilker]certo, vcs esclarecam a abordagem 1 q eu fiz, d travar a inicilizacao do programa, mas ng toco no assunte de:

o programa ja esta aberto? entao de foco nele!
[/quote]

Simples. Se você seguiu minha sugestão do protocolo, depois que sua aplicação “provar” que é ela que está aberta, envie um outro comando via socket que seja interpretado como uma instrução para que a janela atual ganhe foco.