[RESOLVIDO] Impedir que crie duas instâncias?

É mais ou menos o que se fala nesse post (é, eu sei), mas não entendi bem. Não quero que o usuário consiga abrir um jar enquanto ele estiver em execução, o que posso fazer?

[]'s

Abre um ServerSocket em uma porta de sua escolha. Ai toda vz q iniciar o app verifica se a porta ta em uso.

1 curtida

Eu conheço essa maneira:

Quando o usuário clicar no jar, o sistema verifica se no arquivo confxxx tem a propriedade logado = true, se for true quer dizer que o ele ja esta aberto, se não, não. Ai quando fechar, muda o valor para false

1 curtida

Problema q se o programa for forçado a encerrar por desligamento inesperado ou gerenciador de tarefas (sem alterar a propriedade no arquivo), nunca mais vai abrir.

1 curtida

Ai pode criar uma outra propriedade de controle, que ai dependendo do valor dela você sabe que não foi fechado corretamente

1 curtida

Parece um passo extra. Qual seria a vantagem e desvantagem em relação ao ServerSocket? Obrigado pela resposta!

@Rodrigo_Void em muito me interessa e ajuda sua resposta, obrigado.

[]'s

ServerSocket se torna mais automatico. N precisa ter o arquivo, n precisa implementar leitura e escrida pro arquivo, nem contingencias.
Vc só dá um new ServerSocket(1234);
Faz isso com try/catch, se n der erro qr dizer q é a primeira instancia, se der erro qr dizer q já tm outra instancia rodando. Se a aplicação for finalizada por meios mais “brutos” n terá problema pq a porta deixará d estar em uso.
Já implementei isso a anos atras para este mesmo objetivo.

2 curtidas

Nunca cheguei a usar ServerSocket, vou dar uma googlada em códigos de exemplo para esse caso. Obrigado, meu caro.

[]'s

O legal do ServerSocket é que se você não consegue abrir ele, você sabe que a porta está em uso, provavelmente pela outra instância do seu programa, que conseguiu abrí-lo.
Neste caso você pode abrir um Socket para enviar uma mensagem à primeira instância de seu programa dizendo para ele trazer o foco pra janela do seu sistema, aí nem precisa apresentar mensagem de erro na segunda instância, só encerra ela e pronto.

2 curtidas

Eu nunca mexi com Socket profissionalmente, então não saberia te responder :frowning: mas pelo que o @Rodrigo_Void e o @staroski disseram, o Socket se sai bem melhor nisso, e parando para pensar realmente faz sentido e aparente ser melhor.

:+1:

1 curtida

Não tem a chance de outro programa estar utilizando aquela porta?

Tô muito interessado mas ao mesmo tempo chateado pois nunca trabalhei com ServerSocket, temo não conseguir usar desta forma

Sim, pode. Escolha um número e faça uma pesquisa rápida para ver se tem algum programa q usa.

Se vc conhece java, n sei pq sofrer por antecipação, vc n vai necessariamente usar socket. Vc só vai dar um NEW, e daí se este new for de um obj ServerSocket? Qualquer outra ideia que venha não será mais simples que isso.
Já poderia ter testado, sem pesquisa alguma, o código é literalmente aquilo que falei

try {
new ServerSocket(1234); //escolha sua porta
}catch(Exception e) {
System.exit(0);
}
Faça as personalizações que achar pertinentes. A ideia do @staroski é boa, mas precisará implementar a comunicação com o socket.

Se n tm opção melhor no momento, primeiro vc tenta, depois vc v c foi difícil ou não.

1 curtida

Ah, eu imaginei que teria complicações com esse lance. Semestre passado tive muita dor de cabeça com isso, por isso pensei que seria mais complexo. Mas vou testar. Obrigado galera! :slight_smile:

Exemplo:

import java.awt.Container;
import java.awt.Dimension;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;

public class Exemplo {

    private static final int PORTA = 12345;
    private static final int MENSAGEM = 1;
    private static final int RESPOSTA = 1;

    public static void main(String[] args) throws Throwable {
        Exemplo programa = new Exemplo();
        programa.iniciar();
    }

    private ServerSocket server;
    private JFrame janela;

    public void iniciar() throws Exception {
        if (estaExecutando() && focouJanela()) {
            System.exit(0);
            return;
        }
        criaJanela();
        new Thread(() -> escutaMensagens()).start();
    }

    private boolean estaExecutando() {
        try {
            server = new ServerSocket(PORTA);
            return false;
        } catch (IOException e) {
            return true;
        }
    }

    private boolean focouJanela() throws IOException {
        InetAddress localhost = InetAddress.getLocalHost();
        Socket client = new Socket(localhost, PORTA);
        OutputStream output = client.getOutputStream();
        int mensagem = MENSAGEM;
        output.write(mensagem);
        output.flush();
        InputStream input = client.getInputStream();
        int resposta = input.read();
        client.close();
        if (resposta == RESPOSTA) {
            return true;
        }
        return false;
    }

    private void criaJanela() {
        janela = new JFrame("Meu Programinha");
        janela.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        janela.setMinimumSize(new Dimension(640, 480));
        janela.setLocationRelativeTo(null);
        Container container = janela.getContentPane();
        container.add(new JLabel("Programa executando", SwingConstants.CENTER));
        janela.setVisible(true);
    }

    private void escutaMensagens() {
        while (true) {
            try {
                Socket client = server.accept();
                InputStream input = client.getInputStream();
                int mensagem = input.read();
                if (mensagem == MENSAGEM) {
                    janela.setAlwaysOnTop(true);
                    janela.toFront();
                    janela.setAlwaysOnTop(false);
                    janela.requestFocus();
                    OutputStream output = client.getOutputStream();
                    output.write(RESPOSTA);
                    output.flush();
                }
                client.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
3 curtidas