2009-10-22 12 views
5

È necessario utilizzare onApplicationEnd() come parte di Application.cfc per eseguire una chiamata su un oggetto Java di terze parti per chiudere una connessione a un altro dispositivo sulla rete.onApplicationEnd - CF in realtà si sta spegnendo?

Il codice ho funzionato perfettamente se lo chiamo come una richiesta normale, ma quando lo metto nel metodo onApplicationEnd() sto correndo alcuni errori. Questi errori suggeriscono che CF potrebbe in effetti chiudersi al punto in cui non posso accedere a queste classi Java di terze parti.

Codice:

<cffunction name="onApplicationEnd" returnType="void"> 
    <cfargument name="appScope" required="true" /> 

    <cfset var logLocation = "test" /> 

    <cflog file="#logLocation#" text="*** [Application.cfc] - **** START RUN ****" /> 
    <cflog file="#logLocation#" text="*** [Application.cfc] - #timeformat(now(),'HH:mm:ss')# - onApplicationEnd() called " /> 


    <cftry> 

     <cfif structKeyExists(ARGUMENTS, "appScope")> 
      <cflog file="#logLocation#" text="*** [Application.cfc] - #timeformat(now(),'HH:mm:ss')# - ARGUMENTS.appScope is defined" /> 
     <cfelse> 
      <cflog file="#logLocation#" text="*** [Application.cfc] - #timeformat(now(),'HH:mm:ss')# - ARGUMENTS.appScope is undefined! " /> 
     </cfif> 

     <!--- Check if we have a test crypto object in scope, and if so close it's connection ---> 
     <cfif structKeyExists(ARGUMENTS.appScope, "testCrypto")> 

      <cflog file="#logLocation#" text="*** [Application.cfc] - #timeformat(now(),'HH:mm:ss')# - onApplicationEnd() - crypto object exists in app scope" /> 

      <cfset ARGUMENTS.appScope.testCrypto.closeConnection() /> 
      <<cflog file="#logLocation#" text="*** [Application.cfc] - #timeformat(now(),'HH:mm:ss')# - onApplicationEnd() - closed crypto server connection" /> 

     <cfelse> 
      <cflog file="#logLocation#" text="*** [Application.cfc] - #timeformat(now(),'HH:mm:ss')# - onApplicationEnd() - NO crypto server connection present to close" /> 
     </cfif> 

      <cfcatch type="any"> 

       <cflog file="#logLocation#" text="*** [Application.cfc] - #timeformat(now(),'HH:mm:ss')# - onApplicationEnd() - Error - #cfcatch.message#" /> 

      </cfcatch> 

     </cftry> 
    <cflog file="#logLocation#" text="*** [Application.cfc] - #timeformat(now(),'HH:mm:ss')# - onApplicationEnd() ended " /> 

</cffunction> 

La linea per chiudere la connessione sul mio oggetto sta venendo a mancare con il messaggio: 'java.lang.IllegalStateException: Spegnimento in corso'.

Qui ci sono i log completi per una corsa:

"Information","Thread-8","10/23/09","09:05:54",,"*** [Application.cfc] - **** START RUN 

"Information","Thread-8","10/23/09","09:05:54",,"*** [Application.cfc] - 09:05:54 - onApplicationEnd() called " 

"Information","Thread-8","10/23/09","09:05:54",,"*** [Application.cfc] - 09:05:54 - ARGUMENTS.appScope is defined" 

"Information","Thread-8","10/23/09","09:05:54",,"*** [Application.cfc] - 09:05:54 - onApplicationEnd() - crypto object exists in app scope" 

"Information","Thread-8","10/23/09","09:05:54",,"*** [Application.cfc] - 09:05:54 - onApplicationEnd() - Error - Shutdown in progress" 

"Information","Thread-8","10/23/09","09:05:55",,"*** [Application.cfc] - 09:05:55 - onApplicationEnd() ended " 

c'è restrizioni a quello che posso fare in onApplicationEnd() e se è così c'è qualche lavoro in giro?

Utilizzo la versione per sviluppatori CF 8 (8,0,1,195765) su un computer Windows XP.

Inoltre, se eseguo CF in una finestra della console e preme CTRL-C, viene visualizzato questo, ma vedo anche questo comportamento se eseguo cfstop.

Molte grazie in anticipo!

MODIFICA: alcuni altri hanno riscontrato questo problema here, ma nessuna soluzione.

MODIFICA: esempio di thread rimosso in quanto potrebbe appannare il problema. Codice e log inviati.

risposta

3

Sembra che questo può essere causato dal fatto che il serversi sta spegnendo, piuttosto che l'applicazione CF. Immagino che se la JVM è già in fase di spegnimento, le risorse utilizzate dalla classe java potrebbero non essere disponibili in quel momento. Quindi onApplicationEnd potrebbe non essere il posto giusto per quel codice.

Si potrebbe voler aggiungere un ShutdownHook. Non sono al 100% positivo, ma penso che posizionare il codice di pulizia lì, invece che su onApplicationEnd, possa consentire all'oggetto java di eseguire la sua pulizia prima che la JVM entri nella fase di morte.

Ma dopo aver detto tutto questo, la "connessione a un altro dispositivo sulla rete" non si chiuderà automaticamente una volta che il server si spegne?

+0

Sono d'accordo che questo potrebbe essere il caso e indagherò usando questo hook. Sto usando CF 8, penso che 9 sia integrato in Application.cfc. Per quanto riguarda il tuo ultimo commento: l'intera ragione per cui devo farlo è la mancanza di un arresto regolare della connessione al dispositivo di terze parti. –

+0

@Leigh - Ci scusiamo per il deplay nell'approfondimento di questo, occupato da altre cose. Devo passare una discussione al metodo di hookdowndown. Ho deciso di guardare JavaLoader di Mark Mandel per aiutarmi: http://www.compoundtheory.com/?action=displayPost&ID=422. Immagino di poter creare un CFC che implementa Runnable per passare al metodo hook. Qualsiasi altro suggerimento è benvenuto! –

+0

Dopo un sacco di test e qualche altra discussione qui: http://forums.adobe.com/message/2337930#2337930 Non riesco a trovare un modo che possa essere fatto in modo affidabile. Anche creare un thread e passarlo al hook di runtime del server non va bene, ottengo un'eccezione di puntatore nullo nonostante il thread funzioni correttamente al di fuori dei contesti di arresto del server. Molte grazie per l'aiuto di tutti, sto implementando un work-around per chiamare il codice di spegnimento esplicitamente prima della fine dell'applicazione, ad esempio tramite una normale richiesta. –

2

secondo i documenti "Non è possibile utilizzare questo metodo per visualizzare i dati su una pagina utente, perché non è associato a una richiesta."

Penso che "non sia associato a una richiesta". è la chiave. Potrebbe essere che i tuoi oggetti java esistano solo all'interno del thread di richiesta e non nell'istanza dell'app.

Forse invece shound provare a utilizzare onRequestEnd

http://livedocs.adobe.com/coldfusion/8/AppEvents_09.html

+0

Hm. Mi sembrava che l'oggetto fosse stato creato solo su OnApplicationEnd, e forse stava tentando di accedere ad alcuni dati che non erano disponibili all'interno di OnApplicationEnd. Anche se è davvero difficile dirlo senza vedere il messaggio di errore .. o qualche codice. – Leigh

+0

L'oggetto java che sto tentando di accedere alle vite nell'ambito dell'applicazione. Tale ambito viene passato al metodo onApplicationEnd() AFAIK. Il messaggio di errore per il test del thread è brutale, solo il nome del thread e un'eccezione del puntatore nullo. Avrebbe usato la richiesta ma questa deve essere l'ultima cosa che deve fare prima che il server si fermi. Pubblicherà presto del codice. –

+0

Sì, una copia dell'ambito dell'applicazione viene passata in OnApplicationEnd. Vorrei saltare i test con il "thread parallelo" per ora. Basta concentrarsi sugli errori che si verificano quando si utilizza direttamente l'ambito ambito dell'applicazione. – Leigh

1

Beh, la prima cosa che ho pensato è che il server non si ferma effettivamente quando l'applicazione si arresta ... L'applicazione si fermerà, ma il server è tenuto a continuare a fare il chugging.Se hai una directory con un vecchio Application.cfm in essa e solo alcuni file .cfm in quella directory, le persone possono richiedere quelle pagine cf e non possono essere associate a nessun tipo di contesto applicativo. In questo modo è possibile che nessuna applicazione sia in esecuzione e continui a pubblicare molte pagine CF. Certo, non è così che le persone generalmente impostano i loro server CF, ma funzionano così. Si è parlato della creazione di un Server.cfc come Application.cfc in una versione futura, anche se non so se l'hanno implementato in CF9.

mio secondo pensiero è che l'unico modo per il metodo onApplicatinEnd per causare l'errore specifico "java.lang.IllegalStateException: Spegnimento in corso" sarebbe se gli oggetti Java che stai riferimento sono oggetti Java che sono in qualche modo intrinsecamente legati al contesto dell'applicazione, ad esempio oggetti a cui è possibile accedere tramite ColdFusion.server.ServiceFactory non documentato. Ma il codice che hai pubblicato non sembra che stia succedendo.

È una soluzione lunga, ma è possibile provare a collocare l'oggetto testCrypto in una variabile locale/temp all'interno del metodo onApplicationEnd ed eseguirlo da lì.

Scusa non potrei essere più helfpul.

Problemi correlati