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. See this post.
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 which i covered here. 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:
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 with me, blog about this, tweet this and vote for this as a bug and let Adobe hear us.
I was not saying we should not care about the data types. My point was - when you write client code to work with JSON data, you typically _know_ the type at the time you write it. Therefore, the fact that 901 may things do "wrong" is inconvenient, it is still a _known_ variable. Ie, you know your numbers are coming back as strings and can code to that.
I hope that distinction makes sense. I can say that Adobe is well aware of the issues with JSON.
apart from Ajaxy-Client/Server communication we use JSON a lot to just store data we receive from webservices like Google Geocoding etc.
At the time we receive the data we just store it and don't really care about what fields are in there. We might want to work on the data in future.
So while i agree with you about that when writing client-code i know i will be getting back certain variables, i don't know and care at the time when i store data about what fields are in the JSON. All i need to do is add one or two fields and leave the rest of the JSON untouched - and i mean untouched.
I updated the above post with some example code.
Thanks for your comment. Hope Adobe gets a fix out soon.
On the other hand - i believe that JSON is such an important part of todays web that there should be a native function for it.
Another point is: All users of Coldfusion, unless you use just the dev version to play around, probably pay Adobe to get a working product.
They could use PHP and find external scripts for all those nice functions that CF brings in one box. But they don't. They prefer to pay to have this hassle taken away from them.
I did not do any benchmarks comparing the builtin JSON to the CFC but something tells me JSON parsing could be faster when done natively.
So all i ask for is a working version of a JSON parser, that matches those of other platforms.
And from what i can tell, Adobe is actively working on one that hopefully makes an external CFC for this obsolete.