2009-10-22 88 views
5

我需要使用onApplicationEnd()作为Application.cfc的一部分,以便在第三方Java对象上执行呼叫以关闭与网络上其他设备的连接。onApplicationEnd - CF实际上是否关闭?

如果我将它作为普通请求调用,但我将它放在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()做,如果是的话有没有什么解决办法?

我在Windows XP机器上使用CF 8(8,0,1,195765)Developer Edition。

此外,如果我在控制台窗口中运行CF并按下CTRL-C,我看到了这一点,但如果我运行cfstop,我也会看到此行为。

非常感谢提前!

编辑:其他人有这个问题here,但没有解决方案。

编辑:删除线程示例,因为它可能会模糊问题。发布代码和日志。

回答

3

这听起来像这可能由事实服务器被关停,而不是仅仅CF应用程序引起的。我在猜测,如果JVM已经在关闭的过程中,那么您的java类使用的资源可能在此时不可用。所以onApplicationEnd可能不是该代码的正确位置。

您可能想要考虑添加一个ShutdownHook。我不是100%肯定的,但我认为将清理代码放在那里,而不是onApplicationEnd可能会允许java对象在JVM进入其死亡阶段之前进行清理。

但说了这么多,一旦服务器关闭,“连接到网络上的其他设备”会不会自动关闭?

+0

我同意这可能是这种情况,并将使用此钩子进行调查。我正在使用CF 8,我认为9已经内置到Application.cfc中。关于您最后的评论:我必须这样做的所有原因是没有正常关闭与第三方设备的连接。 – 2009-10-24 10:58:32

+0

@Leigh - 很抱歉,在这个问题的底部,忙于其他的事情。我需要将一个线程传递给shutdown hook方法。我决定看看Mark Mandel的JavaLoader来帮助我:http://www.compoundtheory.com/?action=displayPost&ID=422。我认为我可以创建一个实现Runnable传递给钩子方法的CFC。欢迎任何其他建议! – 2009-11-02 17:11:32

+0

经过大量测试和更多讨论之后:http://forums.adobe.com/message/2337930#2337930我无法找到一种可以可靠地完成这项工作的方法。即使创建一个线程并将它传递给服务器运行时关闭钩子也不行,我得到一个空指针异常,尽管线程在服务器关闭上下文之外运行良好。非常感谢大家的帮助,我正在实施一个解决方法,在应用程序结束之前明确调用关闭代码,即通过正常的请求。 – 2009-11-03 11:02:51

2

根据文档“您不能使用此方法在用户页上显示数据,因为它不与请求关联。”

我认为“与请求无关”。是关键。这可能是因为你的java对象只存在于请求线程中,而不存在于应用程序实例中。

也许不是你shound尝试使用onRequestEnd

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

+0

嗯。它听起来像对象只是在OnApplicationEnd中创建的,也许它试图从OnApplicationEnd中访问一些不可用的数据。虽然很难说没有看到错误信息或一些代码。 – Leigh 2009-10-22 18:47:11

+0

我试图在应用程序范围内访问生命的java对象。该范围传递给onApplicationEnd()方法AFAIK。线程测试的错误消息是残酷的,只是线程名称和空指针异常。 将使用请求结束,但这确实需要是服务器停止之前完成的最后一件事。 很快会发布一些代码。 – 2009-10-22 18:53:07

+0

是的,应用程序范围的副本被传递到OnApplicationEnd。现在我会跳过“并行线程”的测试。只关注直接使用应用程序作用域对象时发生的错误。 – Leigh 2009-10-22 19:10:16

1

那么我的第一个想法是,当应用程序停止时,服务器并没有真正停止...应用程序将停止,但服务器可能会一直处于停顿状态。如果您的目录中包含一个较旧的Application.cfm,并且该目录中只有一些平坦的.cfm文件,则人们可以请求这些cf页面,并且它们可以不与任何类型的应用程序上下文关联。所以你实际上可以没有应用程序运行,并且仍然可以提供大量的CF页面。当然,这不是人们通常设置他们的CF服务器的方式,但他们确实以这种方式工作。关于在将来的版本中创建像Application.cfc这样的Server.cfc,虽然我不知道他们是否已经在CF9中实现了它,但仍有一些讨论。

我的第二个想法是,onApplicatinEnd方法导致特定错误“java.lang.IllegalStateException:Shutdown进行中”的唯一方法是如果您引用的java对象是以某种方式内在地链接的java对象到应用程序上下文,例如您可能通过未公开的ColdFusion.server.ServiceFactory访问的对象。但是你发布的代码看起来并不像这样。

这是一个长镜头,但您可以尝试将testCrypto对象放置在onApplicationEnd方法内的本地/ temp变量中并从此处执行。

对不起,我不能更helfpul。

相关问题