Module Loading Type Coercion Error in Flex
Sunday June 17, 2007
What a delicious nightmare this was for a while. I’m working on a large application that’s very reliant on modular capabilities offered by Flex. From past experience, one should know the perils of using technology that’s not fully understood. It’s especially noted that when dealing with complexities of modular architecture, nothing is ever “plug and play”. Time to RTFM.
It’s just a shame TFM doesn’t provide enough info to understand what’s really going on under the hood. Those who will have scoured the net for glittery gems of enlightenment on this very topic will likely have stumbled upon this presentation by Alex Harui. If not, go read it and peel the delicate skin off the fruit of knowledge.
For myself, getting two or more modules to work together resulted in a horrendous onslaught of confounding error messages. In the context of a smaller project I’ve found it hard to reproduce everything. If I find time to work on this I’ll upload a proof of concept, but for the moment take it from me that Modules and Hotfix 2 don’t play well together.
So, back to TFM and how to ensure you don’t get errors when integrating modules. If you’ve been through that presentation and it makes no sense, then you probably need a little primer on Virtual Machines in general.
All OO VMs (Mono/CLR, Java, AVM, etc) have a region of memory where your Classes are loaded. When classes are instantiated by the “new” operator, the instances (objects) of these classes are constructed from the information held there, and placed on the heap. Class memory is static, and remains the same throughout the length of the program runtime (unless you load classes dynamically at runtime).
In AVM, your MXML files are Subclassing their root tags, so they themselves are classes. One of the first things at runtime is Class Loading (see the example). This has nothing to do with the MXML Loader tag but it runs on a similar premise. All your Classes referenced by an mx:Application or mx:Module go into an applicationDomain (as seen in the presentation).
These application domains section off class loading areas of memory so that Types of one application/module dont get mixed up with types of another.
However, if you’re being a good programmer and making use of common classes across a modular application, things can go awry. The dictum to follow is ensure that shared types that might cause problems are declared in the parent applicationDomain.
The sort of errors that crop up are normally Type Coercion ones, and they’re pretty damn confusing because it’ll say something along the lines of
Type Coearcion Error: Unable to Convert SomeTypeXYZ to SomeTypeXYZ
Mighty confusing since it seems flex is flummoxed when casting one type to exactly the same type.
The trick is, even if it’s not used, declare a variable of type SomeTypeXYZ, in your root application.
var someType:SomeTypeXYZ;
SomeTypeXYZ will now be loaded in the parent applicationDomain, and the child will always default to using that one. You can make the same declarations with interfaces too. The error that stitched me up was “Unable to convert mx.messaging.messages.AcknowledgeMessage to mx.messaging.messages.IMessage.”