Skip to main content
Known Participant
January 30, 2018
Question

CF2016 - <cfinclude> dynamic template name - java.IO.IOException *sometimes*

  • January 30, 2018
  • 2 replies
  • 1474 views

Hello,


I have a problem with CF2016 after upgrading two of our three servers; all are running behind a load balancer.  The CF2016 servers have had this problem multiple times since upgrading to CF2016, while the CF11 server has never had this problem.  So I'm pretty confident it's CF2016.

Based on a URL parameter appl, we check to see if the index.cfm file exists in that folder:

<cfset filename="#appl#\index.cfm">

<cfif fileExists("d:\docs\#filename#")>

     <cfinclude template="#filename#">
<cfelse>

     <cfthrow type="applDoesNotExist">
</cfif>

This code gets run hundreds of thousands of times per day, most with no trouble at all.

Occasionally (maybe 3x a day), the bolded <cfinclude> line above errors with:

java.io.IOException

The process cannot access the file because it is being used by another process

Key points:

  • This ONLY happens when cfincluding dynamically-created template names.  Any instances where the template name is hard coded, e.g. <cfinclude template="testapp\index.cfm"> are not affected
  • It can happen with any variation of #appl# - i.e. it's not just one #appl# that gets this error
  • The .cfm files which it is trying to access EXIST
  • The .cfm files which it is trying to access are UNTOUCHED and have been untouched, in most cases, for years.
  • This is only happening in CF2016, not in CF11 with 100% matching settings (including things like template caching)
  • Again, 99.99% of the time, the exact same URL gets hit and it works fine. In other words, it is hard to replicate this issue

I don't understand the error.  We have ensured that no processes are touching .cfm files (and besides, the fact that this is only happening to files with *dynamically generated* (variable) names seems to contraindicate such an explanation)

Any ideas what behavior behind the scenes in CF2016 is causing this?  Thanks for insight.

    This topic has been closed for replies.

    2 replies

    BKBK
    Community Expert
    Community Expert
    February 5, 2018

    Occasionally (maybe 3x a day), the bolded <cfinclude> line above errors with:

    java.io.IOException

    The process cannot access the file because it is being used by another process

    Surpising behaviour, perhaps due to the dynamic variables. If so, a named lock might help

    <cflock name="cfincludeFileLock" type="exclusive">

        <cfset filename="#appl#\index.cfm">

        <cfif fileExists("d:\docs\#filename#")>

             <cfinclude template="#filename#">
        <cfelse>

             <cfthrow type="applDoesNotExist">
        </cfif>

    </cflock>

    James Moberg
    Inspiring
    January 30, 2018

    I was encountering the same issue after upgrading some legacy apps from CF8/9 to CF10/2016.  We have a special template sub-directory where we maintain themes.  Occasionally CF10/2016 would insist that it didn't exist and throw an error.

    The only thing we've identified that works is to add an application.cfc file to these projects and specifically define the "rootDir" & generate mappings for the sub-directories that were getting lost.

        <cfset this.rootDir = getDirectoryFromPath(getCurrentTemplatePath())>

        <cfset this.mappings = {}>

        <cfset this.mappings[ "/templates" ] = "#this.rootDir#templates/">

    EddieLotter
    Inspiring
    January 30, 2018

    Surely this:

    <cfif fileExists("d:\docs\#filename#")>

      <cfinclude template="#filename#">

    should be:

    <cfif fileExists("d:\docs\#filename#")>

      <cfinclude template="d:\docs\#filename#">

    Otherwise you are checking that a file exists in one location but then trying to include it in the folder of the caller.

    Cheers

    Eddie

    bpropAuthor
    Known Participant
    January 31, 2018

    I may have taken a couple liberties (or missed a character) when consolidating the code for easy view, but the second line is relative from the index.cfm file where the <cfinclude> is. We generally don't cfinclude absolute file paths with drive letters, though that's what we have to use for fileExists.

    So for example:

    D:\

         \docs

              index.cfm <- this is where the <cfinclude> is

              \appl1

    index.cfm  <- this is the file we're <cfinclude>ing

    othertemplate.cfm

              \appl2

    index.cfm

    othertemplate.cfm

              \appl3

    index.cfm

    othertemplate.cfm

    So if we have <cfinclude template="appl1\index.cfm">, it is relative to the index.cfm file under D:\docs

    But for purposes of fileExists(), we use the full template path, D:\docs\appl1\index.cfm