[Risolto] Intercettare istanza del programma già in esecuzione

di il
24 risposte

24 Risposte - Pagina 2

  • Re: [Risolto] Intercettare istanza del programma già in esecuzione

    Chiarissimo. Grazie mille.
    Probabilmente non mi sono accorto dell'inconveniente, perché la più grande tabella del mio db contiene circa 5000 record di soli puntatori di relazione, e le query, per ora, non sono molto complesse, quindi i tempi di esecuzione sono pressoché istantanei.
    Ma a questo punto, mi hai messo la famosa "pulce" nell'altrettanto famoso "orecchio" ... per cui devo assolutamente imparare ad usare il multi-threading, anche perché altrimenti non risolvo il mio problema di questa discussione ...

    EDIT: Correggo, i record della tabella più grande sono quasi 10000 ... ma la sostanza non cambia.
  • Re: [Risolto] Intercettare istanza del programma già in esecuzione

    ZioCrick ha scritto:


    per cui devo assolutamente imparare ad usare il multi-threading
    Sì. Parti da tutti i concetti essenziali sulla classe java.lang.Thread e la interfaccia Runnable. Poi vedi i concetti basilari sulla sincronizzazione (qui è già un pelino più difficile) cioè il lock "intrinseco" degli oggetti, la keyword synchronized, il meccanismo di wait/notify sempre intrinseco degli oggetti.
    Poi, riferito a Swing, come far interagire il EDT di Swing con "altri" thread e eventualmente anche la classe SwingWorker di Swing.
  • Re: [Risolto] Intercettare istanza del programma già in esecuzione

    andbin ha scritto:


    EDIT: anzi, è più giusto dire che la seconda istanza cerca di "ascoltare" su quella stessa porta e ovviamente è già in uso, quindi il bind fallisce. Allora può poi connettersi a quella porta per notificare la prima istanza, ad esempio per dirgli di mettersi in primo piano (tanto per dire uno scenario sensato).
    Caro @andbin
    Ti ringrazio di cuore per l'indicazione, perché ho implementato proprio la logica che mi hai descritto!
    Durante questi giorni di forzata assenza di lavoro, ho avuto un po più di tempo per studiare e fare prove e ... dopo guide, tutorial, manuali, esempi trovati sul web, prove, riprove e testate contro il muro (metaforicamente parlando) mi sembra di esserci riuscito!!!
    Dico "sembra" perché durante questo faticoso percorso mi sono capitate cose strane, come il fatto che un giorno, sembrava funzionare e il giorno dopo non partiva nemmeno il programma e non capivo il perché.
    Poi magicamente, dopo aver fatto una modifica apparentemente ininfluente tornava a funzionare ... boh?

    Alla fine con l'uso dei thread e dei socket riesco ad intercettare l'istanza precedente e a portarla in primo piano!

    Mi restano ancora un mucchio di domande senza risposta, sicuramente perché non ho ancora studiato abbastanza.
    La cosa che mi preoccupa di più è che non ho utilizzato alcun tipo di sincronismo, che è un argomento di cui non ancora capito nulla e che tu mi avevi suggerito di utilizzare.
    Mi preoccupa perché non so se potrebbero verificarsi situazioni in cui senza sincronismo il tutto potrebbe bloccarsi.

    Poi non ho capito perché dal lato server per scrivere un messaggio si usa OutputStream con BufferedWriter che spedisce una String, mentre per leggere si usa InputStream che legge un vettore di byte di cui bisogna stabilire la dimensione a priori. E invece nel client bisogna usare DataOutputStream che spedisce una String e bisogna leggere ancora con InputStream che usa il solito vettore di byte?

    Poi resta il mistero del come mai su windows per portare in primo piano l'istanza già in esecuzione è sufficiente la sequenza:
    myForm.setState(JFrame.NORMAL);
    myForm.toFront();
    myForm.requestFocus();
    dove myForm è il JFrame contenitore del programma.
    mentre su Kubuntu devo anteporre:
    myForm.setVisible(false);
    myForm.setVisible(true);
    Non ho ancora fatto le prove per verificare se servono veramente tutte le istruzioni riportate o se ne basterebbero di meno, ma così al momento funziona.

    Per completare l'opera ho altri problemi da risolvere ma sono altri argomenti, per cui almeno questo sembra risolto.
  • Re: [Risolto] Intercettare istanza del programma già in esecuzione

    ZioCrick ha scritto:


    Ti ringrazio di cuore per l'indicazione, perché ho implementato proprio la logica che mi hai descritto!
    Durante questi giorni di forzata assenza di lavoro, ho avuto un po più di tempo per studiare e fare prove e ... dopo guide, tutorial, manuali, esempi trovati sul web, prove, riprove e testate contro il muro (metaforicamente parlando) mi sembra di esserci riuscito!!!
    Per dubbi potevi chiedere ...

    ZioCrick ha scritto:


    Mi restano ancora un mucchio di domande senza risposta, sicuramente perché non ho ancora studiato abbastanza.
    La cosa che mi preoccupa di più è che non ho utilizzato alcun tipo di sincronismo, che è un argomento di cui non ancora capito nulla e che tu mi avevi suggerito di utilizzare.
    Nel tuo caso specifico, l'unica cosa davvero necessaria è che quando sei nel thread che gestisce il socket e vuoi riattivare la finestra semplicemente devi far "passare" tutte le impostazioni sul frame (quelle che hai riportato sotto), nel EDT tramite il "solito" invokeLater.

    ZioCrick ha scritto:


    Mi preoccupa perché non so se potrebbero verificarsi situazioni in cui senza sincronismo il tutto potrebbe bloccarsi.
    Sì possibile ma bisognerebbe vedere esattamente cosa hai scritto.

    ZioCrick ha scritto:


    Poi non ho capito perché dal lato server per scrivere un messaggio si usa OutputStream con BufferedWriter che spedisce una String, mentre per leggere si usa InputStream che legge un vettore di byte di cui bisogna stabilire la dimensione a priori. E invece nel client bisogna usare DataOutputStream che spedisce una String e bisogna leggere ancora con InputStream che usa il solito vettore di byte?
    No allora, detto così vuol dire poco/nulla. I socket (quelli TCP intendo, non i datagram) forniscono uno "stream" di byte puri (quindi InputStream/OutputStream). Poi devi sapere tu quale è il "protocollo" all'interno di questa comunicazione (nel tuo caso te lo inventi tu ...).

    In base a come vengono scambiate le informazioni allora si decide quale/i classe/i di I/O è sensato usare per un certo tipo di comunicazione.

    ZioCrick ha scritto:


    Poi resta il mistero del come mai su windows per portare in primo piano l'istanza già in esecuzione è sufficiente la sequenza:
    Questa è un'altra (bella) questione .... anche critica/non banale. Perché c'entra anche molto come i S.O. gestiscono le finestre.
    Appena ho un po' più di tempo faccio qualche prova anche per "rinfrescarmi" su questi aspetti ...
  • Re: [Risolto] Intercettare istanza del programma già in esecuzione

    andbin ha scritto:


    Per dubbi potevi chiedere ...
    Eh, si ma, siccome mi hai già aiutato altre volte e sei già stato parecchio disponibile e paziente ... c'era solo un pizzico di orgoglio ... che mi ha fatto intestardire.

    andbin ha scritto:


    Nel tuo caso specifico, l'unica cosa davvero necessaria è che quando sei nel thread che gestisce il socket e vuoi riattivare la finestra semplicemente devi far "passare" tutte le impostazioni sul frame (quelle che hai riportato sotto), nel EDT tramite il "solito" invokeLater.
    Ecco, siccome il "solito" invokeLater l'ho visto citato nella documentazione ma non ci capito un gran che, ho tagliato corto (almeno mi è parso) creando una classe che estende SwingWorker con un costruttore a cui ho passato come argomento il JFrame iniziale, e poi nel metodo process ho inserito i comandi di cui sopra.
    Se non è abbastanza ortodosso ... attendo le bastonate ...

    andbin ha scritto:


    Sì possibile ma bisognerebbe vedere esattamente cosa hai scritto.
    Lo mostrerei volentieri ma al momento mi risulta difficile riportare il codice perché non ho ancora un codice pulito, ma ho fatto tante di quelle prove che ho pezzi sparsi e mescolati a roba che non serve, per cui devo fare le pulizie di primavera.

    andbin ha scritto:


    No allora, detto così vuol dire poco/nulla. I socket (quelli TCP intendo, non i datagram) forniscono uno "stream" di byte puri (quindi InputStream/OutputStream). Poi devi sapere tu quale è il "protocollo" all'interno di questa comunicazione (nel tuo caso te lo inventi tu ...).
    Allora ... in pratica durante le mille prove che ho fatto mi è venuta la smania di generalizzare il mio problema e avrei voluto poter far comunicare il client e il server tramite l'interscambio di semplici stringhe a lunghezza variabile, ma non ho capito come fare perché cercando di usare il BufferedReader, che pensavo fosse l'opposto del BufferedWriter il "sergente Netbeans" mi sgridava con degli erroracci che non capivo.

    andbin ha scritto:


    In base a come vengono scambiate le informazioni allora si decide quale/i classe/i di I/O è sensato usare per un certo tipo di comunicazione.
    Ecco, potresti darmi un'imbeccata su cosa dovrei usare per trasmettere e ricevere delle semplici String?
  • Re: [Risolto] Intercettare istanza del programma già in esecuzione

    Mi sa che si e' preso una strada abbastanza strana per risolvere il banale problema di

    Intercettare istanza del programma già in esecuzione

    La soluzione e' ESTREMAMENTE SEMPLICE!

    1) il concetto d "processo" e' un concetto di responsablita' del SISTEMA OPERATIVO. E' il sistema operativo che si occupa di decidere quale sia l processo con interfaccia utente in PRIMO PIANO. Ogni processo ha un suo ID univoco

    2) questo vuol dire che l'applicazione deve interagire con il sistema operativo e per interagire con gli altri processi, deve usare gli ID.

    3) quando l'applicazione in questione parte, salva su file il PROPRIO ID di processo.
    4) quando RIPARTE, controlla se il file e' presente e se e' presente CHIEDE AL SISTEMA OPERATIVO di mettere in primo piano il processo con ID letto nel file. Diciamo che la cosa deve essere UN PO' piu' intelligente, nel senso che il nuovo processo deve leggere l'ID del processo precedente e CONTROLLARE che un processo con quel ID effetivamente esista, perche' il processo precedente potrebbe essere morto di morte violenta

    Ovviamente ci sono sistemi piu' sofisticati e sia WIndows che qualunque altro SO mettono a disposizione primitive che possono essere usate allo scopo.
    Sono chiamati: oggetti di sincronizzazione

    -------------

    I socket sono un meccanismo per far PARLARE due processi. Certamente possono essere usati per capire se un prcesso e' gia' in esecuzione, MA non sono esattamente la soluzione migliore
  • Re: [Risolto] Intercettare istanza del programma già in esecuzione

    migliorabile ha scritto:


    3) quando l'applicazione in questione parte, salva su file il PROPRIO ID di processo.
    4) quando RIPARTE, controlla se il file e' presente [...]
    L'approccio del PID salvato su file è giustissimo e molte applicazioni "native" infatti lo usano. Il punto è che in Java, perlomeno fino a Java 8 compreso, non è mai stato disponibile direttamente il concetto del Process Id. Solo a partire da Java 9, con la nuova Process API, la classe Process ha un bel public long pid()

    Prima di Java 9 si dovrebbero usare altri accrocchi, librerie esterne che sfruttano JNI (Java Native Interface) oppure la libreria JNA o altro. Con tutte le ovvie questioni sulla "portabilità" tra le varie piattaforme.

    Un truschino che ho già visto fare è prendere il name della Virtual Machine in esecuzione usando il MXBean della API di management/monitoring di Java, così:
    String nomeJVM = ManagementFactory.getRuntimeMXBean().getName();
    Dove questo name è qualcosa nella forma nnnn@nomepc (es. 1234@HOMEPC) e quindi si taglia la parte dal @ in poi e la prima parte effettivamente è il PID. Ma non so dire se/quanto sia portabile su altre piattaforme (su Windows 10 funziona come detto).
    E comunque almeno fino a Java 8, anche sapendo un PID non si può sapere se c'è davvero un processo attivo con quel PID (solo con il framework standard).
  • Re: [Risolto] Intercettare istanza del programma già in esecuzione

    migliorabile ha scritto:


    Mi sa che si e' preso una strada abbastanza strana per risolvere il banale problema di
    Ti ringrazio per il tuo contributo, ma tieni conto che io sono super principiante con Java, per cui quello che per un esperto può essere banale per me può diventare una montagna insormontabile.

    migliorabile ha scritto:


    1) il concetto d "processo" e' un concetto di responsabilità' del SISTEMA OPERATIVO. E' il sistema operativo che si occupa di decidere quale sia l processo con interfaccia utente in PRIMO PIANO. Ogni processo ha un suo ID univoco

    2) questo vuol dire che l'applicazione deve interagire con il sistema operativo e per interagire con gli altri processi, deve usare gli ID.

    3) quando l'applicazione in questione parte, salva su file il PROPRIO ID di processo.
    Questa era una possibilità a cui, per logica, avevo pensato anch'io ... ma ...

    migliorabile ha scritto:


    4) quando RIPARTE, controlla se il file e' presente e se e' presente CHIEDE AL SISTEMA OPERATIVO di mettere in primo piano il processo con ID letto nel file . Diciamo che la cosa deve essere UN PO' piu' intelligente, nel senso che il nuovo processo deve leggere l'ID del processo precedente e CONTROLLARE che un processo con quel ID effetivamente esista, perche' il processo precedente potrebbe essere morto di morte violenta
    ... qui nasce il problema ... Come si fa ad eseguire le operazioni che ho evidenziato in grassetto?

    migliorabile ha scritto:


    Ovviamente ci sono sistemi piu' sofisticati e sia WIndows che qualunque altro SO mettono a disposizione primitive che possono essere usate allo scopo.
    Sono chiamati: oggetti di sincronizzazione
    Ecco, per utilizzare questi "oggetti di sincronizzazione" mi sembra, ma dimmi se sbaglio, che bisogna scrivere codice differente a seconda del SO su cui gira l'applicazione.
    Invece io volevo un modo per rendere il funzionamento completamente indipendente dal SO.

    migliorabile ha scritto:


    I socket sono un meccanismo per far PARLARE due processi. Certamente possono essere usati per capire se un prcesso e' gia' in esecuzione, MA non sono esattamente la soluzione migliore
    Ecco, come ho detto prima, volendo evitare di scrivere codice legato al SO, in base alle indicazioni di @andbin, mi è sembrato che i socket e i thread fossero l'unica strada percorribile, ma se ne conosci altre, sono qui per imparare.
    Grazie.
  • Re: [Risolto] Intercettare istanza del programma già in esecuzione

    ZioCrick ha scritto:


    ... qui nasce il problema ... Come si fa ad eseguire le operazioni che ho evidenziato in grassetto?
    Come ho già detto prima, per gestire da Java i processi, enumerarli, conoscere i loro PID, ottenere info sui processi, fare un lookup del PID, ecc... serve almeno Java 9. Fino a Java 8 non si può con il solo framework standard, a meno di ricorrere a librerie esterne che sicuramente fanno invocazioni di funzionalità "native".

    Riguardo il fatto che sia il S.O. (e non l'applicazione) a riattivare una applicazione, in questo momento non ricordo ad esempio se nelle API native di Windows c'è una funzionalità del genere. Se ci fosse ... ok, ma sarebbe comunque un aspetto system-dependent, ovviamente.

    ZioCrick ha scritto:


    Ecco, per utilizzare questi "oggetti di sincronizzazione" mi sembra, ma dimmi se sbaglio, che bisogna scrivere codice differente a seconda del SO su cui gira l'applicazione.
    I sistemi operativi mettono generalmente a disposizione (su Windows sì) meccanismi vari di intercomunicazione/sincronizzazione tra processi, quali mutex, pipes e altro. Ma appunto qui è un terreno impervio perché si tratta di cose MOLTO system-dependent che da Java generalmente non si possono usare direttamente (e ripeto, solo con il framework standard).

    ZioCrick ha scritto:


    Invece io volevo un modo per rendere il funzionamento completamente indipendente dal SO.

    Ecco, come ho detto prima, volendo evitare di scrivere codice legato al SO, in base alle indicazioni di @andbin, mi è sembrato che i socket e i thread fossero l'unica strada percorribile, ma se ne conosci altre, sono qui per imparare.
    Per il momento ti conviene continuare ad usare i socket ... è la soluzione meno impegnativa, almeno per te in questo momento.
  • Re: [Risolto] Intercettare istanza del programma già in esecuzione

    Grazie per le ulteriori indicazioni.

    andbin ha scritto:


    Per il momento ti conviene continuare ad usare i socket ... è la soluzione meno impegnativa, almeno per te in questo momento.
    Sicuramente.

    Ora però ho un altro problema che non so se imputabile al SO o a java.
    Provo ad aprire un'altra discussione.
Devi accedere o registrarti per scrivere nel forum
24 risposte