Question

I am placing a component in my application scope so that it is shared across all requests and it includes a a cfm template:

<cfcomponent output="false">

    <cffunction name="run" output="false" returntype="void">

        <cfset var tmp = false/>

        <cftry>
            <cfinclude template="inc.cfm"/>
            <cfcatch>
                <cffile action="append"
                        file="#ExpandPath("error.log")#"
                        output="ERROR: #cfcatch.message#"/>
            </cfcatch>
        </cftry>

    </cffunction>

</cfcomponent>

The template that is being included simply creates an array and checks the array length is what it should be, if not it writes to the error.log file:

<cfset tmp = [
    "one",
    "two",
    "three"
]/>
<cfif ArrayLen(tmp) neq 3>
    <cffile action="append"
            file="#ExpandPath("error.log")#"
            output="Length = #ArrayLen(tmp)#"/>
</cfif>

If I then run a load across it (100 concurrent threads) I get the following items appearing in my error.log file...

ERROR: element at position 3 of array variable &quot;___IMPLICITARRYSTRUCTVAR0&quot; cannot be found.
Length = 0
Length = 2

Note I'm using ColdFusion 9.0.1.274733 ontop of Java 1.7.0_09. I've tested Railo on the same JRE and it works fine.


Additional The following also causes a problem, changing the tmp variable to a struct and adding a random item in the variables scope that is not referenced anywhere...

<cfcomponent output="false">

    <!--- 
    Some random variable that does nothing with the exception
    of being the facilitator of my eternal pain
    --->
    <cfset variables.t = {}/>

    <cffunction name="run" output="false" returntype="void">

        <cfset var tmp = {}/>

        <cftry>
            <cfinclude template="inc2.cfm"/>
            <cfcatch>
                <cffile action="append"
                        file="#ExpandPath("error.log")#"
                        output="ERROR: #cfcatch.message#"/>
            </cfcatch>
        </cftry>

    </cffunction>

</cfcomponent>

Which includes a template, very similar to the first, that looks like this...

<cfset tmp.arr = [
    "one",
    "two",
    "three"
]/>
<cfif ArrayLen(tmp.arr) neq 3>
    <cffile action="append"
            file="#ExpandPath("error.log")#"
            output="Length = #ArrayLen(tmp.arr)#"/>
</cfif>

If you remove the item in the variables scope it works fine. If you dump #variables# and #local# in the template, everything is where you would expect it to be.


(Update from comments)

I've since raised this issue as a bug #3352462

Was it helpful?

Solution

This is based on Peter's / your own comments above.

There have been / are a number of bugs with array and struct shorthand notion, and have been since CF8 introduced the syntax. Adobe's approach to fixing 'em has been a bit like whack-a-mole rather than an effort to sort the problem out once, and properly. It looks like you've found another example of this. It'd be interesting to see if this still exists in CF10 though, as I know they fixed some more during its dev cycle.

The only way around it is to not use that notation in situations in which you see these problems.

Could you pls raise a bug for this so Adobe are aware of it?

Also slightly noteworthy, but unrelated to your specific issue here: CF ain't supported on Java 1.7 yet. You might wanna bear that in mind.

OTHER TIPS

You might consider adding some locking around your tag to ensure only one request is permitted to modify the file.

In your first example, does it make any difference if you declare tmp as an array instead of a boolean?

<cfset var tmp = ArrayNew(1) />

instead of...

<cfset var tmp = false />
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top