Important update 12 July 2010: Railo changed it's code, so the trick underneath doesn't work anymore.
Solution for Railo: simply use <cfhtmlhead action="reset" />
Cross-platform solution: use the resetCFHTMLHead function from the ModelGlue framework:
<!---
Based on original function by Elliot Sprehn, found here
http://livedocs.adobe.com/coldfusion/7/htmldocs/wwhelp/wwhimpl/common/html/wwhelp.htm?context=ColdFusion_Documentation&file=00000271.htm
BlueDragon and Railo by Chris Blackwell
--->
<cffunction name="resetCFHtmlHead" output="false" access="public" returntype="void">
<cfset var my = structnew() />
<cfswitch expression="#trim(server.coldfusion.productname)#">
<cfcase value="ColdFusion Server">
<cfset my.out = getPageContext().getOut() />
<!--- It's necessary to iterate over this until we get to a coldfusion.runtime.NeoJspWriter --->
<cfloop condition="getMetaData(my.out).getName() is 'coldfusion.runtime.NeoBodyContent'">
<cfset my.out = my.out.getEnclosingWriter() />
</cfloop>
<cfset my.method = my.out.getClass().getDeclaredMethod("initHeaderBuffer", arrayNew(1)) />
<cfset my.method.setAccessible(true) />
<cfset my.method.invoke(my.out, arrayNew(1)) />
</cfcase>
<cfcase value="BlueDragon">
<cfset my.resp = getPageContext().getResponse() />
<cfloop condition="true">
<cfset my.parentf = my.resp.getClass().getDeclaredField('parent') />
<cfset my.parentf.setAccessible(true) />
<cfset my.parent = my.parentf.get(my.resp) />
<cfif isObject(my.parent) AND getMetaData(my.parent).getName() is 'com.naryx.tagfusion.cfm.engine.cfHttpServletResponse'>
<cfset my.resp = my.parent />
<cfelse>
<cfbreak />
</cfif>
</cfloop>
<cfset my.writer = my.resp.getClass().getDeclaredField('writer') />
<cfset my.writer.setAccessible(true) />
<cfset my.writer = my.writer.get(my.resp) />
<cfset my.headbuf = my.writer.getClass().getDeclaredField('headElement') />
<cfset my.headbuf.setAccessible(true) />
<cfset my.headbuf.get(my.writer).setLength(0) />
</cfcase>
<cfcase value="Railo">
<cfset my.out = getPageContext().getOut() />
<cfloop condition="getMetaData(my.out).getName() is 'railo.runtime.writer.BodyContentImpl'">
<cfset my.out = my.out.getEnclosingWriter() />
</cfloop>
<cfset my.headData = my.out.getClass().getDeclaredField("headData") />
<cfset my.headData.setAccessible(true) />
<cfset my.headData.set(my.out, createObject("java", "java.lang.String").init("")) />
</cfcase>
</cfswitch>
</cffunction>
[updated 17-oct-2009: combined function did not always work; now corrected with switch if railo/else CF] In case you're using your own white-space reduction implementation in Coldfusion, you are very probably using something like this: But in CF8 and later, as well as in Railo 3.1, the content which is added with <cfhtmlhead/> will be output twice: once it is set in the output for the 'pageContent' variable when getPageContext().getOut().getString() is called, and it is added again when the output stream is actually sent to the client (in the example it would be when getPageContext().getOut().flush() is called). Now, a solution for this double output is to clear the cfhtmlhead content after retrieving it once. A few years ago, I already asked about the possibility to clear this cfhtmlhead buffer at Ben Nadel's site, and even got the answer from Elliott Sprehn: But this code is Adobe Coldfusion only. It does not work in Railo, since there is no function initHeaderBuffer. I did a bit of peeking around in Railo's open source code, and came up with the following function: This way, you can safely keep using your own whitespace reduction functionality, without partial double output! Off course it's much nicer if we could have just one function for both platforms, so here it goes:
[Updated 16-Jan-2010: added some extra code sometimes needed for CF8/9, and made the code usuable in CF7 again (reverted the i<3 / == references)] <cfscript>
pageContent = getPageContext().getOut().getString().trim();
getPageContext().getOut().clearBuffer();
pageContent = REreplace(pageContent, ">\s+<", ">" & chr(13) & chr(10) & "<", "all");//strip whitespace between tags
pageContent = REreplace(pageContent, "[\n\r\f]+", chr(13) & chr(10), "all");//condense excessive new lines into one new line
pageContent = REreplace(pageContent, "\t+", " ", "all");//condense excessive tabs into a single space
writeoutput(pageContent.trim());
getPageContext().getOut().flush();
</cfscript> <cfscript> function resetCFHtmlHead() { var out = getPageContext().getOut(); var method = ""; while (getMetaData(out).getName() is 'coldfusion.runtime.NeoBodyContent')
{
out = out.getEnclosingWriter();
} method = out.getClass().getDeclaredMethod("initHeaderBuffer",arrayNew(1)); method.setAccessible(true); method.invoke(out,arrayNew(1)); } resetCFHtmlHead();
</cfscript> <cfscript> function resetCFHtmlHead() { var args = arrayNew(1); var out = getPageContext().getOut(); var methods = out.getClass().getDeclaredMethods(); args[1]=true; for (var i=1; i lt arrayLen(methods);i=i+1) { if (methods[i].getName() eq '_toString') { methods[i].setAccessible(true); methods[i].invoke(out, args); return; } } } resetCFHtmlHead(); </cfscript><cfscript>
function resetCFHtmlHead() {
var args = arrayNew(1);
var out = getPageContext().getOut();
var methods = out.getClass().getDeclaredMethods();
var i=0;
if (structKeyExists(server, 'railo'))
{
for (i=1; i lt arrayLen(methods); i=i+1)
{
if (methods[i].getName() eq '_toString')
{
args[1]=true;
methods[i].setAccessible(true);
methods[i].invoke(out, args);
return;
}
}
} else // Adobe Coldfusion
{
// It's necessary to iterate over this until we get to a coldfusion.runtime.NeoJspWriter (for CF 8/9)
while (getMetaData(out).getName() is 'coldfusion.runtime.NeoBodyContent')
{
out = out.getEnclosingWriter();
}
methods = out.getClass().getDeclaredMethod("initHeaderBuffer",arrayNew(1));
methods.setAccessible(true);
methods.invoke(out,arrayNew(1));
}
}
resetCFHtmlHead();
</cfscript>







#1 by John - January 16, 2010 at 4:48 AM
Unable to invoke method getDeclaredMethod on object class coldfusion.runtime.NeoBodyContent.
I get the same error on both cf8 and cf9 when trying to execute the function as provided.
#2 by Paul Klinkenberg - January 16, 2010 at 10:27 AM
For me, it was working on a CF8 box. But I did some searching around, and now changed the code in this post. Could you please test it, to see if it works in your sitation?
Are you perhaps using CF8/9 enterprise edition/dev. edition?
Paul
#3 by Sebastiaan - January 22, 2010 at 11:11 AM