How to Snoop on ColdFusion Data Types

Last week, I made a couple of posts about ColdFusion Arrays, and how they are actually java.util.Vectors, which means that you can convert them to Java arrays by calling toArray(). How did I figure that out? I didn’t ask the ColdFusion engineers. That’s cheating. The first thing I did was find out what type of class we are actually dealing with when we have a reference to an array. The Java object “Object” (which all objects extend) has a method called getClass() which returns the runtime class of an object. Calling toString() on the class (or simply the act of outputting it, which automatically calls toString()) will reveal the class name:

<cfset cfArray = arrayNew(1)/><cfset cfArray[1] = "c"/><cfset cfArray[2] = "b"/><cfset cfArray[3] = "a"/><html><cfoutput>#cfArray.getClass()#</cfoutput></html>

The result of the code above is:

class coldfusion.runtime.Array

So now I know that I’m dealing with a coldfusion.runtime.Array, however that information doesn’t do me any good by itself. What I need to know is what a coldfusion.runtime.Array really is, and what its public interface looks like. That’s where “javap” comes in. javap is a program that comes installed with your JDK that most people actually don’t know about. I don’t know what the “p” stands for (any ideas?), but javap is essentially a Java class disassembler. Running it against any class in your classpath will, by default, output public and protected method signatures along with other class information (use the -private flag to see private method signatures). If you have java installed and in your path, at the command line, type:

javap java.lang.String

And you will get something like:

Compiled from String.javapublic final class java.lang.String extends java.lang.Object implementsjava.io.Serializable, java.lang.Comparable, java.lang.CharSequence {public static final java.util.Comparator CASE_INSENSITIVE_ORDER;public java.lang.String();public java.lang.String(java.lang.String);public java.lang.String(char[]);public java.lang.String(char[],int,int);public java.lang.String(byte[],int,int,int);public java.lang.String(byte[],int);public java.lang.String(byte[],int,int,java.lang.String)throws java.io.UnsupportedEncodingException;public java.lang.String(byte[],java.lang.String) throwsjava.io.UnsupportedEncodingException;public java.lang.String(byte[],int,int);public java.lang.String(byte[]);public java.lang.String(java.lang.StringBuffer);java.lang.String(int,int,char[]);public int length();...}

So to find out more about coldfusion.runtime.Array, I used the following command:

javap -classpath /path/to/your/cfusion.jar coldfusion.runtime.Array

The output is:

No sourcepublic final class coldfusion.runtime.Array extends java.util.Vector {public coldfusion.runtime.Array();public coldfusion.runtime.Array(int);static coldfusion.runtime.Array copy(coldfusion.runtime.Array);static coldfusion.runtime.Array copy(java.util.List);public int getDimension();...}

Since I could see from the output above that coldfusion.runtime.Array extends java.util.Vector, I knew that I had access to all of Vector’s public methods, as well, such as toArray(), which was precisely the method I was looking for.