[Looking for Charlie's main web site?]

Clearing the ColdFusion template cache programmatically

Note: This blog post is from 2012. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
I was asked today how one might clear the template cache ColdFusion template cache programmatically, as opposed to clicking the button in the CF Admin (Caching) page. The good news is that pretty much anything done in the CF Admin can be done programmatically, via the CF Adminapi, since CF 7. And there is in fact an AdminAPI method to clear the template cache. I'll show the code in a moment.

While it's basically just a single line of code, my regular readers won't be surprised to hear that I feel there's a lot more you ought to know or consider about using that code! So while the code below may be all that some readers need, I hope folks will take time to consider the other related matters I raise. At least scan the headlines to decide. :-) (Indeed, I'm even leaving a more detailed discussion of the Admin API and the template cache in general to another day.)

The code

So here's just one variant of some code one could use to clear the template cache. It can of course be done using tags (CFOBJECT vs createObject) and could be done even more compactly in script. Those preferring other styles can take this ball and run with it.

<cfscript>
adminObj = createObject("Component", "cfide.adminapi.administrator");
adminObj.login("cfadmin_password"); //change to use your CF Admin password (case-sensitive)
rtService = createObject("component", "cfide.adminapi.runtime");
rtService.clearTrustedCache();

// rtService.clearTrustedCache("C:\inetpub\wwwroot\test.cfm,C:\inetpub\wwwroot\test2.cfm");
// rtService.clearTemplateFolderFromCache("C:\inetpub\wwwroot\test");
</cfscript>
<p>Template Cache has been cleared</p>

Before proceeding, let me share a big warning: if you have the trusted cache feature enabled, and you implement the code above, and then you make changes to it (such as to fix a mistake in the code), note that you will NOT see the change implemented because...the trusted cache is turned on, and no changes to ANY templates already compiled INCLUDING THIS ONE will be picked up. You would need turn off the trusted cache feature, and THEN re-execute the template, with your changes, and then if you want to test how it works in flushing the template cache WHILE "trusted cache" is enabled, turn the feature back on and try again.

About the code

The first couple of lines are to "log in". Just as one can't use the CF Admin without a password (unless the Admin has removed that requirement), one can't use the Admin API without knowing the CF Admin password (and it is case-sensitive). (If you don't provide the correct one, the CF error will be "The current user is not authorized to invoke this method.")

The next couple of lines obtain a reference to the runtime CFC, which has the method to clear the template cache. Sadly, the engineers called it "cleartrustedcache". It should have been called clear cleartemplatecache, but they've never seen fit to change it.

(The method does NOT clear any "trusted cache". There's no such thing. There is a template cache, and the "trusted cache" setting, also available on the CF Admin "Caching" page, simply changes how CF processes files found in the template cache--whether it should check the source to see if it has changed. Again, this entry is not the place to elaborate on that.)

Why would one want to clear the template cache?

Again, I don't want to elaborate on the details of template caching, but I'll just say briefly that at least one reason one might want to clear the template cache is because they're using the "trusted cached" feature (also set on the CF Admin "Caching" page), which causes CF to no longer look at the source code on disk to see if it's changed, once a template is loaded in the template cache. If a developer changes a template and wants CF to pick it up (while "trusted cache" is enabled), they can clear the template cache to cause CF to pick up the change. (I'll have more to say on options to limit clearing the *entire* template cache, later in this entry.)

Note that you don't need to clear the "trusted cache" setting. Just clear the cache. (Also, turning off the "trusted cache" setting does not itself clear the template cache.)

Let's now move on to some nuances of clearing the template cache.

Clearing all vs some of the cache

Note that this cleartrustedcache function will by default clear the entire template cache, across all templates and applications on the CF instance. You might reasonably wonder "isn't that throwing the baby out with the bathwater? Why can't we just clear the template cache only for a given template or folder?"

And the good news is that Adobe has indeed addressed that, a couple of ways.

As of CF8, clearing template cache entries for given file(s)

First, as of CF 8, there's a new option for this cleartrustedcache method of the Admin API. Note the commented out final line above, showing use of the optional new argument to clear the template cache for only one or more named templates, which indicated as a comma-separated list of full path\filename values.

Do you find it a hassle to have to do that by code? Wish there was a way to do it via a web page (or in the CF admin)? Well, Ray Camden comes to the rescue with both an Admin extension that adds an admin page to do this, which he calls CacheClearer, or check out his simpler web page/form that he created to do this as well, discussed in this blog entry.

(And if you need to know how to add extensions to the CF Admin, which are new links in a new page that gets created when added, see Ray's nifty guide to using those.)

But before you consider using that approach, note that there are still more options, both as of CF10 and based on some clever code Ray Camden wrote.

As of CF10, clearing all template cache entries for given folder(s)

While it's nice that CF 8 had added the ability to clear the entries for a given file or list of the, sadly you can't specify just a folder and hope it will clear all the template cache entries for files in that folder and subfolders, at least, not until CF 10, which adds a couple ways to do just that.

First, in the CF 10 Admin "Caching" page, there's not only the long-existing button (since CF7) to clear the entire template cache, but there's now a new field and button (under the label, "Clear folder specific template cache") with which you *can* now in fact point to a directory, and tell it to clear the template cache entries only for files whose source came from the given folder, recursively.

Second, CF10 also adds a new method in the API to do this action also. It's not a new argument but a new method: clearTemplateFolderFromCache, and it takes as an argument a directory, and it again will clear the template cache of entries for files whose source came from the given folder, and note that it does this recursively!

With both of these approaches, note that the more files that there are in the template cache which were loaded FROM the named folder and its descendants, then the longer this action will take.

What about clearing it automatically

A natural follow-on question to all this would be, "can't we just set things up so that CF just watches a directory, and whenever a file is changed, it automatically clears the template cache for that file(s)"?

Well, there's nothing built-in to do that, but you can make it happen yourself, watching some directory to see when files change.

Update: In 2013, Ray created yet another post showing just that, code that would auto-flush the cache for specific files that had been found to be recently updated in a named directory. Some might love that. See his post, Programmatically clearing ColdFusion's Trusted Cache By Time.

One other way one could "watch" a directory for changes would be the little-used DirectoryWatcher gateway (another introduced in CF7). This entry is not the place to elaborate on that, but it could be set to watch a given diretory(ies) and then if a file changes, it would call a CFC that you could write, which could then call any of these AdminAPI methods.

The template cache is about compiled CFML code stored in memory, not on disk

Just a couple more points of clarification before we conclude.

I really don't want to delve into general matters of CF's template caching here, but it seems worth heading off a couple of questions "at the pass".

First, note that this matter of clearing the template cache is all about the template cache in memory, which holds the compiled CFML code for templates that are executed during the life of the instance (or until the cache fills, whose size is also controlled on the CF Admin "Caching" page).

On that same page there's another option called "saved class files", which causes CF to saved those results of the compiled templates (.class files) to disk as well, in a cfclasses directory buried deep within the CF directory.

My point in raising this here is that this cleartrustedcache method does ONLY clear the templates from memory. It does NOT clear them from that cfclasses directory. (And generally, you should not have any reason to clear those, which is why there is no function or method to do that. Again, this is not the place to get into an extended discussion of the "save class files" option, when and why to use it, how to resolve problems with it, etc.)

This template cache is not THAT template cache

Second, there's some real potential for confusion when it comes to talking about "template caching" in CF, because CF9 introduced the integrated ehCache functionality, which adds all kinds of power for caching objects, whether strings, CFCs, queries, or even page output (whether a full or partial page). And the engineers chose to refer to the latter (caching page output) as "template caching".

Well, this CF Admin template cache (holding compiled code) is not THAT template cache (holding objects or page content that you have stored via code). They are entirely unrelated to each other, and the CF admin settings (and admin API method above) all apply only to the former, not the latter.

How can I find more about methods in the Admin API

Again, I don't want to get too far into general discussions of the Admin API, but it seems worth pointing out that while you won't find much documentation on the Admin API, you can find details about all the methods in the Admin API, by simply browsing each CFC in the API (they're in the /CFIDE/adminapi/ folder). So for instance, the following request would browse the runtime.cfc in which the cleartrustedcache (and many other methods) would be found:

http://[server]/CFIDE/adminapi/runtime.cfc

When you run that, you should be shown the built-in (and oft-missed) CF component browser tool, which will ask you for your CF Admin password. Some day I should do an entry about that tool! :-)

You'll see there are also methods related to other separate but related buttons on the CF Admin "Caching" page, such as one to clear the component cache added in CF9), clearcomponentcache, and to clear the query cache: clearquerycache. See the help there for more on those and all the other CFCs in the Admin API.

So there you have it: go forth and clear your template cache when you need to, programmatically. And hopefully you'll appreciate now why I really couldn't just leave it at showing just the one line of code!

For more content like this: Need more help with problems?
  • If you may prefer direct help, rather than digging around here/elsewhere or via comments, I can help via my consulting services
  • See that for more on how I can help a) over the web, safely and securely, b) usually very quickly, c) teaching you as we go, and d) with satisfaction guaranteed
Comments
Good tips there Charlie.

Just a follow up, if you have a multi instance environment, with trusted cache on, you need to call the clearTrustedCache() on each instance.

The way we have this done this, is by having an admin extension page (like you suggest) in the CF administrator on the CFusion instance. This calls a CF page per instance to clears its local trusted cache. Works really well and is a one stop button to clear all caches on X amount of instances.
# Posted By Tom Jenkins | 12/14/12 5:15 AM
@Tom, yep, and just to be clear, this is why I'd said that the method cleared the entire template cache "across all templates and applications on the CF *instance*" (emphasis added). I suppose I could have added, "and only that instance, if you have multiple instances", but your comment now will make that clarification. :-)

And yes, fair point that if you have a cluster of instances, sharing the same code base, then if you needed to clear the template cache on one, you'd likely need to clear it on all instances in the cluster. Thanks for pointing it out.
# Posted By Charlie Arehart | 12/14/12 10:10 AM
@Charlie,

Have you ever run into an issue where the template cache is so large that it brings a site down?
# Posted By Steve Withington | 1/23/13 3:23 PM
Found this article from the googles. Works great.

But worried about placing a template somewhere that has the CF Admin password. Is there a way to protect that? Or a way to specify a user account other than the 'admin', say one that had less privileges than 'admin'?

Thanks...Rick...
# Posted By Rick | 1/21/14 4:35 PM
@Rick, what I do is treat it like any other sort of password-protected CF code: i check if a cfadmin var in the session scope exists: if not, I prompt for it, and I use that in the code.

I realize I just showed the password being stored in code above. I was just offering the simplest example and assumed people could/would modify it to suit their tastes. But glad you asked, and hope this comment will suffice to get you/others going on this point.
# Posted By Charlie Arehart | 1/21/14 4:51 PM
@Charlie : thanks for your quick response to an old thread.

I have added code for a login form before the code is entered (wandered into the adminapi docs to figure out how to specify a user other than 'admin'; was quite proud of myself). So that part is working.

But I notice that the number of entries returned by the directorylist command are nowhere near the number of CFM/CFC files on the site. My count stops at about 862.

I have set the requesttimeout setting to "120", but that doesn't help. Can you think of any reason why directorylist is not returning all of the files into the array?

Thanks.
# Posted By Rick | 1/22/14 3:43 PM
@Rick, sorry for the delay in responding to this one. So about "the directorylist command", do you mean the CFML function? Or might you be referring to something in the admin API (since that was also being discussed here)?

As for it not returning all files, and you wondering if a timeout is impacting things, I'd say that if you hit a timeout before it finished, you'd get an error not a low number. So I suspect something else is at play for you.

But first I wonder: why are you doing a directorylist in the first place? Is it that you want to have CF look at ALL files in a folder? Just note that CF10 adds that as a feature of the cleartrustedcache method. But maybe you are wanting to look at all files in a folder and only get those that are updated recently.

Anyway, if indeed you are using the directorylist function, and if the "low" number returned is because you are counting all files in that folder and any subfolders, it could be that the function is not recursing into subfolders. There is an argument to control that. It's not clear from the docs what its default is.

Hope that helps.
# Posted By Charlie Arehart | 2/4/14 7:07 PM
Hey Charlie,

Whenever we are using composition as a style for our cfcs, we are finding that cfcs that are instantiated in the "parent" cfc will not clear from the trustedcache when clearing by file or by the entire directory. The only way we can get this to work is to clear then entire trusted cache.

parent.cfc
function init()
this.exampleChild = new child();
this.exampleChild.newFunctionJustUploaded()

child.cfc
function newFunctionJustUploaded()
return void


We would upload changes to child.cfc, clear child.cfc and parent.cfc and then parent.cfc would bomb stating that newFunctionJustUploaded() is not defined. We try programatically clearing the trusted cache by file and directory repeatedly -- no luck.

The funny thing is, we can try to recreate a test case, but the test never succeeds in demonstrating the problem! Our test cases have zero traffic, so that's the only conclusion we can make. Something under the hood does not allow child CFCs under a composition "chain" to recompile when programatically clearing the trusted cache, even when we clear all files in the composition chain/or the entire directory when there is a moderate amount of traffic to those files.

Unfortunately, the performance hit when clearing the whole trusted cache is pretty substantial, so we try to avoid that whenever possible.

I'm not sure if this comment is a question or a comment, but there it is. This post comes up in google as a top result.
# Posted By Brian | 4/24/14 9:44 AM
Odd that under CF11 our active webservice no longer appear in the listing under the admin. I confirmed that I am on the right admin that is connected to the iis site we are hitting. strange
# Posted By Alex | 4/16/15 1:49 PM
Alex, since CF10, you will not find that CF adds web services to the list in the CF admin anymore. You can add them, but don't need to.

That said, this blog entry is not at all about web services, or CF11. It seems an odd place for you to have raised this issue. :-) FWIW, if you look on the right, I do have a web services category, currently with 8 current entries, and one of them may be a better place to raise such questions (though for now, if you have only a closing comment on this, feel free to add it here).
# Posted By Charlie Arehart | 4/16/15 2:08 PM
We skipped 10 and when to 11 :) I will use the correct section in the future thanks!
# Posted By Alex | 4/16/15 2:15 PM
Hey Charlie,

I have a question in regards of CF9, recently I added a new Jar file to the C:\ColdFusion9\cfusion9_home\WEB-INF\lib folder, this new jar is just a Java 1.5 library with some new functionality, I was doing some tests, but after that the Jar file was no longer necessary and I delete it.

But my application still has visibility of the classes I had on that Jar, I'm facing some caching issues, have you ever seen the same issue ? if so, what do you recommend ? do you know how to clear this kind of java classes and clear this cache ? I tried already from the Admin console but nothing works.

Any help will be very appreciated.
Thanks in advance.
# Posted By Ricardo P. Silva | 2/24/17 10:02 AM
Ricardo, that's an interesting question with a lot more behind it than meets the eye, potentially. So this is a long comment, but I hope to get you to your solution.

1) Let's clarify first what you mean by "my application still has visibility of the classes I had on that Jar".

2) And second, when you say you "deleted" the jar, do you really mean you deleted the file (from that CF lib folder), and restarted CF (which would be required for it to be "gone" from CF)? Or might you mean only that you simply renamed the jar file?

I will say that it sounds like you maybe just renamed it. This is a frequent cause of confusion, because folks think that the name of the file is significant. But to Java, it is not. AT ALL. Java looks in ALL jars and classes (in its classpath) to find the first which matches the class (and optionally package) name requested by the Java code.

3) So let's also clarify what you're "seeing". When you say "my application still has visibility of the classes I had on that Jar", do you mean that you can write code that calls those classes and they work?

4) And even if you would say you really did DELETE the jar file, are you 100% sure that the class you're requesting isn't found by some other Java jar (or class file), that perhaps comes with CF or the underlying CFML server (Jrun in your case)?

5) Or do you perhaps mean that you are running some CFML code which is failing because it refers to these classes, which you feel were deleted, and it's failing because it can't find them?

You see how your problem can be any of a number of things.

6) Even if it's this last issue, of an error arising because you have code still trying to call the classes that you feel you deleted, let me clarify first that you may well still have such CFML code calling such classes. :-) But I'll assume you have confirmed that's not the case.

6a) If your point is that you DO see the errors from pages "still accessing it", and you think you HAVE edited them to remove such access, that's then a different matter. And perhaps that's how you think this challenge somehow related to to the subject of this blog post.

6b) First, if you thought it may be that CF is "caching in the template cache" such code of yours which had referred to this Java class (you removed), but you feel you removed that code referring to it, it's worth noting that if you restart CF, that clears the template cache. Did you do that? did it help?

6c) If you did and it did not (and this latter line of questioning is what you think is going on), the only other possibility I readily see is that perhaps you have CFML classes which have been *saved* (per the "save class files" option I allude to above--but don't elaborate on, as it's beyond the scope of this post). It MAY be possible that you could have saved class files that were from a version of your CFML back when it was still referring to this now-removed Java class (and somehow your edited file is NOT overriding that saved class file. There are reasons, but let's not devolve into that discussion here.) The problem is that it's hard to delete a specific cfclass file for a given CFML template.

6d) In most cases, people with some issue like this (this latter point I'm making, where you once had code referring to a java class, but you removed it, and yet still see errors like it's trying to refer to it) have simply resorted to deleting all their cfclass files (in the wwwroot\WEB-INF\cfclasses folder). That's often overkill, so don't do it unless you're sure that not of the other proposals I make above work first.

Let us know how it goes. I have given numbers to the paragraphs above (in a hierarchy where appropriate), if you may want to easily refer back to a point in any reply.

(And if you remain stuck, I'm confident I could resolve this in a consulting session, in perhaps less than 15 minutes. More at the www.carehart.org/consulting.)
# Posted By Charlie Arehart | 2/24/17 11:32 AM
@Charlie, hello,

Thanks for answering me, I'm going to answer point by point.

1) I was using that java 1.5 Jar with CF9, in other words, I'm calling Java from CF9 this way and was working fine:

<cfset Request.whateverJavaVar = Createobject("java", "com.company.whatever.WhateverClassName") />

Even now when the JAR file is not present into the lib folder and I have restarted the CF9 app server several times.. the Jar is gone and I still do see the CF server still has visibility of the "WhateverClassName" class,.. I was specting an error, but no, no errors calling WhateverClassName.someMethod(), that's why I think the classes were cached or something, that's what I meant when I said "my application still has visibility of the classes I had on that Jar".

2) I actually deleted the JAR file.

3) Yes. and it is crazy, seems to me, the DF server has loaded the definitions of those classes somewhere and I can't clean/erase them.

4) exactly, I'm 100% sure those classes does not exist somewhere else, I was coding those classes from scratch.. there is no way I can have another class name with exactly the same signature into the same package somewhere else.

5, 6, 6a do not apply.

6b) I tried to clear the cache from the admin page, nothing works.

6c) this might be the root cause of the issue, I'm not sure, CF could be loading the definition of those java classes somewhere, and I don't know where.

6d) for me is located at C:\ColdFusion9\cfusion9_home\WEB-INF\cfclasses and it is empty.

Before posting this comment, I did test again, and my local CF9 application server is "reading" this class that is supposed does not exist.

I'm not sure if I mentioned before this is happening on my local environment (my PC) and I do not want to propagate this issue to the actual DEV, QA and PROD environments :o(
# Posted By Ricardo P. Silva | 2/24/17 1:07 PM
OK, Ricardo. Let's try some other things, then. (To be clear, no, I don't think there's some bug here, just a case of you having the class somewhere ELSE than that lib location.)

1) So you said you had put the jar in CF's WEB-INF\lib folder, from which you deleted it. Well, note that there is a sibling to that called classes (WEB-INF\classes), where one can put a .class file (.jars typically go in lib, .class files typically go in classes). CF automatically can load classes or jars from both. Worth double checking to see if you or anyone put a version of your mystery class there.

2) The CF admin also lets you point to STILL OTHER locations to load classes and/or jars. See the "java & vm" page, and its "coldfusion class path" field. Anything there? If so, check those folders.

3) Better still, the CF admin also has a page that prints out ALL the jars it has loaded. See the "Settings Summary" (right under "java & jvm"), and its "CF Server java class path" field, and see if perhaps there's a folder you recognize loading the jar in question (from somewhere not identified above).

4) Finally, you may be able to get the location of the JAR using this code:

<cfdump var="#classLoader.forName("yourpackage.youclassname").getProtectionDomain().getCodeSource().getLocation().tostring()#">

That should print out the location but under some circumstances it may not work. Just to see if it works with a class that CF always has, you could try this:

<cfdump var="#classLoader.forName("macromedia.jdbc.MacromediaDriver").getProtectionDomain().getCodeSource().getLocation().tostring()#">

That reports (on a CF11 server):

C:/ColdFusion11/cfusion/lib/macromedia_drivers.jar

Let us know how you go.
# Posted By Charlie Arehart | 2/24/17 2:23 PM
Copyright ©2019 Charlie Arehart
Carehart Logo
BlogCFC was created by Raymond Camden. This blog is running version 5.005.
(Want to validate the html in this page?)

Managed Hosting Services provided by
Managed Dedicated Hosting