ColdFusion CFImage Bug - Font Size Data Type Casting

Posted February 11, 2008 at 7:04 AM by Ben Nadel

Tags: ColdFusion

Normally, I am hesitant to call anything in ColdFusion a bug, but since ColdFusion is a dynamically typed language that can cast all simple values to strings, I have to come right out and say that this is a bug. Take a look at the following code:

  • <!--- Loop over font sizes. --->
  • <cfloop
  • index="intFontSize"
  • from="10"
  • to="50"
  • step="10">
  •  
  • <!--- Create ColdFusion image canvas. --->
  • <cfset objImage = ImageNew( "", 500, 150, "rgb" ) />
  •  
  • <!--- Create font properties. --->
  • <cfset objFontProperties = {
  • Font = "Courier New",
  • Size = intFontSize,
  • Style = "normal"
  • } />
  •  
  • <!--- Draw text. --->
  • <cfset ImageDrawText(
  • objImage,
  • "Test Font (#intFontSize#pt)",
  • 10,
  • (intFontSize + 20),
  • objFontProperties
  • ) />
  •  
  • <!--- Draw image. --->
  • <cfimage
  • action="writetobrowser"
  • source="#objImage#"
  • />
  •  
  • </cfloop>

Notice here that we are just looping over different font sizes so that we can see how they look on the canvas. Pretty simple, right. Well, when you run this code, you get the following ColdFusion error:

java.lang.Double cannot be cast to java.lang.String. Error casting an object of type java.lang.Double cannot be cast to java.lang.String 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.

This error, while explicit, is not obvious. If you look at the code above, all the string values are text and all the numeric values are, well, numeric. So, how did I fix this error? When setting up the font properties struct, I had to cast the font size to a string:

  • <!--- Create font properties. --->
  • <cfset objFontProperties = {
  • Font = "Courier New",
  • Size = ToString( intFontSize ),
  • Style = "normal"
  • } />

Notice that the Size property value is now wrapped in a ToString() method. This is because the CFLoop tag is creating an index value of type Double and for some reason ColdFusion cannot cast this Double value to a String value which is clearly what the ImageDrawText() function needs. I have to put my foot down and say that this is definitely a bug. Part of the reason that I am so adamant about this being a bug is that I discovered it while writing a ColdFusion user defined function for Image creation. In the UDF, I had an argument for FontSize and the Type attribute of the CFArgument tag was set to "String". The value I was passing in clearly validated against the Type checking of the CFArgument tag but then threw a type casting error when used within the CFFunction to draw image text.

In general, I am going to say that any time ColdFusion cannot cast a simple value to a string, it is a bug.



Reader Comments

Feb 13, 2008 at 12:46 AM // reply »
8 Comments

Ben,

I would not be so fast to call it a bug. I may be deadly wrong but for me ColdFusion is doing things this way:

1. You call your UDF and pass a clearly numeric type (as defined directly by the CFLOOP);

2. Your UDF tries to validate it - so, CF converts numeric type to string successfully and goes on.
BUT WAIT - CF didn't convert the VARIABLE - only the value! And for validation purposes. The variable still IS a numeric type, as defined by the loop that created it;

3. You pass the argument received to a CF function, which is JAVA and therefore doesn't convert anything, so you get the error.

Now, I can see how you thought - and I'm not certain if you're wrong - this is a bug. If my UDF needs a STRING, CF should not only test it but rather convert it directly, right?

Well, that's a question beyond my developer skills ;) but as I was trapped in errors like this one so many times, I would like to share the process I went through to find a solution and see if any CF-related developer went down here to enlighten us :)

Best wishes and continues with your really great blogging! I don't miss one of your posts.

Fernando


Feb 13, 2008 at 7:16 AM // reply »
11,246 Comments

@Fernando,

I think the whole fact that CFArgument validates a ColdFusion and then doesn't have it work properly in later calls is enough to say it is a bug. I could understand if we were passing this value directly to a Java method and therefore needed to do some sort of JavaCast() call, but the fact is, we are passing the value to a ColdFusion function which should never require a JavaCast() since CF should automatically be able to handle simple data type conversions.


Jul 16, 2010 at 1:29 PM // reply »
1 Comments

You are the best... I owe you at least 1000 hours of my life!


Jul 18, 2010 at 11:37 AM // reply »
11,246 Comments

@Anthony,

No worries - it's my pleasure.


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 23, 2013 at 9:52 PM
Preventing Links In Standalone iPhone Applications From Opening In Mobile Safari
@Muhmmadibn Did you figure out a solution to launching PDFs? I am running into the same issues myself. There is no way to close the PDF or go back once you launch it. Thanks in advance! ... read »
May 23, 2013 at 6:06 PM
The Girl Who Broke My Heart, And Made Me A Better Person
Good day,ladies and gentle men, my name is Dr AMADI the great spell caster in Africa, i have help so many people for different kind of problems,who say there is no solution to problems on earth, that ... read »
May 23, 2013 at 4:26 PM
ColdFusion QueryAppend( qOne, qTwo )
@Heather, Glad people are still getting value out of this! ... read »
May 23, 2013 at 3:49 PM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@WebManWalking, I meant the code at the bottom (not the video). I did try to experiment with an intermediary variable, like: value = users.id[ i ]; arrayContains( userIDs, value ); ... but t ... read »
May 23, 2013 at 11:06 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben, Are you talking about As Number: YES As String: YES As Java: YES? If so, that's with 3 different ways of referencing the constant 1, not users.id[1]. Query object references(*) are what seem ... read »
May 23, 2013 at 9:55 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Dan, According to the CF Admin, I'm running Java "1.6.0_45". As far as the DB column, in the database it's an INT. I'll see if I can dig into what CF sees it as. @WebManWalking, But h ... read »
May 23, 2013 at 9:49 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben, I think the problem is that we're used to loose typing in ColdFusion, like JavaScript. If a value is a number but it's needed in an expression to be a string, noooo problem. I've encountered ... read »
May 23, 2013 at 9:47 AM
ColdFusion QueryAppend( qOne, qTwo )
You rock! Thank you, thank you, thank you!!! ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools