Cache already exists error with CFCACHE - coldfusion

I've recently used CFCACHE to implement page caching on a cold fusion 9 server.
However I'm getting errors reported under load (running an automated link checker) like:
"Cache A95C0BF9E9BFBC6F151F03E939D2D2D6TEMPLATE already exists"
I had thought that cfcache would be thread safe, and handle this without any extra code. If it is relevant I'm calling it within "OnRequest" within my application.cfc. To me it seems like perhaps this is a Cold Fusion bug, but it's also possible I'm abusing the CFCACHE mechanism in some way.
<!--- setup caching if enabled --->
<cfif getConfigValue('page_cache') eq "true" and not application.security.isLoggedOn()>
<cfcache timespan="#createTimeSpan(0,0,10,0)#" directory="#application.pagecachepath#" usequerystring="true" >
</cfif>
<!--- Call request handling and rendering functions --->
<cfcontent reset="yes" type="text/html"><cfoutput>#html.render()#</cfoutput>
<cfif getConfigValue('page_cache') eq "true" and not application.security.isLoggedOn()><!-- content generated at #Now()#--></cfif>
The stack trace is:
net.sf.ehcache.ObjectExistsException: Cache A95C0BF9E9BFBC6F151F03E939D2D2D6TEMPLATE already exists at
net.sf.ehcache.CacheManager.addCacheNoCheck(CacheManager.java:920) at
net.sf.ehcache.CacheManager.addCache(CacheManager.java:915) at
net.sf.ehcache.CacheManager.addCache(CacheManager.java:870) at
coldfusion.tagext.io.cache.ehcache.GenericEhcache.createCache(GenericEhcache.java:317) at
coldfusion.tagext.io.cache.ehcache.GenericEhcache._getCache(GenericEhcache.java:301) at
coldfusion.tagext.io.cache.ehcache.GenericEhcache.getCache(GenericEhcache.java:268) at
coldfusion.tagext.io.cache.ehcache.GenericEhcache.get(GenericEhcache.java:72) at
coldfusion.tagext.io.cache.CacheTagHelper.checkFromTemplateCache(CacheTagHelper.java:56) at
coldfusion.tagext.io.cache.CacheTag.checkTemplatecache(CacheTag.java:695) at
coldfusion.tagext.io.cache.CacheTag.doStartTag(CacheTag.java:609) at
coldfusion.runtime.CfJspPage._emptyTcfTag(CfJspPage.java:2722) at cfapplication2ecfc814216694$funcONREQUEST._factor1(C:\inetpub\vhosts\example.org\httpdocs\application.cfc:190) at
cfapplication2ecfc814216694$funcONREQUEST.runFunction(C:\inetpub\vhosts\example.org\httpdocs\application.cfc:187) at
coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:472) at
coldfusion.runtime.UDFMethod$ReturnTypeFilter.invoke(UDFMethod.java:405) at
coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:368) at
Absent any better ideas I guess I'll start looking into the EH cache source!

race condition in coldfusion.tagext.io.cache.ehcache.GenericEhcache
Looks like it exists in both CF9 & 10 (based on source code)
your only solution is to put cflock somewhere to fix this yourself.

Related

Viewing Execution Stack Trace when there's no access to CFIDE

I'm currently in the process of debugging a ColdFusion system for a client...
Problem is, because they're quite sensitive about any of their systems being screwed up if I were to touch the CF Administrator module, they've made it off limits... And they're quite hesitant to even open it up on a specific IPs because they don't want the stack trace to accidentally be viewed by other users...
So I'm wondering... is there a CF tag or function I can implement in varioous parts of the code to trigger a stack trace in lieu of this access?
If you're trying to get stack traces when errors occur, then you should be able to do that using the onError event on Application.cfc. From there you'll be able to log the exception to a file, send out as an email or hook into something like Hoth or BugLogHG or even 3rd party services like Airbrake or Sentry
// in Application.cfc
function onError(any exception, string event) {
// do something here like send an email / log to file etc
}
If you don't have any errors and you want to get a stack trace then that is harder, but you can fake an error, so something like this might work:
<cfset greeting = "Hello World!">
<cftry>
<!--- deliberately throw an error --->
<cfthrow type="ForceException" message="Thrown Exception">
<cfcatch>
<!---
the cfcatch key has a stacktrace key so you can log/email it
to get the information and the rest of the code will execute
--->
<cflog file="somefile" text="#SerializeJSON(cfcatch)#">
</cfcatch>
</cftry>
<!--- this code will still run --->
<cfoutput>
#greeting#
</cfoutput>

Problems handling 404 errors in ColdFusion 10 on Win2k8 R2 x64?

I'm having difficulties handling 404 errors correctly in ColdFusion 10 on Windows 2008 R2 x64 using a custom error handler (Execute URL) in IIS. I've done this in previous versions of CF with no problems. In IIS, under the web site features, I open "Error Pages" and set it to execute "/404.cfm" for all 404 errors.
The problem I'm having is that the output of the 404.cfm page is not completely being sent back to the browser and the page doesn't load correctly. Sometimes I get nothing back, other times I get 1K, other times I get a little bit more. It's very inconsistent.
Along with setting the 404.cfm handler in IIS, I am also calling it in the onMissingTemplate() method inside Application.cfm:
<cffunction name="onMissingTemplate"
returnType="boolean"
output="true">
<cfargument name="thePage" type="string" required="true">
<cftry>
<cfmodule template="../../../404.cfm" thePage="#Arguments.thePage#">
<cfcatch>
<cfoutput><p>An error occurred</p></cfoutput>
</cfcatch>
</cftry>
<cfreturn true />
</cffunction>
Inside my 404.cfm error handler, I'm calling:
<cfheader statuscode="404" statustext="Not Found">
... and then I output a bunch of stuff.
When I remove the call to cfheader in 404.cfm, the error handler loads correctly [for ColdFusion requests]. That's because nothing is going through IIS - instead, it's simply going through the onMissingTemplate() method in ColdFusion. However, the response header gives me a 200 status code, which is a problem! It needs to be a 404 status code for obvious reasons.
When I include the cfheader call, OR when a non-ColdFusion page is being requested (IIS will generate the 404 status code), the output of my 404.cfm handler is not completely returned to the browser. I think has something to do with IIS getting its hands on the action.
I did report this in the CF bug database, but I'm wondering if there's something I'm doing wrong. The bug is here: https://bugbase.adobe.com/index.cfm?event=bug&id=3488063
This bug is indeed finally fixed for CF10, with update 11. See http://blogs.coldfusion.com/post.cfm/coldfusion-10-update-11-an-update-with-50-fixes. It only mentions it in passing ("8. Web Container/Tomcat - CGI.server_port, IIS custom error handlers"), but it is there.
And the bug report referenced above has also been updated to indicate that it's fixed with this update.
But let me offer a word of warning: some folks are saying (at the bug report) that they are finding the problem NOT fixed even after applying the update.
There's a very likely explanation: please note that after applying update 11, you MUST either update or rebuild the web connector for IIS. For more on that, see http://blogs.coldfusion.com/post.cfm/coldfusion-10-does-the-connector-need-to-be-re-installed-for-update-11.
More specifically, if you look at the coldfusion10\config\wsconfig[nn\ folder (where nn is a number, of which folders you have more than one), and your isapi_redirect.dll is not dated in May 2013, then you have NOT yet done the needed update 11 and will still seem to have the problem.
And be sure to update all of your connectors, if you have more than one such folder under wsconfig. If after doing that, and restarting IIS perhaps, if you are still having the problem, then do report back at the bug report confirming that. Perhaps there may be something else to explain it, but we'd want to rule this issue out first.
I've updated the bug base bug but will re-iterate my workaround here.
I was able to kludge a fix by wrapping the content of the 404 handler using CFSaveContent then forcibly writing the content length:-
<cfsavecontent variable="thePage">
Your 404 code here
</cfsavecontent>
<cfcontent reset="Yes" type="text/html"><cfheader name="Content-Length" value="#len(thePage)#"><cfoutput>#thePage#</cfoutput><cfabort>
Note: I have the cfcontent through to the cfabort on one line so there's no additional whitespace.
CF9 doesn't seem to set a content length header but it doesn't seem to make a difference.. CF10 however ... Tomcat must not be adding the magic ingredient at the end of the CF handling and passing it back to IIS.
I have not found update 11 to work. Even after connector updates. Another kludgey fix:
<CFPARAM default="0" name="URL.r">
<CFPARAM default="0" name="URL.t">
<CFSET ErrUrl = "/cfm/global/404error.cfm">
<CFIF URL.r IS 0>
<CFIF FindNoCase( ".htm", CGI.HTTP_REFERER ) GT 0>
<CFLOCATION url="#ErrUrl#?r=1&t=htm">
</CFIF>
<CFIF FindNoCase( ".cfm", CGI.HTTP_REFERER ) GT 0>
<CFLOCATION url="#ErrUrl#?r=1&t=cfm">
</CFIF>
<CFLOCATION url="#ErrUrl#?r=1">
</CFIF>
<CFIF URL.t IS "htm">
<CFHEADER statuscode="404" statustext="Page Not Found">
</CFIF>
placed at the top of your error page (change your ErrUrl to point to your error page) works for both CFM and HTM(L) pages. It's gross, but seems to work.
Inside my 404 handler, I added:
<cfheader statuscode="404" statustext="Not Found">
<cfheader name="Connection" value="Close"> <!--- this is the fix! --->
Closing the connection seems to work for some reason.
And to output the page, I'm doing:
<cfcontent reset="Yes" type="text/html">
<cfheader name="Content-Length" value="#Len(fullpage)#">
<cfoutput>#fullpage#</cfoutput>
... where the variable fullpage is the content of the 404 handler.
Now I can now consistently return both a 404 status code error AND the entire contents of my error page. However, when a non-ColdFusion page is requested, the CGI values are not correct. Prior to CF10, I could get the requested page by looking at the CGI parameters, specifically CGI.query_string, which used to look like: “404;http://www.example.com/some/file.html” Now I’m getting: “404;http://www.example.com/jakarta/isapi_redirect.dll”, which makes it impossible to get the requested page.
However, the fact that I can now return an entire document makes this at least a partial workaround to the bug, which is still open (after over a year of CF10 being released)! For now, instead of trying to figure out what page was requested and looking at my sitemap, I'm simply outputting a standard "page not found" error.
I should also mention that I'm using the same 404 handler in the onMissingTemplate method in Application.cfc. The requested page is passed into this method, which I then pass to my 404 handler in the Attribute scope, and I call my 404 handler as a cfmodule. So this is a complete solution when it's a ColdFusion page being requested, and only a partial solution when a non-CF page is requested (since we can't determine the requested file).
fix i came up with after trial and error
is in the custom404.cfm that you have pathed to in iis7
put the following code
<cfinclude template="/inc_mypathtoroot/my404.cfm">
<cfheader name="Connection" value="Close">
then create the file my404.cfm in the root (the path for the include will need to be your include path)
in the my404.cfm file put your processing code.
BUT DO NOT USE <CFABORT> ANYWHERE IN THAT FILE AS IT WILL CAUSE THE CONNECTION TO BE RESET.

coldfusion with memcached client returning error after 270 or so calls

My question seems to be related to this one:
Coldfusion memcached connections
however, i have been unable to solve it.
if i put this code in application.cfm:
<cfif not IsDefined("application.memcached")>
<cfset application.memcachedFactory = createObject("component","memcachedFactory").init("192.168.2.91:11211")>
<cfset application.memcached = application.memcachedFactory.getmemcached()>
</cfif>
the page will work for maybe 270 calls. then it will start to fail with an error "Object Instantiation Exception " The code is properly talking to memcached. I can send and receive data. it seems like java is running out of something .. threads, sockets, handles of some sort. I know little about java, and am stuck.
This seems wrong to me Don. Why would this code run again after the very first call? It should be running 1 time after which you have a reference to your object. What does the rest of your application.cfm look like? Have you added a cfapplication tag with a "name"?
If you fail to set an application "name" (via the cfapplication tag or "this.name" in application.cfc), the an "application.x" variable is treated just like a regular variable. After the page request ends it will "go away" and require the next request to reinstantiate the object over again.
The purpose of the "isDefined()" in this case is to insure it runs only once - providing you with a singleton (single reference) you can use again and again without reinstantiating it. It sounds like you are not "inside" an application.

Debugging a Photo Uploader/ CfCatch

I seem to be having an issue with the photo uploading function on a site I'm working on.
<cftry>
<cffile
action="upload"
destination="#physicalPath#\PHOTOS"
filefield="photo"
nameconflict="makeunique"
accept="image/jpeg, image/pjpeg"
result="mypicture"
/>
<cfset OutcomeID = "#FORM.OutcomeID#"/>
<!---Inserts file name and outcome id into Uploads table in the database --->
<cfinvoke component="#classpath#.cf_classes.dao.uploads" method="insertPhoto" returnvariable="success">
<cfinvokeargument name="fileName" value="#mypicture.SERVERFILE#"/>
<cfinvokeargument name="OutcomeID" value="#OutcomeID#"/>
</cfinvoke>
<cfset photoError = "Photo uploaded successfully"/>
<cfcatch type="any">
<cfset photoError = "There was an error uploading your photo.<br/> Please make sure it is a JPEG format."/>
</cfcatch>
</cftry>
No matter what, I just keep getting back the error message defined in the cfCatch. What are some good ways to troubleshoot something like this? Do any problems stand out to anyone?
Thanks for the help, I'm still relatively new to CF.
You're masking the exception that your cfcatch is catching by just setting a string in there. If you don't want to remove your exception handler, a quick and easy way to see what the underlying error is while you're still working on the code is to add:
<cfcatch><cfdump var="#cfcatch#"></cfcatch>
You may want to add an abort="true" to your cfcatch to stop processing of further code at that point which can mask your exception dump or cause it not to appear.
Putting cfcatch.message into a string that the user sees is not good practice as this may potentially result in information disclosure which can be a security risk (eg. if the message contains a file path on your server or similar)
Long term, if you're using Coldfusion Builder then you can also use the Coldfusion Debugger that is built in to step through your code and see where it is failing at the state of your variables at that point.

NullPointerExceptions in ColdFusion 9 and ColdBox on localhost

I'm running CF 9.0.1 Developer and Coldbox 3.0.0 on my local machine (64-bit Windows Vista running 32-bit CF9 on Apache). I'm working on an application that I've checked out from SVN and deployed locally. Everything seems to be working correctly, but my application log is filling up with entries like this:
Apr 18, 2011 12:41 PM Error jrpp-7
exception.log has an extremely long stack trace for each exception, maybe 150 lines or so. It starts with this:
"Error","jrpp-4","04/18/11","11:07:30",,""
java.lang.NullPointerException
at coldfusion.util.Utils.getServletPath(Utils.java:86)
at coldfusion.util.Utils.getServletPath(Utils.java:76)
at coldfusion.util.Utils.getBaseTemplatePath(Utils.java:405)
at coldfusion.runtime.TemplateProxyFactory.getTemplateFileHelper
(TemplateProxyFactory.java:1522)
at coldfusion.runtime.MetadataUtils.getComponentMetadata
(MetadataUtils.java:112)
at coldfusion.runtime.CfJspPage.GetComponentMetaData(CfJspPage.java:2667)
at coldfusion.runtime.TemplateProxy.getRuntimeComponentMetadata
(TemplateProxy.java:1756)
at coldfusion.runtime.TemplateProxy.getRuntimeMetadata
(TemplateProxy.java:1617)
at coldfusion.runtime.MetadataUtils.getMetaData(MetadataUtils.java:54)
at coldfusion.runtime.CfJspPage.GetMetaData(CfJspPage.java:2640)
at cfEventHandler2ecfc862260423$funcPOSTLOAD.runFunction
(C:\ColdFusion9\wwwroot\ybocv5\coldbox\system\orm\hibernate
\EventHandler.cfc:30)
This is a version of an app that has been running in production, and what makes me think this is just on my local version is the appearance of this in the stack trace:
at cfdump2ecfm471394032$funcRENDEROUTPUT.runFunction
(E:\cf9_updates_rc\cfusion\wwwroot\WEB-INF\cftags\dump.cfm:704)
...
at cfCollectionPanel2ecfm961210602.runPage
(C:\ColdFusion9\wwwroot\ybocv5\coldbox\system\includes
\panels\CollectionPanel.cfm:40)
We don't use cfdump in production; this looks like ColdBox is trying to display a complex object in a debugger panel and failing.
The only thing I found online so far was this thread in Google's transfer-dev group ... someone who saw a bunch of similar errors and thought maybe it was a CF9 bug. The only reply with any sort of solution was this one, suggesting a fix that seems to be Transfer-specific.
Does anyone know what might be causing these errors? It's not as important to me to fix them as it would be on a production app, but if I'm spamming my logs with these errors, it's hard to find legitimate errors when they do occur.
Update: I've been working with the CollectionPanel.cfm template to identify the root cause, and the exception is consistently thrown here:
<cfelseif isObject(varVal)>
<!--- this cfdump is the guilty party ... --->
<cfdump var="#varVal#" expand="false" top="2">
<cfelse>
I've tried wrapping the cfdump in a try-catch, but the exception is thrown anyway, always from that same line of code. This makes sense, I guess, given that these errors don't have any visible effect on the pages on which they occur.
It appears to not be caused from a <cfdump> instead from a GetMetaData() call.
Specifically when you get the meta data of a cfc, which extends another cfc which has been modified after the current has been compiled (and where GetMetaData has been run) where it needs to update the extends struct in the GetMetaData() return. Cf only generates the meta data struct once, most likely for performance reasons.
I think it might be a bug in cf...
Inside the TemplateProxyFactory.getTemplateFileHelper() it's calling runtime.resolveTemplatePath(compName + ".cfc") where compName is name.replace('.', '/')
All good and well until you use a mapping. If you straight out replace dots with slashes, you'll need to add a leading slash, just like they do in TemplateProxy.getMetaData()
Without the leading slash, resolveTemplatePath() returns null, which triggers the VFSFileFactory.getFileObject() call which tries to get a File object from the parent cfc name.
Before it even gets to the VFSFileFactory, it calls Util.getBaseTemplatePath() with the pageContext. Inside it gets the ServletContext from the pageContext and tries to call getServletPath() so that it can get its real path. Utils.getServletPath() tries to get the attribute "javax.servlet.include.servlet_path" which on my machine (and probably yours) doesn't exist and returns null.
You can check by calling this: isNull(getPageContext().getRequest().getRequest().getAttribute("javax.servlet.include.servlet_path")); - yes, there is supposed to be two .getRequest() calls in there.
So it seems Cf is trying to refresh it's extends struct in a cfc getMetaData() call when the extended file is modified and does it a different way then when it first generated the struct.
In you cf admin, what are you settings under Server Settings > Caching?
Trusted cache? Cache template in request? Component cache? Save class files? Cache web server paths?