Jul 08

Reserved ColdFusion function names

Posted by James Netherton | Tuesday 08 July 2008 8:55 PM | In ColdFusion

Most people are aware that you cannot give a name to a ColdFusion function that is equal to the name of one of the ColdFusion "built in" functions.

This started me thinking that as ColdFusion templates and CFC's are compiled down to Java servlets, there must be additional function names that are 'reserved'. Each template and CFC page will naturally extend java.lang.Object and therefore inherit all of Object's public methods.

For example, try the following:

<cffunction name="getClass">
</cffunction>

The result is "The name getClass is the name of a built-in ColdFusion function". You get the same result when declaring a function with the names "wait", "notify" and "equals", all of which are public methods on java.lang.Object.

These are only a few examples, I'm assuming that there must be more reserved function names given the number of classes that ColdFusion template and CFC servlets could potentially extend from.

The getClass method opens up the potential for some fun with ColdFusion:

Get the current template class name

<cfoutput>#getClass().getName()#</cfoutput>

Get the current template class properties

<cfset fields = getClass().getFields()/>

<cfloop array="#fields#" index="field">
   <cfoutput>#field.getName()#<br/></cfoutput>
</cfloop>

Get the current template class methods

<cfset methods = getClass().getDeclaredMethods()/>

<cfloop array="#methods#" index="method">
   <cfoutput>#method.getName()#<br/></cfoutput>
</cfloop>

Get the name of the class that the current template extends from

<cfoutput>#getClass().getSuperclass().getName()#</cfoutput>

 

Jun 12

Disabling ColdFusion administrator authentication

Posted by James Netherton | Thursday 12 June 2008 11:51 AM | In ColdFusion

I find having to log into the ColdFusion administrator a pain when I'm working on applications in my development environment. You can disable the authentication process by way of the following:

1. Open up WEB-INF\cfusion\lib\neo-security.xml on multiserver installations or cfinsntallationdir\lib\neo-security.xml on standalone installs

2. Edit the admin.security.enabled property so that it appears as follows:

<var name="admin.security.enabled">
   <boolean value="false"/>
</var>

3. Save the file and restart ColdFusion

Obviously you would not want to be doing this in a production or publicly accessible environment!

 

Jun 04

Using jrunx classes in ColdFusion

Posted by James Netherton | Wednesday 04 June 2008 8:34 PM | In ColdFusion

I've been screwing around with classes within the jrunx Java package that comes bundled with ColdFusion (not sure if it exists if you aren't running CF on JRun). There are some useful and interesting utilities and I've put together a very brief set of demos for a few of them.

jrunx.util.NetUtil

Lookup an IP address from a DNS string:

<cfset variables.netUtil = createObject("java", "jrunx.util.NetUtil")/>

<cfset variables.ip = variables.netUtil.resolveIp("www.google.com")/>

<cfoutput>#variables.ip#</cfoutput>

Validate an IP address:

<cfset variables.netUtil = createObject("java", "jrunx.util.NetUtil")/>

<cfset variables.hostValid = variables.netUtil.validateHostIp("127.0.0.1")/>

<cfoutput>#variables.hostValid#</cfoutput>

jrunx.util.ZipTool

Zip a directory:

<cfset variables.zipUtil = createObject("java", "jrunx.util.ZipTool")/>
<cfset variables.zipUtil.zipDir("C:/Test", "C:/Test.zip", true)/>

Zip a single file:

<cfset variables.zipUtil = createObject("java", "jrunx.util.ZipTool")/>
<cfset variables.zipUtil.unZipSingleFile("C:/Test.zip", "C:/TestUnzip", "myHTMLFile.html")/>

Unzip an entire archive:

<cfset variables.zipUtil = createObject("java", "jrunx.util.ZipTool")/>
<cfset variables.zipUtil.unzipToPath("C:/Test.zip", "C:/TestUnzip")/>

jrunx.xml.XMLScript

Change an XML entity value within an XML file: XML Input File

<root>
   <person id="1">
      <name>James</name>
      <age>00</age>
      <occupation>Developer</occupation>
   </person>
   <person id="2">
      <name>Bob</name>
      <age>00</age>
      <occupation>Developer</occupation>
   </person>
</root>

<cfset variables.xmlScript = createObject("java", "jrunx.xml.XMLScript").init()/>

<cfset variables.inputFile = expandPath("./input.xml")/>
<cfset variables.outputFile = expandPath("./output.xml")/>

<cfset variables.args = arrayNew(1)/>

<cfset variables.args.add("-i")/>
<cfset variables.args.add(variables.inputFile)/>
<cfset variables.args.add("-o")/>
<cfset variables.args.add(variables.outputFile)/>
<cfset variables.args.add("-s")/>
<cfset variables.args.add("/root/person[@id='1']/name/text()")/>

<cfset variables.args.add("Joe")/>

<!--- Hackery to create a java string array --->

<cfset variables.dummyString = repeatString(" : ", arrayLen(variables.args) - 1)/>
<cfset variables.stringArray = variables.dummyString.split(":")/>

<cfloop from="1" to="#arrayLen(variables.args)#" index="i">
   <cfset variables.stringArray[i] = variables.args[i]/>
</cfloop>

<cfset variables.xmlScript.command(variables.stringArray)/>

XML Output File

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <person id="1">
      <name>Joe</name>
      <age>00</age>
      <occupation>Developer</occupation>
   </person>
   <person id="2">
      <name>Bob</name>
      <age>00</age>
      <occupation>Developer</occupation>
   </person>
</root>

Admittedly that's a very lame example, there's a proper overview of what the class can really do on the Adobe Jrun guide There's a full overview of jrunx classes and packages here.

 

May 16

JVM Monitoring Tools For ColdFusion

Posted by James Netherton | Friday 16 May 2008 11:29 AM | In ColdFusion,Java

I've been experimenting with JVM monitoring tools out of curiosity for what impact some applications have on memory and CPU usage. Here is a brief rundown on some of the tools that I used. All of these tools should be included within the bin directory of whatever JDK distribution you are using, providing the Java version is 1.5 or greater.

You may read this post and wonder why I bothered to research any of this, seeing as ColdFusion now has built in monitoring and profiling tools, together with many third party alternatives. Those tools are all good at providing a relatively high level of detail, showing what's going on inside of the application server but the tools outlined below can offer a more granular level of detail.

jps

Some of the tools require an argument to specify the id of the JVM that you want to interrogate, jps can be used to retrieve this id:

jps localhost

358 Jps
268

Other tools require that you pass an argument for the JVM process ID. This information can be easily obtained by using Task Manager, Activity Monitor, top, ps or whatever your tool of choice is for your environment.

JConsole

JConsole is a graphical tool that displays the current state of the JVM in terms of memory usage, thread usage and classes loaded. There are a couple of other items such as MBean management, but that's outside the scope of this post.

To start JConsole you need to the process ID of the JVM. I'm going to use the PID of JRun (2219) which of course is my ColdFusion JVM instance:

jconsole 2219

You'll then see graphs representing the current JVM memory usage. Execute some CF pages or fire up an application and you should see the memory graphs rise and fall as memory is allocated and garbage is collected. You can even force garbage collection by clicking the 'Perform GC' button.

jstack

jstack produces a stack trace dump of all threads within the JVM.

jstack 2219

Note that the output is very verbose so it's probably better to pipe the output to a file.

jmap

jmap can be quite useful to gather details about JVM memory details. For example, you can view heap statistics relating to number of objects loaded and the amount of memory allocated. Again, it's best to pipe the output to a text file:

jmap -histo 2219 > heap_stats.txt

jstat

jstat displays performance statistics for a JVM instance. The tool requires the id of the target JVM to be passed as a command line argument. You can also set the data refresh rate by specifying a value in milliseconds. The example below outputs a summary of garbage collection statistics every 5 seconds:

jstat -gcutil 1700 5000

There a many different switches that can be used to obtain different monitoring statistics. The Sun jstat web page has an overview of these options.

Some other tools that I looked at:

visualgc - similar in some ways to JConsole but focuses on memory and garbage collection statistics.

profiler4j - I couldn't get this working with JRun.

Eclipse Profiler - I got the Eclipse plugin installed ok but JRun choked whenever I tried to start ColdFusion after adding the specified profiler arguments into the jvm.config file. I only tried this with CF 8 so it may work with CF 7 and Java 1.4.2.

JRockit Mission Control - A product from BEA. It has been used to good effect in the past to find memory leaks in ColdFusion:

Mike Schierberl - ColdFusion Memory Leaks

Jason Sheedy - Cold Fusion Memory Leak

I got bored of trying to hunt down a free version of JRockit on the BEA website, but this tool can potentially offer some nice insights into what's happening under the hood of an application.

 

May 04

Converting Unix timestamp values in ColdFusion

Posted by James Netherton | Sunday 04 May 2008 4:58 PM | In ColdFusion

I've been working on an application that integrates with a third party payment gateway solution. The payment service sends back a transaction timestamp after a purchase is successfully completed in the unix time format.

I spent some time trying to figure out how to covert this into a 'normal' date format with ColdFusion. The solution is pretty simple as the following code sample demonstrates.

<!--- Unix Timestamp representing 4th May 2008 00:00:00 AM --->
<cfset variables.unixTimeStamp = "1209859200"/>

<cfoutput>#dateAdd("s", variables.unixTimeStamp, "01/01/1970")#</cfoutput>

 

Apr 15

Run ColdFusion on GlassFish

Posted by James Netherton | Tuesday 15 April 2008 8:10 PM | In ColdFusion

I thought this was worthy of blogging seeing as it's not often that ColdFusion gets mentioned on The Server Side.

Damon Gentry has posted an article on how to get ColdFusion running on Sun's open source JEE application server, GlassFish.

As JRun is no longer being actively developed, maybe it's time to start looking at some of the alternative application servers to deploy ColdFusion onto.....

 

Feb 17

ColdFusion 8 - Custommenu.xml

Posted by James Netherton | Sunday 17 February 2008 12:56 PM | In ColdFusion

In previous versions of ColdFusion you were able to add custom menu items to the ColdFusion administrator by creating a template named extensionscustom.cfm and placing this within the cfadministrator directory.

Peek within the cfadministrator directory under CFIDE within ColdFusion 8 and you should see a file named custommenu.xml. By adding entries into this file you can replicate the behaviour offered by extensionscustom.cfm.

The XML file has the following structure:

<?xml version="1.0" encoding="iso-8859-1"?>
<menu>
   <submenu label="My Custom Menu">
      <menuitem href="href" target="content">Custom Resource</menuitem>
   </submenu>
</menu>

You can have as many submenu or menuitem elements as you wish. Once you have made your changes, head over to the ColdFusion administrator and you should see your custom menu items appended to the end of the main navigation menu.

 

Feb 04

ColdFusion webservice debugging

Posted by James Netherton | Monday 04 February 2008 11:31 PM | In ColdFusion

Debugging webservices can sometimes be a painful experience. ColdFusion provides some help via the getSoapRequest and getSoapResponse functions, which enable you to view the SOAP request / response XML.

Suppose you want to see all SOAP requests and responses sent to the ColdFusion server. This can be achieved by making a simple change to the client-config.wsdd file. On my multi server ColdFusion 8 installation, the file is located in:

[Installationdrive]\JRun4\servers\cfusion\cfusion-ear\cfusion-war\WEB-INF

The beginning of the file has the following declarations:

<globalConfiguration>
<!-- Give ColdFusion the ability to log the request and the response SOAP message -->
<!-- Not recommended for production -->
<!--
<requestFlow>
<handler type="log"/>
</requestFlow>
<responseFlow>
<handler type="log"/>
</responseFlow>
-->


<!-- Change for CFMX 7: Turn off multirefs -->
<parameter name="sendMultiRefs" value="false"/>
</globalConfiguration>

Uncomment the lines around the requestFlow and responseFlow tags. Save the file and restart ColdFusion. You should then see SOAP requests and responses being written out to the cfusion-out.log file.

Note the warning in the snippet above about not enabling SOAP logging in a production environment. For obvious reasons it makes sense not to leave logging enabled for long periods in production.

 

Dec 18

Missing jrunserver.store file when installing ColdFusion 8 with Apache

Posted by James Netherton | Tuesday 18 December 2007 9:32 PM | In ColdFusion

A small problem I just experienced when installing ColdFusion 8 on my mac and choosing to integrate it with the Apache install that ships with OS X.

ColdFusion would not serve any requests and reported:

JRun will not accept request. Check JRun web server configuration and JRun mappings on JRun server

A closer look at the Apache error log revealed:

could not open serverstore /Applications/ColdFusion8/runtime/lib/wsconfig/1/jrunserver.store

It turns out that there was no jrunserver.store file. The simple solution is to create the file and add:

proxyservers=127.0.0.1:51011

 

Nov 25

ColdFusion webservices on shared hosting

Posted by James Netherton | Sunday 25 November 2007 2:12 PM | In ColdFusion

ColdFusion security in a shared hosting environment can be a pain. Different hosts handle security in different ways, some disable certain tags / functions and use sandboxing. Other hosts do neither and allow users to access potentially security compromising functions such as createObject.

Something struck me after I tested a webservice that I had deployed on my host. The WSDL location would be listed under the web services section within the ColdFusion administrator. No big deal you may think and it usually isn't if you're on a shared host that forbids calls to the createObject function.

On a server that allows access to createObject, you can do something like the following. I omitted the code that gets the service details for CF7 as the getWebservice method takes far more parameters than its equivalent in CF 8.

CF 8:

<cfscript>
   serviceFactory = CreateObject("java", "coldfusion.server.ServiceFactory");
   webservices = serviceFactory.getXmlRpcService().getMappings();
</cfscript>

<cfdump var="#webservices#"><br/><br/>

<cfloop collection="#webservices#" item="key">
   <cfoutput><br/>#webservices[key]#<br/></cfoutput>
   <cfset map = structNew()/>
   <cfset map[key] = webservices[key]/>
   <cfdump var="#serviceFactory.getXmlRpcService().getWebservice(key, map)#">
</cfloop>

CF 7:

<cfscript>
   serviceFactory = CreateObject("java", "coldfusion.server.ServiceFactory");
   webservices = serviceFactory.getXmlRpcService().getMappings();
</cfscript>

<cfdump var="#webservices#"><br/><br/>

As you should see in the output, you can discover what services are registered with the CF administrator, the CF 8 example even outlines the method names, return type and required parameters. You could of course just browse to the service WSDL address and determine the same information, assuming of course the service is unsecured.

So, if you're exposing any web services that return sensitive data on a shared host (which you shouldn't be!), make sure they are secured appropriately!