Newsgroup: it.comp.java
Titolo: Evitare piu istanze di una applicazione java.

Salve a tutti,
Devo evitare che possono essere in esecuzioni piu istanze di una
applicazione java. Ora ho pensato a due metodi: 
1) Un thread che ad intervalli regolari modifica la data di ultima
modifica di un file presente nella cartella del programma (ad esempio
intervallo di 15 secondi). Al momento dell'avvio l'applicazione
controlla la data di questo file: se la differenza con l'ora attuale
di sistema è superiore all'intervallo di tempo allora la nuova istanza
viene creata. 
2) Una socket UDP in ascolto: appena viene creata una nuova 
    istanza essa manda un pacchetto udp sulla porta in ascolto (in
locale). Se viene ricevuta una risposta allora la nuova istanza viene
terminata.
Ora la prima soluzione mi sembra dispendiosa... ogni 15 secondi deve
essere modificato il contenuto di un file... non mi sembra molto
appropriato come metodo. Usare i lock dei file non è consigliabile:
non tutti i sistemi operativi li supportano....
La seconda soluzione mi sembra poco sicura... anche se faccio un
controllo sull'indirizzo del sorgente (controllo che sia l'ip
127.0.0.1) c'è cmq il pericolo che mi facciano flood su quella porta
udp.... e in tal caso l'applicazione sarebbe occupata solo a gestire i
i pacchetti in arrivo. Posso fare in modo che quando vengono ricevuti
troppi pacchetti la socket in ascolto venga chiusa... pero cosi nn
potrei evitare la creazione di nuove istanze dell'applicazione.
Qualcuno ha qualche soluzione alternativa? di certo tale problema è
gia stato affrontato... (ho visto un post un po di tempo fa ma nn se
ne parlava approfonditamente). 
Grazie per l'attenzione.

Non sono sicuro di aver capito bene il tuo post. Per avere un'istanza sola
di una classe c'è un metodo semplice, un pattern di cui non ricordo il
nome. Ecco lo schema generale.
class A{
private A a=null;
static public A instance(){
 if (a==null)
  a = new A();
 return a;
}
private A(){
 // crea la classe.
}
}
Per accedere alla classe devi usare A.instance(), dove instance è un metodo
statico della classe A, ovvero lo puoi invocare senza avere una instanza
della classe. Istance non fa altro che controllare se la classe è già stata
istanziata. Se non lo è crea una classe, altrimenti ritorna un riferimento
alla classe creata prima. Per creare la classe, istance invoca il
costruttore. Osserva bene che il costruttore della classe A è dichiarato
privato, così l'unico modo per creare istanze di A è attraverso il metodo
istance.
Le tue soluzioni hanno problemi di concorrenza. Supponi di avere due thread
T1 e T2. T1 invoca il costruttore della classe A, il costruttore esegue il
controllo che ha esito negativo (nessuna istanza già creata). Tuttavia la
risposta impiega del tempo a tornare al thread T1, nel frattempo il thread
T2 ha già creato la classe A ed hai due classi di cui vuoi avere solo
un'istanza.
ciao
Marco

On Thu, 25 Nov 2004 20:19:14 +0100, Marco <ma...@NOSPAMPLZ.it> wrote:
Ho chiesto istanza di una applicazione... non di classi. Voglio fare
in modo che se apro una certa applicazione la stessa non consenta
l'avvio di un altra sua copia (istanza).
Insomma: se ho un programma A in esecuzione non voglio che clicckando
di nuovo sul file jar corrispondente si apra un altra copia di A. 
Ti ringrazio lo stesso.. forse sono stato io poco chiaro.

 applicazione java. Ora ho pensato a due metodi: 
public static void main(String argv[]) {
File lockFile;
lockFile = new File("/some/path/lock");
if(!lockFile.createNewFile()) {
   System.out.println("Acc... occupato!");
   return;
}
lockFile.deleteOnExit();
...
}



Il delete on exit funziona solo nel caso in cui il programma termini
correttamente.... se non viene gestita una interruzione critica il
programma si interrompe senza eliminare il file creato... 
Se questo č poco probabile (si devo catturare le eccezioni e
controllare bene il codice... ma č praticamente impossibile prevedere
tutto... ), allora basta pensare al caso in cui manchi la corrente o
il computer si spenga di colpo: al prossimo riavvio nn si potrebbe piu
riaprire l'applicazione... appunto per questo ho pensato di aggiornare
il file ogni 15 secondi (o di piu anche). 
Ti ringrazio cmq per l'aiuto... 
Ciao 

 il file ogni 15 secondi (o di piu anche). 
Meglio a questo punto mettere il file di lock in una locazione che viene 
ripulita allo startup della macchina.
Oppure, se vuoi essere più realista del re, tieni aperto il file per 
tutta la durata del programma. La seconda istanza che tenterà di fare la 
stessa cosa ovviamente non ci riesce.



Grazie!!!!
A questa soluzione (per quanto semplice) non avevo pensato...
Posso creare semplicemente il file ad ogni avvio della applicazione..
e tenerlo aperto. In questo modo se cerco di crearlo di nuovo in un
altra istanza viene generata una eccezione... se invece la macchina si
riavvia nn ci dovrebbero essere problemi.... il file viene
semplicemente sovrascritto....
Grazie dell'aiuto.
PS: per quanto riguarda errori critici a runtime.. si questo è vero...
fin ora il programma è rimasto attivo per una settimana (giorno e
notte) senza alcun problema di sorta... ovvio che come test non è
sufficiente ma è meglio cercare di prevedere il piu possibile i
probabili problemi no? :-)

DamageInc wrote:

Ops... scusa... ho letto male... colpa mia, volevo sbanfare le mie
conoscenze di Software Engineering... eppure odio quella disciplina!
Per quello che dici tu, non saprei... hai pensato ad una soluzione
server-client? Usi un applicazione server che ha il compito di
"distribuire" l'applicazione. Il server ha il controllo su quante istanze
dell'applicazione ci sono in giro. 
ciao
Marco



E' la seconda soluzione che ho inserito nel mio post precedente... con
la differenza che la singola applicazione di per se fa da server ad
altre richieste di istanza... cmq questa soluzione l'ho scartata per
sicurezza... Mi ha indicato una soluzione piu semplice vincent vega...
Grazie lo stesso 
Ciao