Impedir que se abra o aplicativo que já estyiver em execução

Olá

JNI para abrir um socket com a própria máquina?

[]s
Luca

No caso de mais de um aplicativo aberto, as IDEs java, cito NetBeans e Eclipse, utilizam arquiuvos de lock.
O Eclipse exige que tenha-se que exluir o arquivo caso haja uma saida inexperada do sistema. O NetBeans, avisa que o sistema esta aberto, ou sofreu uma saida repentina e pergunta se deseja realemente continuar (ele então exclui o arquivo e cria novamente).

[]'s

[quote=Luca]Olá

JNI para abrir um socket com a própria máquina?

[]s
Luca[/quote]

Usar JNI pra fazer algum tipo de trava em memoria RAM… tipo gravar um arquivo na RAM ao inves do HD…

Sei lah, deve dar, o duro é como :frowning:

VELO

Se o Eclipse e o NetBeans usam file locking, use vc também. O hmichel já deu uma ótima referência.

Gravar em MP? Dois processos? Memória compartilhada. A complexidade é mil vezes maior que abrir um socket.

File locking é usado em muitos lugares, existem milhares de textos sobre o tema.

[]s

[quote=pcalcado]Gravar em MP? Dois processos? Memória compartilhada. A complexidade é mil vezes maior que abrir um socket.

File locking é usado em muitos lugares, existem milhares de textos sobre o tema.

[]s[/quote]

Mas que era uma API massa, isso eh. Poh, se tivesse um JAR prontinho pra isso fica facil :smiley: :lol:

Não entendi:

O que exatamente você ia ganhar nesse método que valesse a pena perder a portabildiade e apelar pra JNI?

[quote=pcalcado]Não entendi:

O que exatamente você ia ganhar nesse método que valesse a pena perder a portabildiade e apelar pra JNI?[/quote]

Ah, um lock em memória RAM é mais transparente que um lock em disco. Se faltar luz e o cara tiver aquele desligamento súbito, quando ligar o PC denovo o programa não vai estar travado.

Quando você fala de um usuario mais experimentado, uma janelinha avisando do problema resolve, se bobiar o cara nem vai esperar a janelinha, vai direto na pasta e vai apagar o lock, agora, quando você fala de um manipulador de mouse, vixi, se aparecer qualquer coisa diferente do normal ele jah liga pro help desk.

Bom, jah vi gente “chamando” por ajuda pq os botões F + 1 não abria o help. Ou seja, pedindo ajuda pra achar um botão no teclado.

Mas todos casos toh começando a estudar JNI (comecei a ler um pouco ontem :D), se eu aprender como fazer ajudo :smiley:

Olá

Por isso sugiro usar sockets ao invés de locks de arquivos. O fato das IDEs usarem não significa que é a melhor solução, significa apenas que elas usam um monte de arquivos e que simplesmente podem fazer lock de algum. Criar um arquivo especialmente para lock foi a fonte dos problemas que nos fez migrar para sockets.

Não entendo como alguém pode achar lock de arquivos ou elocubrações dependentes da arquitetura do sist. operacional mais simples do que tentar abrir um socket com uma porta > 1024 e verificar se dá exceção.

[]s
Luca

concordo com o Luca, sockets parece bem simples, e a galera ja ta inventando moda demais :slight_smile:

Ainda bem que não puseram isso (checar se o programa já está rodando) como uma API do Java.
Pelo que acho, provavelmente eles iriam usar um lock de arquivos, e isso ia dar esses problemas que foram apontados. (Isso ocorre com o java.util.logging, que usa um lock, e sempre dá problemas. Por isso é que uso o tal do log4j mesmo.)
O grande problema é que normalmente quando existe um recurso no Java padrão (como o java.util.logging), muitas empresas requerem que se use esse recurso, mesmo que saibamos que ele "está com problemas’ e você saiba que seria melhor usar algo mais usado mas não exatamente padrão (como o log4j, que é um padrão “de fato”.)

Provavelmente ia dar alguns problemas como a nova API “isReachable” que é uma forma de você determinar se um determinado host está no ar. Ela tenta usar ICMP ECHO e se não conseguir tenta usar ECHO (UDP ou TCP). Sempre tem alguém que esbarra em algum problema nessa API.

A solucao do Luca eh genial. As IDEs deveriam eh fazer isso ao inves de usar file locks. Outra vantagem eh que vc pode usar o socket pra alguma comunicacaozinha (do tipo “quando o usuario clicar no icone da aplicacao e ela ja estiver aberta, mande um ‘ping’ pra porta e caso a app ja esteja aberta, ela toma foco, ou pisca na barra de tarefas, pra atrair a atencao do usuario ao fato de que ele ja tem a app aberta”).

Olá

Nada como receber um elogio mas na verdade a solução não foi escrita por mim, apenas participei das idéias. Detalhando mais ela fica assim:

Na inicialização da sua aplicação faça o seguinte teste (repare que se isLocked retorna true é porque já está travada por outro):

//import AppLock;

.  .  .  .  .  .  .  .  .  .  .

AppLock appLock = null;
// port é qq número acima de 1024, de preferencia leia em um arq. de properties
int port = 44444;  

if ( AppLock.isLocked(port ) ) {
        JOptionPane.showMessageDialog(null,  "Aplicação já aberta", "ERRO", JOptionPane.ERROR_MESSAGE);
        System.exit(1);
} else {
        // Aplicação livre, vamos trava-la
        appLock = new AppLock(port);
        try {
                appLock.lock();
        } catch (IOException ioex) {
                ioex.printStackTrace();
        }
}

.  .  .  .  .  .  .  .  .  .  .

E crie uma classe AppLock tal como abaixo:

[code]
import java.io.IOException;
import java.net.ServerSocket;

public class AppLock {

int port ;
ServerSocket serverSocket ;

// ------------------------------------------------------------------
public AppLock(int lockport) {
port = lockport;
}

// ------------------------------------------------------------------
public void lock() throws IOException {
serverSocket = new ServerSocket(port);
}

// ------------------------------------------------------------------
public void unlock() {
try {
serverSocket.close();
} catch (IOException ioex) {
}
}

// ------------------------------------------------------------------
public static boolean isLocked(int lockport) {
boolean retorno = false;
try {
ServerSocket ss = new ServerSocket(lockport);
ss.close();
} catch (IOException ioex) {
retorno = true;
}
return retorno;
}

}[/code]

[]s
Luca

public static boolean isLocked(int lockport) { boolean retorno = false; try { ServerSocket ss = new ServerSocket(lockport); ss.close(); } catch (IOException ioex) { retorno = true; } return retorno; }

Mas aqui você abre o SocketServer e em seguida o fecha, certo?
Isso não liberaria a porta novamente?

Olá

Repare no seguinte: primeiro preciso testar se já está travado. Então tento abrir o ServerSocket. Caso tenha sucesso, preciso fecha-lo para depois mais adiante realmente abri-lo. Isto foi feito assim, é claro que pode ser modificado se alguém quiser fazer o travamento DENTRO do método booleano isLocked de verificação de travamento. Ficou assim por questões de lógica e não de performance.

[]s
Luca

Ah tá! Achei que já estava sem entender nada.

Olá

E receber minha completa desaprovação pois como afirmei nas mensagens que postei aqui e como repeti claramente em mensagens privadas, o código que postei aqui tem dono, faz parte de um projeto profissional, eu não tinha autorização para coloca-lo aqui mas coloquei com o intuito de ajudar aos colegas.

Em mensagem privada ao Velo afirmei que como eu coloquei aqui no GUJ ele podia adaptar em seus projetos mas sem publicar. E publicar como API no java.net é sacanagem.

Acho que depois desta não coloco mais código nenhum aqui.

[]s
Luca

sacanagem. isso é malvadesa! :evil:
mas Luca você sabia que estaria se expondo a isso…
e velo o cara pediu via pm pra que nao publicasse [apesar de ele ter publicado] muita sacanagem… :?