Bom dia,
Tenho um programa aqui que serve como editor de fichas de RPG (feito em Java, usando Swing). O negocio é o seguinte, eu queria simplificar ele, pra isso eu gostaria de simular um comportamento igual de alguns programas, quando você da dois cliques em um .doc por exemplo, ele já abre o editor de texto com o seu arquivo pronto para ser editado.
O problema é que pra fazer isso no meu programa, seria necessario bloquear a execução do mesmo jar duas vezes, ou seja, cada jar poderia ser executado apenas uma vez. Em minhas pesquisas eu vi um projeto chamado Prionace (aqui no guj mesmo) que faz algo parecido com isso, ele cria uma conexão por Socket, e sempre que é executado verifica se essa conexão existe, se existir, significa que o programa já está em execução, então bloqueia e o programa termina, se não existir ele prossegue normalmente. A diferença é que é uma execução para o Prionace, independente de quantos jars existam do prionace.
O problema é que eu preciso que seja permitido mais de uma execução se for por Jar diferente, por exemplo:
eu baixo o jar com o nome de ficha1.jar e executo, depois tento executar ficha1.jar de novo, isso deveria causar o erro “ficha1 já está em execução”
mas se eu baixo o ficha1.jar, copio e colo como ficha2.jar e tento executar ambos, não há mensagem de erro.
alguem tem alguma sugestão? não sei se adianta alguma coisa, mas pretendo usar um Banco de dados embarcado.
ps.: vale lembrar q n to pedindo código pronto, apenas uma direção a seguir pq n to conseguindo pensar em nada que funcionaria…
eu tinha pensado em algo com um arquivo, mas descartei a ideia pq achei que não houvesse jeito de saber o nome do arquivo jar que está sendo executado, já que pro SO é a JVM que está sendo executada. Mas vou pesquisar melhor como fazer isso então. Muito obrigado.
se eu entendi o que voce quis dizer não pode não, pq pode ter /root/ficha1.jar e /root/ficha2.jar por exemplo, apesar de estarem no mesmo diretorio tem o nome diferente e podem ser executados ao mesmo tempo.
Acho que o que o drsmachado sugeriu, é você - ao executar o jar - verificar se existe um arquivo no diretório de execução chamado por exemplo meujar.txt…
Se não houver, tudo bem, cria um arquivo deste e executa normalmente. Seria a primeira instancia do teu programa a rodar.
Se tentasse rodar novamente o programa, na verificação inicial ele encontraria o arquivo de texto, e então fecharia automaticamente…
O problema maior é começar a desenvolver sem planejar. Isso já deveria ter sido pensado antes de desenvolver o sistema.
Se você fizer uma pesquisa no google, verá que há formas de se identificar o jar onde o arquivo está empacotado.
E, quanto ao problema de existir dois jars dentro do mesmo diretório, você irá criar um arquivo por jar. Além do mais, existem outras formas de validar, como a data, por exemplo. Você está vendo a situação por uma ótica muito reduzida.
[quote=drsmachado]Crie um arquivo txt com o nome do jar. Caso, ao tentar ler, ele exista, invoque a saída do sistema. Se ele não existir, prossiga.[/quote]+1
Defina um padrão de nome de arquivo: processo_rodando.txt
Se o arquivo existir, está sendo executado.
Ou então, dentro desse arquivo coloque algo como
processo_ativo=true
[quote=drsmachado]O problema maior é começar a desenvolver sem planejar. Isso já deveria ter sido pensado antes de desenvolver o sistema.[/quote]Pois é…
Triste isso. =/
realmente não houve planejamento, este é um projeto que comecei assim que aprendi a fazer um hello world, eu ia usando ele pra praticar enquanto estava aprendendo, acabou que ele cresceu, se tornou um monstro feioso mas que tinha alguma utilidade, hj depois de muito tempo, estou refatorando e “limpando” bastante coisa.
Mas e se o projeto estivesse começando do zero e este fosse um requisito, o que vocês recomendariam? O uso do arquivo mesmo?
bem, a solução a que cheguei por enquanto foi serializar uma List de Strings que é sempre utilizada pelos programas, está funcionando perfeitamente. O problema que estou enfrentando agora é o que douglaskd disse, ainda n cheguei a uma solução e não entendi como o link postado poderia ser aplicado ao meu caso, pelo que li, aquilo lá serve pra “travar” o arquivo, sinalizando pra outros processos que o arquivo já está sendo usado…
Vou deixar o código que escrevi aqui, se alguem tiver alguma sugestão/critica/opinião e quiser falar…
Documentação: A file-lock object is initially valid. It remains valid until the lock is released by invoking the release method, by closing the channel that was used to acquire it, or by the termination of the Java virtual machine, whichever comes first. The validity of a lock may be tested by invoking its isValid method.
usando esta lógica, basicamente o funcionamento seria esse:
esse código vai no construtor do Jframe principal/ ou no main() do seu aplicativo:
[code]String pathArquivoFlag = “”; //insira aqui o path do arquivo, ou tente encontrar uma maneira de descobrir o path
try {
File file = new File(pathArquivoFlag);
FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
FileLock lock;
//tenta o lock, se arquivo estiver bloqueado cai na exception
try {
lock = channel.tryLock(0,10,false);
} catch (OverlappingFileLockException e) {
//como o arquivo esta bloqueado, significa que outra instancia igual a esta deu lock no arquivo e esta aberta então sair da aplicação
System.exit(0);
}
//se chegou até aqui quer dizer que esta é a unica instancia aberta e esta com lock no arquivo, qualquer outra que tentar ser executada será automaticamente fechada.
} catch (Exception e) {
//exceptions adicionais, debugue seu código
}[/code]
não testei esse código, então provavel que tenha algum erro, mas acho que ajuda.