• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

onApplicationEnd() - are all server resources available?

New Here ,
Oct 22, 2009 Oct 22, 2009

Copy link to clipboard

Copied

Hi all

I need to use onApplicationEnd() as part of Application.cfc to execute a call on a 3rd party Java object to close a connection to another device on the network.

The code I have worked perfectly if I call it as a normal request, but when I place it in the onApplicationEnd() method I'm running into some errors. These errors suggest that CF might in fact be shutting down already to the point where I cannot access these 3rd party Java classes. Not good, but also unexpected.

I then decided I'd create a parallel thread in the onApplicationEnd() and then rejoin to the main thread when I had closed by connection, but I get an obscure null pointer exception trying to create this thread from this function. Again, the same code works well if I use it in a normal request.

Is there restrictions to what I can do in onApplicationEnd() and if so is there any work around?

I am using CF 8 (8,0,1,195765) Developer Edition on a Windows XP machine.

Many thanks in advance!


Ciaran Archer
TOPICS
Advanced techniques

Views

2.0K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

LEGEND , Oct 23, 2009 Oct 23, 2009

I think you're on the button here, -==cfSearching==- : onApplicationEnd() will not reliably run here.

I had a discussion elsewhere about why CF9 provides onServerStart() but not onServerEnd().  The fact of the matter this is no reliable way of hooking into a CF-service shutdown, even if it has been triggered by some action.

The same would apply for onApplicationEnd() here.

onApplicationEnd() is for when the application times out, or applicationStop() is called or something like that.

--

Adam

Votes

Translate

Translate
Valorous Hero ,
Oct 22, 2009 Oct 22, 2009

Copy link to clipboard

Copied

The code I have worked perfectly if I call it as a normal

request, but when I place it in the onApplicationEnd()

method I'm running into some errors.

Can you provide more detail about the error messages?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Oct 22, 2009 Oct 22, 2009

Copy link to clipboard

Copied

-==cfSearching==- wrote:

The code I have worked perfectly if I call it as a normal

request, but when I place it in the onApplicationEnd()

method I'm running into some errors.

Can you provide more detail about the error messages?

And I reckon the code for the onApplicationnd handler too.

--

Adam

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 23, 2009 Oct 23, 2009

Copy link to clipboard

Copied

Thanks for the replies so far. Here is the code:

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

The line to close the connection on my object is failing with the message: 'java.lang.IllegalStateException: Shutdown in progress'.

Here are the full logs for one run:

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

I really hope there is a work-around. The same issue occurs when I run CF as a console window and stop it with CTRL-C or if I run cfstop.

Cheers,

Ciaran

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Oct 23, 2009 Oct 23, 2009

Copy link to clipboard

Copied

Because links have a way of disappearing, I am copying the response from stackoverflow.com :

It sounds like this may be caused by the fact that the server is shutting down, rather than just the CF application. I am guessing that if the JVM is already in the process of shutting down, the resources your java class uses might not be available at that point. So onApplicationEnd might not be the correct place for that code.

You might want to look into adding a ShutdownHook. I am not 100% positive, but I think placing the cleanup code there, instead of in onApplicationEnd might allow the java object to do its cleanup before the JVM enters its death throes stage.

But having said all that, would not the "connection to another device on the network" be closed automatically once the server shuts down?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Oct 23, 2009 Oct 23, 2009

Copy link to clipboard

Copied

I think you're on the button here, -==cfSearching==- : onApplicationEnd() will not reliably run here.

I had a discussion elsewhere about why CF9 provides onServerStart() but not onServerEnd().  The fact of the matter this is no reliable way of hooking into a CF-service shutdown, even if it has been triggered by some action.

The same would apply for onApplicationEnd() here.

onApplicationEnd() is for when the application times out, or applicationStop() is called or something like that.

--

Adam

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Oct 23, 2009 Oct 23, 2009

Copy link to clipboard

Copied

I had a discussion elsewhere about why CF9 provides onServerStart() but not onServerEnd().  The fact of the matter this is no reliable way of hooking into a CF-service shutdown, even if it has been triggered by some action.

Adam - Was it in a public forum or a private group? I would be interested to read the details, because I was just getting to the new OnServerStart feature today and found myself asking that same silly question..  Just trying to learn more about the nuances and ins and outs of server.cfc

-Leigh

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Oct 24, 2009 Oct 24, 2009

Copy link to clipboard

Copied

Adam - Was it in a public forum or a private group? I would be interested to read the details, because I was just getting to the new OnServerStart feature today and found myself asking that same silly question..  Just trying to learn more about the nuances and ins and outs of server.cfc

Sorry mate, it was a private forum.  But there wasn't much/any info beyond what I said anyway: it wasn't the main topic under discussion.

--

Adam

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Oct 26, 2009 Oct 26, 2009

Copy link to clipboard

Copied

LATEST

A Cameron wrote:

Sorry mate, it was a private forum.  But there wasn't much/any info beyond what I said anyway: it wasn't the main topic under discussion.

--

Adam

Okay.  Thanks anyway.

-Leigh

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 24, 2009 Oct 24, 2009

Copy link to clipboard

Copied

Before we proceed, get the typo <<cflog out of the way. Any changes?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 25, 2009 Oct 25, 2009

Copy link to clipboard

Copied

In any case,  it's better to store the object in local scope, as follows

<cffunction name="onApplicationEnd" returnType="void">
        <cfargument name="appScope" required="true" />
        <cfset var logLocation = "test" />

       <!---  local scope marks testObject for garbage collection when onApplicationEnd returns --->
       <cfset var testObject = "">
        <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")>
                      
                        <cfset testObject = ARGUMENTS.appScope.testCrypto>

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation