ColdFusion Tips & Tricks

From Hostek.com Wiki
Revision as of 18:43, 2 June 2015 by Seanc (Talk | contribs) (Fixing cfhttp Connection Failures with Portecle)

Jump to: navigation, search

Contents

Converting Application.cfm to Application.cfc

Using an Application.cfc configuration file offers some advantages over the older style Application.cfm configuration files. Some of the main features that an Application.cfc file give you are "functions triggered by Application, Session, Request, and Error events" and "Application-Level Mappings and Custom Tag Paths".

There are only a few steps required to convert an application to use an Application.cfc file:

NOTE: You should ensure that you have a backup of any files before making changes to them.

Create an Application.cfc file

Below is an example Application.cfc file with the minimum requirements:

<cfcomponent>
	<cfscript>
		this.name = hash( getCurrentTemplatePath() ); // unique app name
	</cfscript>
</cfcomponent>

Setup onRequest function in Application.cfc to include the Application.cfm file

This step is only necessary if an Application.cfm file already exists in the root of the application. Below is what the Application.cfc file will look like after this addition:

<cfcomponent>
	<cfscript>
		this.name = hash( getCurrentTemplatePath() ); // unique app name
	</cfscript>
 
	<cffunction name="onRequest" returnType="void">
		<cfargument name="targetPage" type="string" required="true" />
 
		<!--- Include Application.cfm --->
		<cfinclude template="Application.cfm" />
 
		<!--- Include the requested page --->
		<cfinclude template="#ARGUMENTS.targetPage#" />
	</cffunction>
</cfcomponent>

Copy application settings from the cfapplication tag and remove the cfapplication tag

This step is only necessary if a cfapplication tag is used within the application. Each attribute of the cfapplication tag will need to be copied into the cfscript section at the top of the Application.cfc with the pattern [this.attributeName = "value";].

For example. The below cfapplication tag would be converted into our Application.cfc example as follows:

cfapplication tag:

<cfapplication
	name = "my_app_name"
	sessionManagement = "Yes"
	sessionTimeout = "#createTimeSpan(0,0,20,0)#"
	setClientCookies = "Yes">

Application.cfc:

<cfcomponent>
	<cfscript>
		this.name = "my_app_name"; // app name from old cfapplication tag
		this.sessionManagement = "Yes";
		this.sessionTimeout = CreateTimeSpan(0,0,20,0);
		this.setClientCookies = "Yes";
	</cfscript>
 
	<cffunction name="onRequest" returnType="void">
		<cfargument name="targetPage" type="string" required="true" />
 
		<!--- Include Application.cfm --->
		<cfinclude template="Application.cfm" />
 
		<!--- Include the requested page --->
		<cfinclude template="#ARGUMENTS.targetPage#" />
	</cffunction>
</cfcomponent>

NOTE: Do not forget to remove the cfapplication tag after copying the settings into the Application.cfc file.

Now that the change is complete, this is a good time to test the application to ensure everything is working correctly with the new setup.

Per-Application ColdFusion Mappings

In ColdFusion 8 and above, it is possible to create per-application mappings through your site's Application.cfc file. If you wish to convert to using an Application.cfc file, follow the steps here.

Once you have your Application.cfc created, you will insert the following line:

<cfset this.mappings["/test"]="d:\home\yourdomainname.com\wwwroot\test">

On your site though, you would change "/test" to the name of your mapping. IMPORTANT: You need to include the forward slash before the name of your mapping. Also, change "d:\home\yourdomainname.com\wwwroot\test" to the full physical path to the folder you wish to map. Note: The physical path to your FTP root is listed in the "Site Settings" of your control panel at wcp.hostek.com.

To call a template named "testing.cfm" in the "test" directory we just mapped, you would use this line:

<cfinclude template="/test/testing.cfm">

Per-Application Custom Tag Paths

Starting in ColdFusion 8, ColdFusion allows creation of Custom Tag Paths in each site's Application.cfc file. This allows you to create and manage your Custom Tag Paths without having to use CF Administrator (ie. submit a support ticket). The following steps will help you create a Custom Tag Path:

If you do not already have an Application.cfc file in your site's Web root, create one now. Place the following code in the Application.cfc file and save:

<cfcomponent>
<cfset THIS.customtagpaths="d:\home\yourdomain.com\wwwroot\customtagfolder">
</cfcomponent>

In this case, you'd replace "yourdomain.com" with your domain name, and "customtagfolder" with the name of the folder you created for your custom tags.

Now you have successfully added your custom tag path. If you have multiple tag paths to add, try using the following code instead:

<cfcomponent>
<cfset THIS.customtagpaths=ListAppend(THIS.customtagpaths, "d:\home\yourdomain.com\wwwroot\customtagfolder")>
</cfcomponent>

Per-application Robust Exception Information Settings

To enable Robust Exception Information on a ColdFusion application, you will need to add the following to the top of the site's Application.cfc file:

<cfset this.enablerobustexception = true />

Alternatively, if you wish to ensure Robust Exception Information is always disabled for an application, add this to the site's Application.cfc:

<cfset this.enablerobustexception = false />

Per-application JSON Prefix

To enable the JSON Prefix for your application add the following to the site's Application.cfc file, and adjust the secureJSONPrefix as desired:

<cfset this.secureJSON = true>
<cfset this.secureJSONPrefix = "//">

Alternatively, you can disable this feature using the following code instead:

<cfset this.secureJSON = false>

Restart a ColdFusion Application

If you ever need to restart your site's ColdFusion application (to pick up a setting change, etc), you can do so via the ApplicationStop() function in ColdFusion 9+.

To use this you can create a file (ex: restart.cfm) containing the following code:

<cfset ApplicationStop() />
<cflocation url="index.cfm" addtoken="false" />

When you run the file containing that code your ColdFusion Application will be stopped (flushing your application scope), and when the browser is redirected to the index page the application will start again.

CFHTTP Connection Failures over HTTPS

Fixing cfhttp Failures on Shared Hosting

If you try to use <cfhttp> to connect to a secure site (over HTTPS), you may receive the following error: "Connection Failure: Status code unavailable"

To fix this add the following code to your site's "Application.cfm" file (below the 'cfapplication' tag):

<!--- fix for HTTPS connection failures --->
<cfif NOT isDefined("Application.sslfix")>
	<cfset objSecurity = createObject("java", "java.security.Security") />
	<cfset objSecurity.removeProvider("JsafeJCE") />
	<cfset Application.sslfix = true />
</cfif>

If your site uses an "Application.cfc" file instead, then just place that code in the "'onApplicationStart()" method of that file. After making that adjustment you'll need to restart your ColdFusion application as shown here. If you still run into issues though, you will need to submit a support ticket asking our team to install the remote site's SSL certificate into ColdFusion's Java Certificate Store.

Fixing cfhttp Failures on VPS Hosting

If you are having issues connecting to a site or file from with ColdFusion over HTTPS, you can import the remote site's SSL certificate into the the Java SSL Certificate Store used by ColdFusion.

Fixing cfhttp Connection Failures with Keytool

1) Set Java environment
First, you'll need to find the version of Java being used by ColdFusion. To do this, open the jvm.config for your server. Depending on your server's version of ColdFusion, that file is at one of the following locations:

ColdFusion 9 single-instance: C:\ColdFusion9\runtime\bin
ColdFusion 9 multi-instance: C:\ColdFusion9\bin
ColdFusion 10: C:\ColdFusion10\cfusion\bin

Note: If your server is a Linux/cPanel server, the jvm.config file will be in one of the following locations: ColdFusion 9: /usr/local/coldfusion9/bin ColdFusion 10: /opt/coldfusion10/cfusion/bin
Once opened, look for "java.home" at toward the top of the jvm.config file. You use the value of that variable in the next command. For example, you may see this:

   java.home=C:\\ColdFusion10\\jre

In that case, you would use C:\ColdFusion10\jre as the value of JAVA_HOME as shown below. Open a command prompt and issue the following commands:

   C:\ColdFusion10\jre>set JAVA_HOME=C:\ColdFusion10\jre
   C:\ColdFusion10\jre>set PATH=%PATH%;%JAVA_HOME%\bin

Note: If your server is a Linux/cPanel server, use the following commands (case-sensitive) in your terminal: This example assumes that the JRE is located at /opt/coldfusion10/jre

   export JAVA_HOME=/opt/coldfusion10/jre
   export PATH=$PATH:/opt/coldfusion10/jre

2) List the Keystore Contents

If your Java installation is at C:\ColdFusion10\jre, then navigate to C:\ColdFusion10\jre\bin:

   cd C:\ColdFusion10\jre\bin

If you're using a Linux/cPanel server, use this command instead:

   cd /opt/coldfusion10/jre/bin

Now you can list the keystore contents (Windows & Linux):

   keytool -list -storepass changeit -keystore ../lib/security/cacerts

Example output:

   Keystore type: JKS
   Keystore provider: SUN
   Your keystore contains 76 entries

3) Import certificate in to keystore and list to check added
(assumes you've downloaded the certificate to c:\temp\inet.cer (Windows) or /temp/inet.cer (Linux/cPanel)

Windows

   keytool -importcert -storepass changeit -alias inet -keystore ../lib/security/cacerts -trustcacerts -file c:\temp\inet.cer

Linux

   keytool -importcert -storepass changeit -alias inet -keystore ../lib/security/cacerts -trustcacerts -file /temp/inet.cer
   Trust this certificate? [no]: y
   Certificate was added to keystore

Now verify the keystore contains your new certificate

   keytool -list -storepass changeit -keystore ../lib/security/cacerts

Example output:

   Keystore type: JKS
   Keystore provider: SUN
   Your keystore contains 77 entries

4) Restart the ColdFusion application service so the keystore is re-read.

5) Run your cfhttp request - HTTPS works now!

Fixing cfhttp Connection Failures with Portecle

If you'd rather import certificates into the Java SSL Keystore through a GUI, follow these directions to use a tool named Portecle to do so:

  1. Ensure your JAVA_HOME variable is set correctly as described above.
  2. Download Portecle from Sourceforge: Portecle Project Homepage
  3. Extract the files
  4. Open a Command Prompt and navigate to the extracted directory
  5. Issue this command to launch Portecle:
    java -jar portecle.jar
  6. In Notepad, open your jvm.config file to find the JVM PATH for ColdFusion's JVM; look for java.home={path here}
  7. In Portecle click File, Open Keystore File
  8. Browse to {JVM PATH}\jre\lib\security to the path, and open the cacerts file; Enter Password: changeit
  9. Click on Tools, Import Trusted Certificate, select the certificate you wish to import.
    • To obtain the certificate, you can navigate in a browser to the site where the certificate resides, then download the certificate to a CER (X.509 format) file through the browser.
  10. Click OK to import and YES to accept the certificate as trusted.
  11. Click OK again, usually you won't need to change the Alias name;click OK to finish.
  12. Click File, Save Keystore.
  13. Close Portecle.
  • A ColdFusion Restart is necessary for this to take effect.

Fixing CFHTTP Failures Related to Cached DNS Records

This solution will prevent Java from caching DNS records for the life of the ColdFusion process. Instead, Java will refresh its records periodically.

First, you'll need to find the version of Java being used by ColdFusion. To do this, open the jvm.config for your server. Depending on your server's version of ColdFusion, that file is at one of the following locations:
ColdFusion 9 single-instance: C:\ColdFusion9\runtime\bin
ColdFusion 9 multi-instance: C:\ColdFusion9\bin
ColdFusion 10: C:\ColdFusion10\cfusion\bin

Note: If your server is a Linux/cPanel server, the jvm.config file will be in one of the following locations: ColdFusion 9: /usr/local/coldfusion9/bin ColdFusion 10: /opt/coldfusion10/cfusion/bin
Once opened, look for "java.home" at toward the top of the jvm.config file. You use the value of that variable to find the location of the Java installation used by ColdFusion.

For example, on Windows you may see this:

   java.home=C:\\ColdFusion10\\jre

On Linux you may see this:

   java.home=/opt/coldfusion10/jre

Navigate to the security folder within the Java installation used by ColdFusion. For example:
Windows (open in Windows Explorer)

   C:\ColdFusion10\jre\lib\security\

Linux\cPanel

   cd /opt/coldfusion10/jre/lib/security/

Back-up, then edit the java.security file within that folder and change the following line:
From

   #networkaddress.cache.ttl=-1

To

   networkaddress.cache.ttl=600

Note: The above value refreshes DNS records every 600 seconds (10 minutes). You may adjust it to whatever you feel is appropriate for your server.

Now Save the file then Restart ColdFusion, and the new DNS caching setting will take effect.

CFMAIL Multi-Part Emails

Sending emails with both Text and HTML parts helps reduce the chance of your messages getting caught by a mail server's spam filter. It also helps ensure your recipients can read the message regardless of the mail client being used. The easiest way to do this is to store your message in a variable using <cfsavecontent> then adding it to <cfmail> using <cfmailpart> as shown in the example below:

<!--- Store your message in a variable --->
<cfsavecontent variable="myemailcontent">
Hello,
 
This is some plain text. <br />
<b>And this is some more text in HTML. It will appear in plain-text for anyone who views the Text part of this email, though.</b>
</cfsavecontent>
 
<!--- Function to strip HTML from message while preserving line breaks --->
<cffunction name= "textMessage" access= "public" returntype= "string" hint= "Converts an html email message into a nicely formatted with line breaks plain text message">
    <cfargument name= "string" required= "true" type= "string">
    <cfscript>
      var pattern = " <br>";
      var CRLF = chr( 13) & chr( 10);
      var message = ReplaceNoCase(arguments.string, pattern, CRLF , "ALL");
      pattern = "<[^>]*>";
    </cfscript>
    <cfreturn REReplaceNoCase(message, pattern, "" , "ALL")>
</cffunction>
 
<!--- Now send the email. When adding the Text part, we'll use the textMessage() function we just created to strip out HTML tags. --->
<cfmail from="sender@domain.com" to="recipient@anotherdomain.com" subject="Multi-part Email with CFMAIL" type="html">
    <cfmailpart type= "text/plain" charset= "utf-8">#textmessage(myemailcontent)#</cfmailpart>
    <cfmailpart type= "text/html" charset= "utf-8">#myemailcontent#</cfmailpart>
</cfmail>

Reference: CFMAIL the right way

Scheduling Tasks in ColdFusion

On occasion shared ColdFusion hosting customers need to setup Scheduled Task to run files on a cycle.

This can be done with the following steps, making use of ColdFusion's <cfschedule> tag:

  1. Create a file locally using any text editor, save the file with the .CFM extension (example: setschedule_example.cfm).
  2. Copy and past in the code example below taken from ColdFusion's Documentation and save.
  3. Replace the data in the example note the following recommendations.
    !- Name each file made for creating a schedule with the name of the task so you can reference the task later if needed. Specific naming will also make it more difficult for someone to randomly run the file.
    !- If you need to schedule a job to run monthly on any date in the range 28-31, read about how ColdFusion will handle the scheduling in the ColdFuison8 documentation referenced below.
  4. Working example, the code example below is a working tested solution for getting the weather for a specific zip code and the task to email the results.

Scheduled Task

<!-- This sets the initial task, if your just wanting to set the schedule -->
<cfschedule action = "update"
    task = "Weather_Send" 
    operation = "HTTPRequest"
    url = "http://test.hostek.net/weather_send.cfm"
    startDate = "7/6/09"
    startTime = "09:30 AM"
    interval = "3600"
    resolveURL = "Yes"
    requestTimeOut = "600"
    mode = "application">
 
<!-- This allows for the task created to be deleted, just uncomment and change the task name. -->
<!-- cfschedule action = "delete"
    task = "Weather_Send"-->
 
<!-- This allows for the task to be paused, just uncomment and change the task name. -->
<!-- cfschedule action = "pause"
    task = "Weather_Send"-->
 
<!-- This allows for the task resumed if paused, just uncomment and change the task name. -->
<!-- cfschedule action = "resume"
    task = "Weather_Send"-->

Weather Collector

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>CF External Weather Checker</title>
</head>
 
<body>
 
<cfset zip="12345">
 
<cfinvoke webservice="http://ws.cdyne.com/WeatherWS/Weather.asmx?wsdl" method="getCityWeatherByZIP" returnvariable="aWeatherReturn">
     <cfinvokeargument name="ZIP" value="#zip#"/>
</cfinvoke>
 
<cfif aWeatherReturn.temperature EQ "">
<cfoutput> I cannot get the weather for #zip# external http connections must be DOWN.</cfoutput>
<cfelse>
<cfset message="The temperature for #zip# (Your city) is #aWeatherReturn.temperature# degrees.">
</cfif>
 
<cfif message NEQ "">
 
<cfmail from = "weather.server@test.com" to = "test@test.com" subject = "Weather checker">
 
#message#
 
</cfmail>
 
</cfif>
 
</body>
</html>

Note: We highly recommend setting the mode attribute of cfschedule to application. This will ensure your site's application is the only one allowed to modify the task.

More information on using CFSchedule

Session Management - Handling Bots and Spiders

Robots.txt File

First and foremost we suggest creating a robots.txt file in the web root of the domain to address two issues. First to control the rate at which the website is being crawled which can help prevent a bot/spider from creating a massive number of database connections at the same time. Second to prevent specific bots from crawling the website.

Please see our robots.txt article for more information on implementing a robots.txt on your site.

Lower Session Timeouts for Bots and Spiders

Next we suggest setting your session timeout specifically lower for bots and spiders. These spiders and bots will crawl a page and when a session (ColdFusion) is created, it will persist during then entire page load. The page fully loaded allows the bot or spider to get the information from the Web page AND allows the session to expire quickly protecting ColdFusion from effects similar to a memory leak.

To do this, implement the appropriate solution for your site below:

If using Application.cfm

Place this code at the top of your Application.cfm file:

<!--- This checks if a cookie is created, for bots this will return false and use the low session timeout --->
<cfif StructKeyExists(cookie, "cfid") or StructKeyExists(cookie, "jsessionid")>
 <cfset REQUEST.sessionTimeout = CreateTimeSpan(0,0,30,0) />
<cfelse>
 <cfset REQUEST.sessionTimeout = CreateTimeSpan(0,0,0,2) />
</cfif>

Then use the REQUEST.sessionTimeout variable to specify the session timeout period in your cfapplication tag:

<cfapplication name="myawesomeapp"
     sessionmanagement="Yes"
     sessiontimeout="#REQUEST.sessionTimeout#">

If using Application.cfc (tag-based)

If you primarily use cfml tags in your Application.cfc, you can set the Session Timeout like this:

<!--- This checks if a cookie is created, for bots this will return false and use the low session timeout --->
<cfif StructKeyExists(cookie, "cfid") or StructKeyExists(cookie, "jsessionid")>
 <cfset this.sessiontimeout = CreateTimeSpan(0,0,30,0) />
 <cfelse>
 <cfset this.sessiontimeout = CreateTimeSpan(0,0,0,2) />
</cfif>

If using Application.cfc (cfscript)

If instead, you're using cfscipt in your Application.cfc, you'll set the custom Session Timeout like this:

// This checks if a cookie is created, for bots this will return false and use the low session timeout
if (StructKeyExists(cookie, "cfid") || StructKeyExists(cookie, "jsessionid")){
this.sessionTimeout 	= createTimeSpan(0,0,30,0);
} else {
this.sessionTimeout 	= createTimeSpan(0,0,0,2);
}

Reference: Session Management code examples for the Application.cfm

Creating Client Variables Tables for MySQL Databases

If you need your datasource set up as a ColdFusion Client Variables Store, you can enable the 'Client Variables option in your ColdFusion datasource within the WCP control panel.

Please note, if your datasource MySQL DSN, you'll need to create the necessary tables prior to using the Client Variable Store. To do this you would need to create two tables, one named "cdata" and one named "cglobal". The SQL you'd use to create those tables is below:

Table: cdata

 CREATE TABLE IF NOT EXISTS cdata (
          cfid varchar(64) NOT NULL default '',
          app varchar(64) NOT NULL default '',
          data longtext NOT NULL,
          PRIMARY KEY (cfid,app)
     );

Table: cglobal

CREATE TABLE IF NOT EXISTS cglobal (
          cfid varchar(64) NOT NULL default '',
          data longtext NOT NULL,
          lvisit timestamp,
          KEY cfid (cfid),
          KEY lvisit (lvisit)
     );

Output CF Error details without CFDump

It is common in an error handler that you want to output all of the error details to the screen, a file, or an email. Therefore, the cfdump tag is commonly used for this; and, while this works well in development, it is not always the best practice on a production site because of the performance of the cfdump tag due to its use of reflection (Runtime type introspection).

A better performing alternative is to output the information you want directly from the Error/Exception struct within a 'cfoutput' tag. This can be done by looking up the cferror structure or the cfcatch structure in the ColdFusion docs to see what is available and what values you might want to output:
Error: https://wikidocs.adobe.com/wiki/display/coldfusionen/cferror
CFCatch: https://wikidocs.adobe.com/wiki/display/coldfusionen/cfcatch

Cfdump Custom Tag Alternative

You can also use the following link to download an example CF custom tag that will give a similar error output as when using the cfdump tag on an error variable:
http://hostek.com/tutorials/ColdFusion/CF_OutputError.zip


Below is the custom tag's usage:


In the error handler specified in your 'cferror' tag:

<cf_OutputError Error="#Error#" />

The above code would replace:

<cfdump var="#Error#" />

Or, in a cfcatch block:

<cftry>
   ...
<cfcatch>
   <cf_OutputCFCatch CFCatch="#CFCatch#" />
</cfcatch>
</cftry>

Configure ColdFusion to Handle html and htm Files

Enable HTML/HTM as CFML on Shared Accounts

On our ColdFusion servers, the best way to process HTML files (.html, .htm) as ColdFusion/CFML (.cfm files) is by using a set of rewrite rules that route the HTML files through a ColdFusion "controller" script. The main benefits of this approach are that it is easy to implement on a site-by-site basis, and it works with any version of ColdFusion. To implement this approach on your site, follow the steps below:

Step 1: Add Rewrite Rules to Route HTML Files through the CFM Controller

If you have a '.htaccess' file in your webroot, add the rules below to the top of that file. Otherwise, create a file named '.htaccess' in your site's web root and place these rules within it:

For Sites Using .HTML Files
#Rewrite requests without script name to index.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*) /index.html   [R]
 
# REDIRECT to change the address in the browser address bar
RewriteRule ^/htmlcontrol.cfm$   /$1.html   [R]
 
# REWRITE so that the correct page executes when /cart is the URL
RewriteRule ^(.*)\.html htmlcontrol.cfm/?pageName=$1   [L]
For Sites Using .HTM Files

NOTE: If your site uses .htm files instead of .html files, use this set of rules instead. The only difference is html is replaced with .htm.

#Rewrite requests without script name to index.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*) /index.htm   [R]
 
# REDIRECT to change the address in the browser address bar
RewriteRule ^/htmlcontrol.cfm$   /$1.htm   [R]
 
# REWRITE so that the correct page executes when /cart is the URL
RewriteRule ^(.*)\.htm htmlcontrol.cfm/?pageName=$1   [L]

Step 2: Create the ColdFusion Controller Script (htmlcontrol.cfm)

Now we just need to create a ColdFusion script that will process the HTML files. To do this, create a file named htmlcontrol.cfm within your site's web root. Place this CFML code within the file:

CFML for Sites Using .HTML Files
<cfinclude template="#URL.pageName#.html" >
CFML for Sites Using .HTM Files
<cfinclude template="#URL.pageName#.htm" >

Once you save the controller script, your site will begin processing any ColdFusion/CFML code within your HTML files.

Enable HTML/HTM as CFML on a VPS

In case you need to process ColdFusion code in your .htm or .html files, here is what you will need to do to get this to work. This is based on using ColdFusion on one of our dedicated server hosting accounts on a Windows server.

NOTE: This will affect every site on the server, so use cautiously.

First, you will need to edit the web.xml file located generally at C:\ColdFusion10\cfusion\wwwroot\WEB-INF

Open this file and look for coldfusion_mapping_1.

Scroll down the file until you see the last number increment like:

<servlet-mapping id="macromedia_mapping_15">

Then add the following right below the closing </servlet-mapping> of the last number increment item:

    <servlet-mapping id="coldfusion_mapping_16">
        <servlet-name>CfmServlet</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>
    <servlet-mapping id="coldfusion_mapping_17">
        <servlet-name>CfmServlet</servlet-name>
        <url-pattern>*.html/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping id="coldfusion_mapping_18">
        <servlet-name>CfmServlet</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>
    <servlet-mapping id="coldfusion_mapping_19">
        <servlet-name>CfmServlet</servlet-name>
        <url-pattern>*.htm/*</url-pattern>
    </servlet-mapping>

Save this file and exit.

Now in IIS, setup a mapping for the site:

  1. In IIS 7+ click the server name section (right below the Start Page in the left-hand navigation), then double-click the Handler Mappings icon.
  2. Select and "edit" the *.cfm record and copy the value of "executable". Now hit Cancel and then click Add Script Map.
  3. Paste the executable value copied from the *.cfm record and type *.htm into the Request Path and hit OK.
  4. Repeat the above steps to add a handler for *.html
Lastly, open the uriworkermap.properties file for your ColdFusion 10 IIS Connector in a text editor such as Notepad. On a standard ColdFusion installation this is located at:
C:\ColdFusion10\config\wsconfig\1\uriworkermap.properties
Copy the following lines, paste them at the bottom of the file, then save and close the file:
/*.html = cfusion
/*.htm = cfusion

Now restart the ColdFusion service and IIS. ColdFusion should begin processing CFML within htm/html files now.

Increase the ColdFusion Post Parameters Limit

ColdFusion 10

In ColdFusion 10, you can easily increase the value of ColdFusion's postParametersLimit via the ColdFusion Administrator. Once logged into the ColdFusion Administrator, click the Settings link then scroll to the bottom of the page. Set the value for the Post Parameters Limit to the desired limit and click the submit button.

ColdFusion 9 and below

To adjust the Post Parameters Limit setting in ColdFusion 9 and below, you will have to edit the server's neo-runtime.xml file which is located here on a standard installation:
C:\ColdFusion9\lib

Open that file in a text editor such as Notepad, then search for the postSizeLimit tag. It will look similar to this:

<var name='postSizeLimit'><number>100.0</number></var>

Immediately after that set of tags, paste this chunk of text:

<var name='postParametersLimit'><number>1000.0</number></var>

Once you've adjusted the file, you'll just need to save your changes and restart ColdFusion for the new setting to go into effect. Note: The value of 1000 is just an example, so you can increase it as needed.

Loading custom Java library or Java Libraries (jar or class files) in ColdFusion 10

ColdFusion 10 makes it easy to load Java libraries into your ColdFusion application without having to restart ColdFusion. All that's required is your application define the 'THIS.javaSettings' attribute within the site's Application.cfc like below:

<cfset THIS.javaSettings = {LoadPaths = ["/javafiles/"], loadColdFusionClassPath = true, reloadOnChange=false}/>

The above code will check the javafiles directory in your Web root for 'jar' and 'class' files and make any libraries within the directory accessible from your ColdFusion application. If you modify the JAR files in your javafiles directory though, ColdFusion will need to be restarted to load the new versions of the JAR files.

References:

How to handle ColdFusion Error Permission denied for creating Java object: coldfusion.server.ServiceFactory

When using Mura or using Transfer ORM

Issue

If you are using Mura or using Transfer ORM and you get this error, Permission denied for creating Java object: coldfusion.server.ServiceFactory, you are likely using an outdated version of Mura and also are probably on a ColdFusion 9 server. The Transfer ORM component causing this issue has not been updated to work with ColdFusion 9. There is a quick fix though:

Solution

Find the file named CFMLVersion.cfc which should be at /wwwroot/requirements/transfer/com/factory.

Edit that file and find the line that has:

if(server.coldfusion.productversion.startsWith("8"))

And change that to:

if(server.coldfusion.productversion.startsWith("8") OR server.coldfusion.productversion.startsWith("9"))

Save the file and it should now work.

NOTE: Since this is likely running an outdated version of Mura, we highly recommend updating Mura to the latest version to take advantage of numerous performance and security enhancements.

When using DataMgr

If you get this error while using DataMgr.cfc, the changes described below will solve this problem:

Here is the section of code from the original DataMgr.cfc:

<cffunction name="getDataBase" access="public" returntype="string" output="no" hint="I return the database platform being used.">
 
	<cfset var connection = 0>
	<cfset var db = "">
	<cfset var type = "">
	<cfset var qDatabases = getSupportedDatabases()>
 
	<cfif Len(variables.datasource)>
		<cfset connection = getConnection()>
		<cfset db = connection.getMetaData().getDatabaseProductName()>
		<cfset connection.close()>
 
		<cfswitch expression="#db#">
		<cfcase value="Microsoft SQL Server">
			<cfset type = "MSSQL">
		</cfcase>
		<cfcase value="MySQL">
			<cfset type = "MYSQL">
		</cfcase>
		<cfcase value="PostgreSQL">
			<cfset type = "PostGreSQL">
		</cfcase>
		<cfcase value="Oracle">
			<cfset type = "Oracle">
		</cfcase>
		<cfcase value="MS Jet">
			<cfset type = "Access">
		</cfcase>
		<cfcase value="Apache Derby">
			<cfset type = "Derby">
		</cfcase>
		<cfdefaultcase>
			<cfif ListFirst(db,"/") EQ "DB2">
				<cfset type = "DB2">
			<cfelse>
				<cfset type = "unknown">
				<cfset type = db2>
			</cfif>
		</cfdefaultcase>
		</cfswitch>
	<cfelse>

Here is what the modified code should look like (this sample assume MySQL)

<cffunction name="getDataBase" access="public" returntype="string" output="no" hint="I return the database platform being used.">
 
	<cfset var connection = 0>
	<cfset var db = "">
	<cfset var type = "">
	<cfset var qDatabases = getSupportedDatabases()>
 
	<cfif Len(variables.datasource)>
		<!-- cfset connection = getConnection() -->
		<!-- cfset db = connection.getMetaData().getDatabaseProductName() -->
		<!-- cfset connection.close() -->
 
		<cfswitch expression="#db#">
		<cfcase value="Microsoft SQL Server">
			<cfset type = "MSSQL">
		</cfcase>
		<cfcase value="MySQL">
			<cfset type = "MYSQL">
		</cfcase>
		<cfcase value="PostgreSQL">
			<cfset type = "PostGreSQL">
		</cfcase>
		<cfcase value="Oracle">
			<cfset type = "Oracle">
		</cfcase>
		<cfcase value="MS Jet">
			<cfset type = "Access">
		</cfcase>
		<cfcase value="Apache Derby">
			<cfset type = "Derby">
		</cfcase>
		<cfdefaultcase>
			<cfif ListFirst(db,"/") EQ "DB2">
				<cfset type = "DB2">
			<cfelse>
				<cfset type = "unknown">
				<cfset type = "db2">
			</cfif>
		</cfdefaultcase>
		</cfswitch>
                <cfset type = "MYSQL">
	<cfelse>

Summary of changes:

These 3 lines were commented out:

		<!-- cfset connection = getConnection() -->
		<!-- cfset db = connection.getMetaData().getDatabaseProductName() -->
		<!-- cfset connection.close() -->

This line needed quotes around db2:

		<cfset type = "db2">

And lastly, this line needed added:

                <cfset type = "MYSQL">

NOTE: If you are using an MS Access database instead of MySQL, replace MYSQL with msaccessjet on the line that is added.

How to handle ColdFusion Error Security: The requested template has been denied access to {file/directory}

Issue

Our shared servers have ColdFusion Sandbox Security enabled, which requires absolute filesystem paths to be provided to tags and functions that interact with the filesystem. If you receive an error that starts with Security: The requested template has been denied access to ..., then it is followed by a relative path, you'll need to replace the relative path with a full path.

Solution

One way to do this is to hard-code the path (d:\home\sitename.com\wwwroot\filename.jpg), but that can cause portability problems if your site is ever moved to a different environment.

A better way to do this would be to "wrap" your relative path with the ExpandPath() function. The ExpandPath() function will automatically detect the absolute filesystem path to the file, and ColdFusion will no longer give you a permissions error.

More info: Adobe Documentation - ExpandPath

How to handle ColdFusion COM Object Error java.lang.RuntimeException: Can not use native code: Initialisation failed

The error java.lang.RuntimeException: Can not use native code: Initialisation failed is related to calling a 32-bit COM object from within a 64-bit ColdFusion installation.

The simplest way to bypass this error is to write a small ASP Webservice to proxy the call to the COM object as shown in Option 2 of this blog post: 32-bit Components on 64-bit ColdFusion

Alternatively, you can ask Support to move your site to a 32-bit ColdFusion server.

Using SeeFusion to Monitor ColdFusion Performance on a VPS/Dedicated Server

To use Seefusion, visit the address mentioned in your server's Welcome email.

Once loaded, you'll see a summary of memory consumption, average response time, number of requests processed by ColdFusion per second, and a view of currently running ColdFusion requests.

Finding Scripts to Optimize

When using Seefusion it is helpful to look at the Slow section of the request monitor. This will show you recent requests that took longer than 8 seconds to complete, giving you a good idea of what scripts need optimization.

Stack Tracing with Seefusion

Additionally, when a request is running in the Active section of Seefusion's request monitor, you can click the paper stack icon to the left of the request to view a stack trace of the request. A stack trace tells you what line of code is currently being processed by the request.

Once the stack trace loads, start at the top and work your way down until you find a recognizable path to a ColdFusion template (eg. c:\home\mysite.com\wwwroot\index.cfm: 47). This tells you the template currently being executed followed by the line number being processed at that moment in time. If a request consistently shows the same line of code in subsequent stack traces, then you've found the main area to focus on optimizing.

To make deciphering stack traces easier, you can also click the Seestack button at the top of the stack trace window. This will send the stack trace to a service that will analyze the trace and attempt to tell you where you need to focus.

Viewing Metrics over Time

If you want to watch how response times and memory utilization in a more granular manner than the dashboard graphs show, you'll want to click the Counters button at the top of SeeFusion. Once on the Counters page you can select a time interval, then have Seefusion display performance metrics at the interval you selected. This is helpful to ensure requests are completing quickly and not exhausting ColdFusion's memory.

How to Wrap Your ColdFusion DSN with Seefusion

If you wish to have Seefusion monitor your server's query activity, you'll need to "wrap" your DSN with SeeFusion's JDBC driver so Seefusion can monitor the DSN's activity.

Install SeeDSN

SeeDSN is a plugin for ColdFusion Administrator that makes it easy to wrap a DSN with Seefusion. Follow these directions to install SeeDSN:

  1. Download the SeeDSN archive here.
  2. Extract the seedsn folder within the archive to your /CFIDE/Administrator/ folder. This means it will be located at /CFIDE/Administrator/seedsn once extracted.
  3. Move /CFIDE/Administrator/seedsn/custommenu.xml to /CFIDE/Administrator/custommenu.xml

Add Seefusion.jar to the ColdFusion Classpath

In order for ColdFusion to use Seefusion's JDBC driver, you'll need to ensure seefusion.jar is on your ColdFusion class path. Follow these directions to add seefusion.jar to the Coldfusion class path:

  1. Log into your server's ColdFusion Administrator
  2. Click the Java and JVM link on the left, under Server Settings.
  3. In the box labeled ColdFusion Class Path add the path to your seefusion.jar file and click Submit Changes. For example, if it is located in ColdFusion's "WEB-INF\lib" folder, you can add this to the Class Path: {application.home}/wwwroot/WEB-INF/lib/seefusion.jar.
    • Each path in the ColdFusion Class Path is separated by a comma, so be sure to add a comma right before the path to seefusion.jar (do not add any spaces).
  4. Restart ColdFusion after modifying the class path

Wrap a DSN using SeeDSN

Once you've installed SeeDSN and restarted ColdFusion, you can wrap a DSN with the SeeFusion JDBC driver. Follow these instructions to do so:

  1. Log into ColdFusion Administrator
  2. Expand the SeeFusion navigation menu on the left and click Datasource Wrapper
  3. On the Datasource Wrapper page, you'll see a list of DSNs on your server. To wrap a DSN, click the Start Start.png icon next to your DSN. SeeDSN will automatically wrap your DSN with the SeeFusion driver and display OK if it is successful.

Reference: WebApper Blog - Using SeeDSN JDBC Wrapping Tool

Using fckEditor on ColdFusion 10 or Higher

When getting the following error for fckEditor:

"The server didn't reply with a proper XML data. Please check your configuration."

If you are on a ColdFusion 10+ server this will be cause by the FileUpload() function that is being used. In ColdFusion 10+ FileUpload is a built-in function name, so you'll need to rename the FileUpload function used in fckeditor. You can update the text for fckeditor by changing all instances of "FileUpload" to "fckFileUpload" to remove this conflict.

Optimze CFIMAGE Rendering in Three Steps

USE

When full size images are required, re-sized images need to be used for displaying smaller images or thumbnails and the application needs to perform at optimal speed for displaying images in a browser.

KEY POINTS

Except for during development cfimage action="writeToBrowser" should not be used to display images. Use CFIMAGE to resize images ONCE, if possible during upload but if page timeouts make this impossible break up the task by using a CFC to check and re-size images as needed.

SUMMARY

Those sites that display many images often times also upload many photos via form or via FTP and need to display both the FULL size images and smaller images for thumb nails or (small, med, large) optional sizes. The process of uploading images using CFFile can impose time constraints specifically for large files, or if the coldfusion page timeouts are set lower than is possible for large file upload and re-size jobs. To overcome this issue we can write a simple CFC for resizing the images after the upload is complete and the page is run for the first time. This will be ideal for either form based upload or FTP upload making this solution very versatile.

Step 1 - Create the CFC for re-sizing and writing images to disk

Create file "GetResizedImage.cfc" in the directory with the CFM files that display images. Use the code below for the contents of this file and modify as needed.

<cfcomponent>
	<cffunction name="GetImage" hint="Re-sizes images for display in album">
<!--- Set the image path where photos exist --->
<cfset imgpath = "imgdir/"/>
<!--- Set the domain path, allows reuse resized images on other sites --->
<cfset domain = "domain.com"/>
<!--- Re-writes image extension if for alternates of JPG, and adds _resized to differentiate from fullsize images --->
<cfset rfile= "#REReplace("#img#",".(jpg|JPG|JPEG|jpeg)","_resized.jpg")#">
<!--- Checks if file is already resized --->
        <cfif FileExists("d:\home\#domain#\wwwroot\" &"#imgpath#" & "#rfile#")>
           <cfset myImage="http://#domain#/#imgpath##rfile#">
         <cfelse>
<!--- Resizes image if it has not been done already --->
            <cfset myImage=ImageNew(URLDecode("d:\home\#domain#\wwwroot\" & "#imgpath#" & "#img#"))>
                    <cfset ImageResize(myImage,"175","175","bilinear")>
<!--- Saves image, and to eliminate problems with url friendly encoding when getting our images re-replace %20 with no-space --->
                    <cfimage source="#myImage#" action="write" overwrite=true destination="d:\home\#domain#\wwwroot\#imgpath##REReplace("#rfile#","%20"," ","ALL")#">
<!--- Set the new path for the image for browser output --->
			<cfset myImage="http://#domain#/#imgpath##rfile#">
		</cfif>
<!--- Return the image variable --->
	<cfreturn myImage>
	</cffunction>
</cfcomponent>

Step 2 - Invoke the CFC

<!--- Generate image name from query --->
<cfoutput query="MyEvent">
<!--- Invoke CFC to check if resized image exists, if not resize and output URL for resized image --->
	<cfinvoke component="GetResizedImage"
<!--- Declare what part of the CFC handles checking / getting the image --->
	method="GetImage"
<!--- Declare variable that will pass back the new image name --->
	returnvariable="myImage">
	<cfinvokeargument name="img" value="#event.Pic#"/>
	</cfinvoke>
<!--- Display re-sized image --->
	<img src="#myImage#" alt="" />     
</cfoutput>

Step 3 - Test

The proposed solution cut page load times from 20+ seconds to below one second after the first page load. During the FIRST or FIRST FEW times the page loads all the re-sizing will be done.

Q and A

Question: Checking if a file exists each time the page loads is excessive.
Answer: We agree but it's much better than resizing every image each time the page loads.

How to create Services for Additional ColdFusion Instances

If you've created additional ColdFusion instances on your VPS/Dedicated Server, and ColdFusion was unable to create the Services for those instances just do the following:

  1. Open a Command Prompt as Administrator
  2. Run this command, replacing INSTANCE with the actual name of your new ColdFusion instance:
    sc create "ColdFusion 10 INSTANCE Application Server" binPath= "C:\ColdFusion10\INSTANCE\bin\coldfusionsvc.exe" displayname= "ColdFusion 10 INSTANCE Application Server" start= auto

Now you will be able to start your instance through the Windows Services Manager. If you need to know how to create additional ColdFusion instances, please see this guide from Adobe: Defining Additional ColdFusion Instances

Once you've created the instances, you can attach them to your Web server as described here: Web Server Configuration

If you're using IIS, this video has a great walkthrough for using the ColdFusion Web Server Connector tool: Learn About ColdFusion IIS Connectors

How to Fix Error: Value '0000-00-00' can not be represented as java.sql.Date

If your application has null values in a MySQL datetime/date column you may encounter the error "Value '0000-00-00' can not be represented as java.sql.Date". The easiest way to fix this is by adding the parameter zeroDateTimeBehavior=convertToNull to your site's DSN as recommended by Adobe.

How to Fix Null DateTime Error - Shared Hosting

  1. Log into your site's WCP control panel
  2. Click the DataSources (DSNs) button
  3. Click the Edit icon next to your DataSource (DSN)
  4. Add the following to the JDBC Query Parameters field:
    zeroDateTimeBehavior=convertToNull

Note: To add multiple JDBC Query Parameters, separate each name/value pair by an '&'. Example: zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8

How to Fix Null DateTime Error - VPS Hosting

If your site uses WCP to manage its DSNs, you may utilize the Shared Hosting solution. Otherwise, follow the steps below:

  1. Log into ColdFusion Administrator on your VPS/Dedicated Server.
  2. Navigate to the "Data Sources" page and click your site's DSN name.
  3. On the page that opens add ?zeroDateTimeBehavior=convertToNull to the end of the JDBC URL field.
  4. Click Submit and your site should no longer display the date representation error.

Find the Java Version Used by ColdFusion or Railo

This CFML code will report the version of Java used by your ColdFusion or Railo server:

<cfoutput>#CreateObject("java", "java.lang.System").getProperty("java.version")#</cfoutput>

Reference: Pete Freitag's Blog - What Version of Java is ColdFusion Using?

Reset ColdFusion Admin Password on CF 10+ VPS

Reset CF Admin Password - Windows VPS

  • On your VPS, open a command prompt window as Administrator
  • Issue the following command to change to the ColdFusion bin directory replace ColdFusion10 with the actual path to your ColdFusion installation':
    cd C:\ColdFusion10\cfusion\bin
  • Execute the passwordreset.bat script:
    .\passwordreset.bat
  • Enter '1 to change your ColdFusion administrator password
  • Enter a new strong password, then enter it again to confirm the password
  • The next section will ask for a new RDS password. If you're not using RDS you may leave the password and confirmation blank, or you can enter a secure password if you like.
  • Restart ColdFusion to force the new password into effect

Reset CF Admin Password - cPanel/Linux VPS

  • SSH into your VPS
  • Issue the following command to change to the ColdFusion bin directory replace ColdFusion10 with the actual path to your ColdFusion installation':
    cd /opt/ColdFusion10/cfusion/bin
  • Execute the passwordreset.sh script:
    ./passwordreset.sh
  • Enter '1 to change your ColdFusion administrator password
  • Enter a new strong password, then enter it again to confirm the password
  • The next section will ask for a new RDS password. If you're not using RDS you may leave the password and confirmation blank, or you can enter a secure password if you like.
  • Restart ColdFusion to force the new password into effect

ColdFusion 11+ PDF Generation: How to Fix 'No Service Manager is Available' Error

If you receive the error No Service Manager is Available when trying to generate PDFs or use the cfhtmltopdf tag on your ColdFusion 11+ VPS, do the following to fix it:

  1. Log into your server's ColdFusion Administrator
  2. Expand Data & Services, then click the PDF Service link
  3. On the next page, you should see an entry for localhost under the list of PDF Service Managers
  4. If the localhost service manager is not enabled, click the Enable button to the left of the manager name. (The button looks like a play button)
  5. Try using cfhtmlpdf now, and see if it works.

If you still have any issues after enabling the service manager, try restarting the ColdFusion Addon Services Windows service and test again.

HTML5 Audio Player with ColdFusion

This player uses an list named Tunes within the session scope to store a list of mp3 names. After populating the list, you can use this code as the foundation for an HTML audio player that plays each song in the list.

<cfif action is "play_next_tune">
 
	<cfset myArray=ListtoArray(session.Tunes)>
	<cfset T_max=Arraylen(myArray)>
	<cfset session.track=session.track+1>
	<cfif session.track GT T_max>
		 <cfset session.track="false">
		 <cflocation url="tunespage.cfm" addtoken="false">
	</cfif>
 
	<cfoutput>
		<audio controls id="myVideo" autoplay>
		<source src="path/#myarray[session.track]#" type="audio/mpeg">
		Your browser does not support the audio element.
		</audio>
	</cfoutput>
 
	<script language="JavaScript">
		document.getElementById('myVideo').addEventListener("ended",function() {
		window.location.href="tunespage.cfm?action=play_next_tune";
		});
	</script>
</cfif>

Cfchart error: Could not locate the style file style.xml

In ColdFusion 11 the ability to specify styles in an XML file was removed. As such, you will need to convert any XML stylesheets to json files. To do this, you'll need to do the following:

  • Install a trial edition of ColdFusion 11 on your local computer
  • Open a command prompt and run this command:
    • C:\ColdFusion11\cfusion\bin\cfchart_xmltojson.bat C:\sites\mysite.com\cfchartstyle.xml
    • Be sure to replace the paths above with the actual path to "cfchart_xmltojson.bat" as well as the path to your XML stylesheet.
  • When the conversion is done you will end up with a new file with the same name as the XML stylesheet, however there will not be a file extension. To simplify things, add a .json extension to the converted file.
  • Update the path to the stylesheet in the cfchart tag to have a .json extension instead of .xml.
  • Update the path to the stylesheet to use relative paths instead of absolute paths from the webroot.
    • Example: If the stylesheet file and the .cfm template with the cfchart code are in the webroot, change /cfchartstyle.json to ../cfchartstyle.json

More details on this are available in the Cfchart documentation. Be sure to check the comments of the documentation for more helpful cfchart troubleshooting tips.