Java Collection Types & ColdFusion

At work one of our developers is programming an ecommerce store against a Java API written by a third party. Said Java API returns a TreeMap object from a method and when you try to access that TreeMap object in any fashion, you’ll get an error, specifically:

“Error casting an object of type java.lang.Integer to an incompatible type. This usually indicates a programming error in Java, although it could also mean you have tried to use a foreign object in a different way than it was designed.”

What we’ve concluded is that ColdFusion attempts to cast any and all Java classes that implement the Map interface to:

coldfusion.runtime.Struct

which is of type java.util.Hashtable. Unfortunately, a TreeMap uses an Object (in this case an Integer) as the key. ColdFusion structures can only use strings as the key. The takeaway is that this is a ‘feature’ of ColdFusion, it’s nice that it attempts to transform collection type objects into the native ColdFusion structure type. In this specific case, it’s more of a hindrance. The workaround is to create your own Java wrapper that takes the TreeMap, loops over all the keys, inserting each into a Vector and then return the Vector to ColdFusion, which turns that into a structure.

In case you don’t feel comfortable going to sleep at night without seeing the code, here’s an example Java class that returns a simple TreeMap:

import java.util.*;
public class TreeMapTest {
   public static TreeMap getTree() {
      TreeMap t = new TreeMap();
      t.put(new Integer(131000), “product”);
      return t;
   }
}

Compile that and then drop it into your [cfusionmx]\wwwroot\WEB-INF\lib\ directory. You can use this script to test it:

<cfscript>
   tmt = createObject(“java”, “TreeMapTest”);
   WriteOutput(“tmt is of type ” & tmt.getClass());
   treeMap = tmt.getTree();
   WriteOutput(“treeMap is of type ” & treeMap.toString()); // you get an error here
</cfscript>

I’d be very very interested in hearing about any ways that you know of to get around something like this without having to write a wrapper class. And for you Macromedia ColdFusion guys, it might be a nice (albeit probably rarely used) feature to be able to maintain the Java type of an object by using some function, ( ie: maintainType() or some such).

By the way, if you’re interested in knowing more about using Java and ColdFusion together, Terry Ford has written a great article here entitled “Using Java and J2EE Elements in ColdFusion MX Applications”.

4 thoughts on “Java Collection Types & ColdFusion”

  1. Are you sure this is something specific to TreeMap? If ColdFusion structs can only use strings as keys, and all Maps are turned into structs, then all Maps that have anything but strings as keys will get you into trouble.

    As for the workaround, why would you want to turn a Map into a Vector? Don’t you just want to create a new Map where .toString() has been called on all the keys?

    I always get a little leery of integrating multiple languages, no matter how easy the vendor seems to make it… there always seem to be ugly little type (or method dispatch) incompatibilities…

  2. I got the same message using a cfgrid to update a datasource. The type of data I am updating is boolean. I use a check box for the user interface.

  3. I got the same message using a cfgrid to update a datasource. The type of data I am updating is boolean. I use a check box for the user interface.

  4. Thanx for your help, but I got a light different conclusion. I faces the same problem und was unable to solve it, till I found your posting. I got a Java Object extended from TreeMap and had the described error. But when you exchange the TreeMap against a HashMap, everything (I hope) works fine. So maybe CFMX uses TreeMaps for internal representation of CF-Structs and using TreeMaps from CFMX causes wrong casts? I’ll put this to MM Forum and see 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *