4

We've migrated a ColdFusion application from ColdFusion 10 to ColdFusion 2016. After Migration, Application variables are not staying in its scope, it is refreshing on each and every request.

Consider the following example,

Application.cfm

<cfsetting enablecfoutputonly="true" />

<CFAPPLICATION  NAME="Test App"
                SETCLIENTCOOKIES="YES"
                CLIENTMANAGEMENT="YES"
                SESSIONMANAGEMENT="YES"
                SESSIONTIMEOUT="#CREATETIMESPAN(0,8,0,0)#"                                   
                APPLICATIONTIMEOUT="#CREATETIMESPAN(1,0,0,0)#">

<cfdump var="#Application#" label="app">

<CFLOCK SCOPE="APPLICATION" TYPE="EXCLUSIVE" TIMEOUT="10">
    <CFSET Application.Email = "test@test.com">
    <CFSET Application.DataSource="test">
</cflock>

Test.cfm

<CFLOCK SCOPE="APPLICATION" TYPE="READONLY" TIMEOUT="10">
    <cfset Application.one = 1>
    <cfset Application.two = 2>
    <cfset Application.three = 3>
</cflock>

OnRequestEnd.cfm

<cfsetting showdebugoutput="false" />
<cfdump var="#Application#" label="onRequestEnd">

So if we request /test.cfm it'll throw the following output enter image description here

Again refreshing the page also giving the same output enter image description here

Not sure why the Application scoped variables are losing its persistence.

the following is the expected output..

enter image description here

Any idea of Why the application variables are lost and getting refreshed on each and every request ?

James A Mohler
  • 11,060
  • 15
  • 46
  • 72
Rajesh Manilal
  • 1,104
  • 9
  • 20
  • Huh @Rajesh, I got the your expected result on my browser after refreshing the test.cfm. – Kannan.P Apr 03 '19 at 12:30
  • Could you please check my below gif image ? https://gyazo.com/e06f92bb4408377a8ac1bc86ceda47a9 – Kannan.P Apr 03 '19 at 12:31
  • @Kannan.P : That is the fact, even in my local environment also it is working as expected, but in server it is not happening. That is what questioning, on what circumstance the application will behave like this ? – Rajesh Manilal Apr 03 '19 at 12:49
  • 3
    @Rajesh, the `` in your Application.cfm page is simply running before the `Test.cfm` page is run. Once that page is run then the application variables have been set. So the next request/refresh of the page shows them. Since you are using a newer version of ColdFusion you should stop using Application.cfm and switch to Application.cfc. It gives you much more control over the processing life cycle. – Miguel-F Apr 03 '19 at 12:51
  • 1
    @Miguel-F On next request also the output is same, that is what I came to SO :). Application.cfc,we can use, but the application came to me after getting migrated :) – Rajesh Manilal Apr 03 '19 at 12:55
  • What if you take the ' ' (space) out of the application name? So instead of ` – Miguel-F Apr 03 '19 at 13:03
  • 1
    Aside - your second application lock is read only, but I don’t think that would affect the issue. – Redtopia Apr 03 '19 at 14:00
  • @Miguel-F if the space is problem means then that should be reproduced in local too. Right ? – Kannan.P Apr 03 '19 at 14:19
  • 1
    @Kannan.P yes I would agree _except_ that the local environment most likely does not match the server environment exactly (otherwise they would be behaving the same way). – Miguel-F Apr 03 '19 at 14:27
  • 1
    @RajeshManilal Your dev system and your test server are both on CF 2016 with identic updater installed? – Bernhard Döbler Apr 03 '19 at 15:11
  • 2
    ... and same operating system, same operating system version, same operating system patches, same java version, etc etc etc – Miguel-F Apr 03 '19 at 15:21

1 Answers1

2

I haven't tested this code, but what you're seeing is the procedural order of operation performed by Application.cfm. You're essentially redefining the application on every request, which is why on the name exists in your initial dump and the rest exist on the dump in onRequestEnd.

If you update your code to use Application.cfc, you can ditch the cflock code, better organize your "triggers" and define your application variables once, when needed, using onApplicationStart.

<cfcomponent>

    <cfset this.name = "Test App">
    <cfset this.SETCLIENTCOOKIES="YES">
    <cfset this.CLIENTMANAGEMENT="YES">
    <cfset this.SESSIONMANAGEMENT="YES">
    <cfset this.SESSIONTIMEOUT="#CREATETIMESPAN(0,8,0,0)#">
    <cfset this.APPLICATIONTIMEOUT="#CREATETIMESPAN(1,0,0,0)#">
    <cfsetting enablecfoutputonly="true" />

    <cffunction name="onApplicationStart" access="public" returnType="void" output="false">
        <cfset application.Email = "test@test.com">
        <cfset application.DataSource="test">
    </cffunction>

    <cffunction name="onRequestStart" access="public" returntype="boolean" output="false">

        <cfset application.one = 1>
        <cfset application.two = 2>
        <cfset application.three = 3>

        <cfreturn true>
    </cffunction>

    <cffunction name="onRequestEnd" access="public" returntype="boolean" output="false">

        <cfsetting showdebugoutput="false" />
        <cfdump var="#application#" label="onRequestEnd">

        <cfreturn true>
    </cffunction>

</cfcomponent>

This should define email and datasource in the application scope one time, when the app first loads. The variables one, two and three will be created at the start of each request, but you can add a check to set them only if they don't already exist.

You can then use child Application.cfc files to help modularize your application using sub-folders and sub-application specific variables. They'll still exist in the scope of the larger application, but you'll be able to manage them from a location specific to a sub-app this way.

Miguel-F
  • 13,450
  • 6
  • 38
  • 63
Adrian J. Moreno
  • 14,350
  • 1
  • 37
  • 44
  • 1
    Exactly what I was trying to convey to them in comments but didn't have time to create an answer. Thanks for posting. – Miguel-F Apr 03 '19 at 17:26