Adobe, please fix Coldfusion SerializeJSON()

Coldfusion 9.0.1 is essentially disqualified to be used with NoSQL datastores where JSON is involved.

We have used Coldfusion since 3.0 in 1998 upgrading to 4.0, 5.0, 6.1, 7.0, 8.0 and 9.0. We did this upgrade for our servers and for even more of our customers servers that use our software.

So I am kind of an Coldfusion evangelist with one difference being that i don’t get paid by Adobe but i pay them, even though I sell their products to our customers. Another difference is that I don’t greet every change or feature a new version brings with cheer no matter how badly implemented it is. And I don’t try to sell bugs as features. Because in the end bugs cost our customers more money because we have to waste time to work around them. Or in the worst case use other technology to get around those bugs.

I hope fellow Coldfusion developers agree with me on this. We like to use Coldfusion. We get work done with it. We get it done fast on a reliable platform. After all, if I would not like Coldfusion I would not write the following.

The SerializeJSON() function was flawed in 8.0 and 9.0 and is now broken in 9.0.1. And Adobe needs to fix it asap before more people upgrade to 9.0.1

Those who worked with JSON in 8.0 and 9.0 know that it was flawed to some extend.

When serializing queries it worked pretty well - as CF knew the data types for each field. Integers stayed integers, floats stays floats. The only weakness being strings that were pure numbers (think of a DB with movie names and the movie “2010”). This became a number while all other movies were strings. Also “000123” became a number with the 000 cut off. With CF created data structures instead of queries there were some more flaws in that integers also became floats unless you used JavaCast(“int”) on every number to tell CF that it is an integer. Some things could not be worked around like numbers in strings that just became numbers. The “00123” example would turn to 123.0. So the 8.0/9.0 JSON implementation needed some fixing and 9.0.1 tried to fix.

Also the date conversion used the Java locale. I actually haven’t checked if that got fixed i 9.0.1.

Now the surprise: 9.0.1 says goodbye to the number format in JSON. All numbers in JSON will become strings once Coldfusion gets its hand on the data. There are no more numbers. 10 becomes “10”, 10.2 becomes “10.2” etc. Even though the patch notes stated that differently. And i still believe it was not Adobe’s intention to remove numbers but somehow this flawed implementation slipped in.

Here is some example code to try on your 9.0.1 installation:

<cfhttp url=","utf-8")#&output=json&oe=utf8&sensor=false" method="get">
<cfsetting showdebugoutput="no">
	<cfset toJSON = DeserializeJSON(cfhttp.FileContent)>
	<h1>After DeserializeJSON</h1>
	<cfdump var="#toJSON#">
	<h1>After SerializeJSON</h1>

When I first commented about the flawed SerializeJSON here, some people said: Why should I care - if I work with JSON I will probably know my data types and can convert them. What’s the big deal? True I could. I could also stop using data types in SQL and make all fields varchar(MAX). Disk space isn’t a constraint any more. Just let my app convert the data to the desired format and save some thinking on the db creation. But I don’t like that. I still like that fact that there are different data types in CF, Javascript, Python etc. and I like to work with them.

I want to store data in a JSON format in Memcached, SimpleDB, Redis or other NoSQL engines like for example in CouchDB. The last thing I want is to store a price of a product as a string only to do a string to float conversion for every view index inside CouchDB that uses the price for sorting. So if I want to use JSON in any of the NoSQL stores I cannot use Coldfusion 9.0.1. Unless I don’t mind having a soup of strings stored.

Another example where the new SerializeJSON() is a bad choice would be an efficient data exchange of large lists with lots of attributes. Think of hotels with attributes like “hasPool”, “hasTV”, “hasMiniBar”, etc. So a list of let’s say 250 hotels could have 50 attributes each. In number Format one attributes would be (0,1,0,1,0,3) so around 500 bytes. The comma being the overhead. For strings there is an overhead of three characters (“0”,“1”,“0”,“1”,“0”,“3”) doubling the size to 1000 for no reason. So it’s 50K just for the attributes when it could be just 25k. 25k more don’t matter much on a fast network, but 25k are a lot on a slow mobile connection when those 25k are just attributes.

I know loosely typed languages don’t make it easy to do a correct JSON encoding, but please Adobe, look at other JSON implementations and get back to work on this. JSON is and will be the standard of data exchange and us CF developers can not work with an implementation that turns all numbers to strings once the data runs through a CF server. CF needs to at least do JSON right to support the new NoSQL landscape. Coldfusion needs native JSON parsing that is fast and on the same level with implementations in other languages. Not some quick hack that removes numbers and turns them to strings like the current implementation.

The JVM startup parameter to turn behaviour back to 8.0 / 9.0 levels is no option as this affects the whole server and the old implementation was far from perfect. Coldfusion needs a good JSON parser that works. Not the 9.0 or the 9.0.1 one. A better one.

If you agree, blog about this, tweet this and vote for this as a bug.

Update 1 (July 29th 2010): Adobe has officially accepted this as a bug and targets a fix for 9.0.1 (Hotfix).

Update 2 (September 1st 2010): Adobe has fixed this bug in a hotfix. But SerializeJSON is still flawed:

hexcolor = '350E25';
writeoutput(SerializeJSON(hexcolor));   // Sigh

Adobe might argue: This is a perfect scientific number. So we decide to serialize it as a number. But let me ask you this: How many customers are using Coldfusion in a scientific environment. And how many just want `350E25 to stay a hex color? You guess.