2009-10-22 11 views
5

Necesito usar onApplicationEnd() como parte de Application.cfc para ejecutar una llamada en un objeto de Java de un tercero para cerrar una conexión a otro dispositivo en la red.onApplicationEnd - ¿Se está cerrando CF realmente?

El código he funcionado perfectamente si lo llamo como una solicitud normal, pero cuando lo coloco en el método onApplicationEnd() me encuentro con algunos errores. Estos errores sugieren que CF podría de hecho cerrar ya al punto en el que no puedo acceder a estas clases Java de terceros.

Código:

<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 línea para cerrar la conexión en mi objeto está fallando con el mensaje: 'java.lang.IllegalStateException: Apagando el sistema'.

Éstos son los registros completos para una carrera:

"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 " 

¿Existe restricciones a lo que puedo hacer en onApplicationEnd() y si es así ¿hay alguna solución?

Estoy usando CF 8 (8,0,1,195765) Developer Edition en una máquina con Windows XP.

Además, si ejecuto CF en una ventana de consola y presiono CTRL-C veo esto, pero también veo este comportamiento si ejecuto cfstop.

¡Muchas gracias de antemano!

EDITAR: Algunos otros tenían este problema here, pero no hay soluciones.

EDITAR: Se eliminó el ejemplo de la secuencia, ya que podría estar empañando el problema. Código publicado y registros.

Respuesta

3

Suena como esto puede ser causado por el hecho de que el servidorse está cerrando, en lugar de sólo la aplicación CF. Supongo que si la JVM ya está en proceso de cierre, los recursos que utiliza su clase java podrían no estar disponibles en ese momento. Así que onApplicationEnd podría no ser el lugar correcto para ese código.

Es posible que desee considerar agregar un ShutdownHook. No soy 100% positivo, pero creo que colocar el código de limpieza allí, en lugar de onApplicationEnd podría permitir que el objeto java haga su limpieza antes de que la JVM entre en su estado de agonía.

Pero habiendo dicho todo eso, ¿no se cerraría automáticamente la "conexión a otro dispositivo en la red" una vez que el servidor se apaga?

+0

Acepto que este podría ser el caso e investigaré el uso de este gancho. Estoy usando CF 8, creo que 9 tiene esto integrado en Application.cfc. En cuanto a su último comentario: la razón por la que tengo que hacer esto es la falta de un cierre elegante de la conexión al dispositivo de terceros. –

+0

@Leigh - Perdón por la deplay al llegar al fondo de esto, haber estado ocupado con otras cosas. Necesito pasar un hilo al método de enganche de cierre. He decidido mirar a JavaLoader por Mark Mandel para ayudarme: http://www.compoundtheory.com/?action=displayPost&ID=422. Creo que puedo crear un CFC que implementó Runnable para pasar al método hook. Cualquier otra sugerencia es bienvenida! –

+0

Después de muchas pruebas y más discusión aquí: http://forums.adobe.com/message/2337930#2337930 No puedo encontrar una manera de hacer esto de manera confiable. Incluso crear un hilo y pasarlo al enganche de apagado del tiempo de ejecución del servidor no es bueno, obtengo una excepción de puntero nulo a pesar de que el hilo funciona correctamente fuera de los contextos de apagado del servidor. Muchas gracias por ayudar a todos, estoy implementando una solución para llamar al código de cierre explícitamente antes de que finalice la aplicación, es decir, a través de una solicitud normal. –

2

según los documentos "No puede usar este método para mostrar datos en una página de usuario, porque no está asociado a una solicitud".

Creo que "no está asociado con una solicitud". es la llave. Podría ser que sus objetos Java solo existan dentro del hilo de solicitud y no en la instancia de la aplicación.

Tal vez se trate de usar shound onRequestEnd

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

+0

Hm. Me pareció que el objeto solo se había creado en OnApplicationEnd, y quizás estaba intentando acceder a algunos datos que no están disponibles desde OnApplicationEnd. Aunque es realmente difícil de decir sin ver el mensaje de error ... o algún código. – Leigh

+0

El objeto Java al que intento acceder vive en el ámbito de la Aplicación. Ese alcance se pasa al método onApplicationEnd() AFAIK. El mensaje de error para la prueba de hilo es brutal, solo el nombre del hilo y una excepción de puntero nulo. Utilizaría el fin de la solicitud, pero esto realmente debe ser lo último que se haga antes de que se detenga el servidor. Publicaremos algún código pronto. –

+0

Sí, se pasa una copia del alcance de la aplicación a OnApplicationEnd. Me saltaría las pruebas con el "hilo paralelo" por ahora. Simplemente concéntrese en los errores que ocurren al usar el objeto con ámbito de la aplicación directamente. – Leigh

1

Bueno, lo primero que pienso es que el servidor no se detiene cuando la aplicación se detiene ... La aplicación se detendrá, pero es probable que el servidor siga avanzando.Si tiene un directorio con una Application.cfm anterior y solo algunos archivos planos .cfm en ese directorio, las personas pueden solicitar esas páginas cf y no pueden asociarse con ningún tipo de contexto de aplicación. Por lo tanto, no puede ejecutar ninguna aplicación y aún así ofrecer muchas páginas CF. Por supuesto, así no es como la gente generalmente configura sus servidores CF, pero funcionan de esa manera. Se ha hablado de crear Server.cfc como Application.cfc en una versión futura, aunque no sé si lo implementaron en CF9.

Mi segundo pensamiento es que la única forma de que el método onApplicatinEnd cause el error específico "java.lang.IllegalStateException: Shutdown in progress" sería si los objetos java a los que hace referencia son objetos java que de alguna manera están intrínsecamente vinculados al contexto de la aplicación, como los objetos a los que podría acceder a través de ColdFusion.server.ServiceFactory sin documentar. Pero el código que has publicado no parece estar sucediendo.

Es una posibilidad remota, pero podría tratar de colocar el objeto testCrypto en una variable local/temp dentro del método onApplicationEnd y ejecutarlo desde allí.

Lo siento, no podría ser más helfpul.

Cuestiones relacionadas