onApplicationEnd - CF на самом деле закрывается? - PullRequest
5 голосов
/ 22 октября 2009

Мне нужно использовать onApplicationEnd() как часть Application.cfc для выполнения вызова на стороннем Java-объекте для закрытия соединения с другим устройством в сети.

Код, который у меня работал отлично, если я называю его обычным запросом, но когда я помещаю его в метод onApplicationEnd(), я сталкиваюсь с некоторыми ошибками. Эти ошибки предполагают, что CF может фактически завершить работу до такой степени, что я не могу получить доступ к этим сторонним Java-классам.

Код:

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

Строка для закрытия соединения на моем объекте завершается с сообщением: «java.lang.IllegalStateException: Завершение работы в процессе».

Вот полные журналы за один прогон:

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

Есть ли ограничения на то, что я могу сделать в onApplicationEnd(), и если да, то есть ли какое-нибудь решение?

Я использую CF 8 (8,0,1,195765) Developer Edition на компьютере с Windows XP.

Также, если я запускаю CF в окне консоли и нажимаю CTRL-C, я вижу это, но я также вижу это поведение, если я запускаю cfstop.

Заранее большое спасибо!

РЕДАКТИРОВАТЬ: Некоторые другие имели эту проблему здесь , но нет решений.

РЕДАКТИРОВАТЬ: Удален пример потока, так как это может затуманить проблему. Прикрепленный код и логи.

Ответы [ 3 ]

3 голосов
/ 23 октября 2009

Похоже, это может быть вызвано тем, что сервер завершает работу, а не только приложением CF. Я предполагаю, что если JVM уже находится в процессе выключения, ресурсы, которые использует ваш класс java, могут быть недоступны в этот момент. Таким образом, onApplicationEnd может быть неправильным местом для этого кода.

Возможно, вы захотите добавить ShutdownHook . Я не уверен на 100%, но я думаю, что размещение кода очистки вместо onApplicationEnd может позволить объекту java выполнить очистку до того, как JVM войдет в стадию смерти.

Но, сказав все это, не будет ли автоматически закрываться "соединение с другим устройством в сети" после выключения сервера?

2 голосов
/ 22 октября 2009

в соответствии с документацией «Этот метод нельзя использовать для отображения данных на странице пользователя, поскольку они не связаны с запросом».

Я думаю, что "не связано с запросом". это ключ. Возможно, ваши java-объекты существуют только в потоке запросов, а не в экземпляре приложения.

Возможно, вместо этого вы должны попробовать использовать onRequestEnd

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

1 голос
/ 24 октября 2009

Ну, первая мысль, что сервер не останавливается, когда приложение останавливается ... Приложение будет остановлено, но сервер будет продолжать пыхтеть. Если у вас есть каталог с более старым Application.cfm в нем и просто несколько плоских .cfm файлов в этом каталоге, люди могут запросить эти страницы cf, и они могут быть не связаны с каким-либо контекстом приложения. Таким образом, вы можете не запускать приложения и по-прежнему обслуживать множество CF-страниц. Конечно, это не то, как люди обычно настраивают свои CF-серверы, но они работают таким образом. Ходили разговоры о создании Server.cfc, такого как Application.cfc, в будущей версии, хотя я не знаю, реализовали ли они его в CF9.

Моя вторая мысль заключается в том, что единственный способ для метода onApplicatinEnd вызвать конкретную ошибку "java.lang.IllegalStateException: Завершение работы" может быть, если объекты Java, на которые вы ссылаетесь, являются объектами Java, которые каким-то образом связаны с контекст приложения, например объекты, к которым вы можете получить доступ через недокументированный файл ColdFusion.server.ServiceFactory. Но код, который вы разместили, не выглядит так, как будто это происходит.

Это длинный путь, но вы можете попробовать поместить объект testCrypto в локальную переменную / temp в методе onApplicationEnd и выполнить его оттуда.

Извините, я не мог быть более здоровым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...