Can't Cast Object Type [Struct] To A Value Of Type [image] In Lucee CFML 5.3.4.77
As I wrote about back in January, we were having some performance issues in one of our Lucee CFML services. One of the steps we took in the debugging process was trying to upgrade from Lucee CFML 5.2.9.40 To 5.3.3.62. Unfortunately, when we did that, we started seeing the following ColdFusion image error:
Can't cast Object type [Struct] to a value of type [image]
Java type of the object is org.lucee.extension.image.Image
At the time, we rolled back and continued exploring other options. But, we recently got around to trying a Lucee upgrade once again, this time to Lucee CFML 5.3.4.77 with the latest Image extension. And, once again, the moment we upgraded, we started to see that same error in production.
We still have no idea why this was happening. And, we cannot reproduce the error in any kind of controlled way - not in local development, staging, or production. It appeared to be completely random, possibly related to server-load?
Ultimately, we "fixed" the issue by removing some left-over hacky code that was put in place when we switched from Adobe ColdFusion 10 to Lucee CFML 5.2.9.40:
<cfscript>
// .....
// openJDK on Lucee needs to convert the image to rgb colors
var img = imageNew('', image.getWidth(), image.getHeight(), 'rgb');
img.paste(image,0,0);
image = img;
// .....
</cfscript>
As you can see, this code is just pasting the image
into another Image
object of the same dimensions; but, it's forcing the resultant image to use an RGB colorspace. I believe this code was put in place to strip-out the alpha-channel in transparent PNGs. I'm not really sure. But, for whatever reason, when we took this code out, the error went away.
What's crazy is that there's nothing here of type Struct
that would relate back to the error message. I tried to dig through the Lucee CFML code and found the CasterException.java
class. I think maybe this is what was generating the error message:
// .....
public CasterException(Object o, String type) {
super(createMessage(o, type), createDetail(o));
}
// .....
private static String createDetail(Object o) {
if (o != null) return "Java type of the object is " + Caster.toClassName(o);
return "value is null";
}
// .....
public static String createMessage(Object o, String type) {
if (o instanceof String) return "Can't cast String [" + crop(o.toString()) + "] to a value of type [" + type + "]";
if (o != null) return "Can't cast Object type [" + Type.getName(o) + "] to a value of type [" + type + "]";
return "Can't cast Null value to value of type [" + type + "]";
}
// .....
So, based on the arguments to CasterException
, I think we can rewrite my error message to be something like this, pre-interpolation:
Can't cast Object type [
o
] to a value of type [type
]Java type of the object is "
o
"
The crazy part about this is that, if you refer back to the error message, that second line is:
Java type of the object is org.lucee.extension.image.Image
So, it would appear, unless I'm completely missing the point, that the argument o
is both a Struct
(in the first line of the error message) and an Image
(in the second line of the error message).
Again, I have no idea why this was causing an issue. I have no idea what part of this chunk of code was even the culprit. I have no idea how to translate the Lucee CFML error message into something that makes sense. I'm only posting this here in case anyone ever hits this error message and tries to Google for it. To date, my discussion of this error is the only result that comes up on Google. Which is hella weird!
Want to use code from this post? Check out the license.
Reader Comments
Ben, can you include the top 10-20 lines of the java stacktrace with such posts? The exception message is good for finding the source of the exception, but being able to see the code path to the exception is really useful
@Zac,
Sooooo, unfortunately, when we log ColdFusion errors, we just extract all the lines that end in
.cf[cm]
so that our log entries aren't so large. As such, I can only see where the error happens in our application - not in the Lucee engine :( We get the root message (hence what I have in the post); but, none of the low-level stuff.I should go back and just break it into two different stack-traces (ie, the CFML stack, and then the raw stack).
Hmm, I just ran into this again, this time while creating an entirely new, empty image with nothing but a background color.
For some reason, though, it doesn't seem to error all the time.