Às vezes, vejo muitos aplicativos, como msn, windows media player etc, que são aplicativos de instância única (quando o usuário executa enquanto o aplicativo está executando, uma nova instância de aplicativo não é criada).
Em C #, eu uso Mutex
classe para isso, mas não sei como fazer isso em Java.
java
single-instance
Fuangwith S.
fonte
fonte
Respostas:
Se eu acreditar neste artigo , por:
Nota: Ahe menciona no comentário que usar
InetAddress.getLocalHost()
pode ser complicado:getLocalHost
: retorno do endereço IP da máquina, vs. resultados reais: retorno127.0.0.1
.Ou você pode usar o
ManagementFactory
objeto. Conforme explicado aqui :JNLP oferece também um
SingleInstanceListener
fonte
InetAddress.getLocalHost()
não funciona como esperado no ambiente DHCP porque o endereço retornado depende de o computador ter acesso à rede. A solução foi abrir a conexão comInetAddress.getByAddress(new byte[] {127, 0, 0, 1});
.InetAddress.getByName(null)
retorna o endereço da interface de loopback. Acho que isso é melhor do que especificar 127.0.0.1 manualmente porque, em teoria, isso também deve funcionar em ambientes somente IPv6.Eu uso o seguinte método no método principal. Este é o método mais simples, mais robusto e menos intrusivo que já vi, então pensei em compartilhá-lo.
fonte
Se o app. tem uma GUI, inicie-o com JWS e use o
SingleInstanceService
.Atualizar
O Java Plug-in (necessário para miniaplicativos e aplicativos JWS) foi descontinuado pela Oracle e removido do JDK. Os fabricantes de navegadores já o removeram de seus navegadores.
Portanto, esta resposta está extinta. Só deixando aqui para avisar as pessoas que olham a documentação antiga.
fonte
Sim, esta é uma resposta realmente decente para o aplicativo de instância única eclipse RCP eclipse abaixo é meu código
em application.java
fonte
Usamos o bloqueio de arquivo para isso (pegue um bloqueio exclusivo em um arquivo mágico no diretório de dados do aplicativo do usuário), mas estamos principalmente interessados em evitar que várias instâncias sejam executadas.
Se você está tentando fazer com que a segunda instância passe argumentos de linha de comando, etc ... para a primeira instância, usar uma conexão de soquete no localhost matará dois coelhos com uma cajadada só. Algoritmo geral:
fonte
Eu encontrei uma solução, uma explicação um pouco caricata, mas ainda funciona na maioria dos casos. Ele usa o arquivo de bloqueio antigo simples para criar coisas, mas em uma visão bastante diferente:
http://javalandscape.blogspot.com/2008/07/single-instance-from-your-application.html
Acho que será uma ajuda para quem tem uma configuração de firewall rígida.
fonte
Você pode usar a biblioteca JUnique. Ele fornece suporte para a execução de aplicativos java de instância única e é de código aberto.
http://www.sauronsoftware.it/projects/junique/
Em segundo plano, ele cria bloqueios de arquivo na pasta% USER_DATA% /. Junique e cria um soquete de servidor em uma porta aleatória para cada appId exclusivo que permite o envio / recebimento de mensagens entre aplicativos java.
fonte
No Windows, você pode usar launch4j .
fonte
Classe ManagementFactory com suporte em J2SE 5.0 ou detalhes posteriores
mas agora eu uso J2SE 1.4 e encontrei este http://audiprimadhanty.wordpress.com/2008/06/30/ensuring-one-instance-of-application-running-at-one-time/, mas nunca testei. O que você acha disso?
fonte
Você pode tentar usar a API de preferências. É independente de plataforma.
fonte
Uma maneira mais genérica de limitar o número de instâncias em uma única máquina, ou mesmo em uma rede inteira, é usar um soquete multicast.
O uso de um soquete multicast permite que você transmita uma mensagem a qualquer quantidade de instâncias do seu aplicativo, algumas das quais podem estar em máquinas fisicamente remotas em uma rede corporativa.
Desta forma, você pode habilitar muitos tipos de configurações, para controlar coisas como
O suporte multicast do Java é via pacote java.net com MulticastSocket e DatagramSocket sendo as principais ferramentas.
Nota : MulticastSocket não garante a entrega de pacotes de dados, então você deve usar uma ferramenta construída em cima de sockets multicast como JGroups . JGroups faz entrega de garantia de todos os dados. É um único arquivo jar, com uma API muito simples.
O JGroups já existe há algum tempo e tem alguns usos impressionantes na indústria, por exemplo, ele sustenta o mecanismo de clustering do JBoss para transmitir dados para todas as instâncias de um cluster.
Para usar JGroups, para limitar o número de instâncias de um aplicativo (em uma máquina ou uma rede, digamos: para o número de licenças que um cliente comprou) é conceitualmente muito simples:
fonte
Você pode abrir um Arquivo Mapeado de Memória e ver se esse arquivo já está ABERTO. se já estiver aberto, você pode retornar do main.
Outra maneira é usar arquivos de bloqueio (prática padrão do Unix). Outra maneira é colocar algo na área de transferência quando o principal for iniciado, após verificar se algo já está na área de transferência.
Caso contrário, você pode abrir um soquete em modo de escuta (ServerSocket). Primeiro tente se conectar ao soquete hte; se você não conseguir se conectar, abra um socket de servidor. se você se conectar, saberá que outra instância já está em execução.
Portanto, praticamente qualquer recurso do sistema pode ser usado para saber que um aplicativo está em execução.
BR, ~ A
fonte
Usei soquetes para isso e dependendo se o aplicativo está no lado do cliente ou no lado do servidor o comportamento é um pouco diferente:
fonte
fonte
EDIT : Em vez de usar esta abordagem WatchService, um thread de timer simples de 1 segundo poderia ser usado para verificar se o indicadorFile.exists (). Exclua-o e coloque o aplicativo em primeiro plano ().
EDIT : Eu gostaria de saber por que isso foi rejeitado. É a melhor solução que já vi até agora. Por exemplo, a abordagem de soquete do servidor falha se outro aplicativo já estiver escutando a porta.
Basta baixar o Microsoft Windows Sysinternals TCPView (ou usar netstat), iniciá-lo, classificar por "Estado", procurar o bloco de linha que diz "LISTENING", escolher um cujo endereço remoto diga o nome do seu computador, coloque essa porta em seu novo-Socket ()-solução. Na minha implementação, posso sempre produzir falhas. E é lógico , porque é a base da abordagem. Ou o que não estou conseguindo sobre como implementar isso?
Por favor, me informe se e como estou errado sobre isso!
Minha opinião - que estou pedindo que você refute se possível - é que os desenvolvedores estão sendo aconselhados a usar uma abordagem no código de produção que falhará em pelo menos 1 dos cerca de 60.000 casos. E se essa visão passa a ser correto, então ele pode absolutamente não ser que a solução apresentada que não tem este problema é downvoted e criticado por sua quantidade de código.
Desvantagens da abordagem de soquete em comparação:
Acabei de ter uma boa ideia de como resolver o problema de comunicação Java de nova instância para instância existente de uma forma que deve funcionar em todos os sistemas. Então, preparei essa aula em cerca de duas horas. Funciona como um encanto: D
É baseado na abordagem de bloqueio de arquivo de Robert (também nesta página), que usei desde então. Para informar à instância já em execução que outra instância tentou iniciar (mas não o fez) ... um arquivo é criado e imediatamente excluído, e a primeira instância usa o WatchService para detectar a alteração do conteúdo da pasta. Não acredito que aparentemente esta seja uma ideia nova, dado o quão fundamental é o problema.
Isso pode ser facilmente alterado para apenas criar e não excluir o arquivo e, em seguida, informações podem ser colocadas nele para que a instância adequada possa avaliar, por exemplo, os argumentos da linha de comando - e a instância adequada pode então executar a exclusão. Pessoalmente, eu só precisava saber quando restaurar a janela do meu aplicativo e enviá-la para frente.
Exemplo de uso:
Aqui está a aula:
fonte
new ServerSocket()
com um bloco de captura é bastante adequado,A biblioteca Unique4j pode ser usada para executar uma única instância de um aplicativo Java e transmitir mensagens. Você pode vê-lo em https://github.com/prat-man/unique4j . Suporta Java 1.6+.
Ele usa uma combinação de bloqueios de arquivo e bloqueios de porta dinâmica para detectar e se comunicar entre as instâncias com o objetivo principal de permitir que apenas uma instância seja executada.
A seguir está um exemplo simples do mesmo:
Aviso Legal: Eu criei e mantenho a biblioteca Unique4j.
fonte