Same problem here...
You should create a bootstaploader according the adobe documents:
but i tried that but it doesn't work. LoadForCompatibilty is the issue.
So i have a bootstraploader which has all the remoting stuff in it just as described in the adobe document referered to above. Then it loads my main application which has a remote object in it. Calling the remote object goes fine. If that main application loads a sub application with a remote object, both don't work anymore.
This is only the case if the sub application is loaded in a sibling application domain (which is the same as setting load for compatibility set tot true of the swfloader). If it's loaded ain a child domain of the main application domain it works. The problem is we are need our modules to be flexible and that they can be compiled wth different versions of the flex framework. It should be possible as this is what the marshal plan is all about right?
if i load the subapplication (in compatibility mode) and call the remote method on the sub application i get the next error:
TypeError: Error #1034: Type Coercion failed: cannot convert Object@1c9c3089 to mx.messaging.messages.ErrorMessage.
but it's application domain should be a direct child of the bootstrapper application domain so it should have the mx.messaging.messages.ErrorMessage. Somehow this fails. And even worse the main application gets screwed too. Because if i just load the subapplication and don't cal the remote object, but directly after loading it i call a method on the remote object defined in main i get another similar error:
TypeError: Error #1034: Type Coercion failed: cannot convert mx.messaging.messages::AcknowledgeMessageExt@19b11e49 to mx.messaging.messages.IMessage.
This is clearly undesired behavior. Can someone from adobe shed a light on this?
Sounds like the right things may not be in the bootstrap loader, or the apps aren't loading as children of the bootstrap loader's app domain. However, getting the bootstrap loader to have the right things without sucking in the entire framework and defeating cross-versioning has proven to be such a difficult problem that we're now recommending using multiple domains so the main app and child app are in separate sandboxes, then using allowDomain to share access if needed.
Flex SDK Developer
Adobe Systems Inc.
thank you for the qiuck reply. I am pretty sure the right things are in the bootstrap loader (all the classes that cannot be found are actually in there:).
snippet from bootstraploader:
import mx.rpc.events.ResultEvent; ResultEvent;
import mx.messaging.config.ConfigMap; ConfigMap;
import mx.messaging.messages.AcknowledgeMessage; AcknowledgeMessage;
import mx.messaging.messages.AcknowledgeMessageExt; AcknowledgeMessageExt;
import mx.messaging.messages.AsyncMessage; AsyncMessage;
import mx.messaging.messages.AsyncMessageExt; AsyncMessageExt;
import mx.messaging.messages.CommandMessage; CommandMessage;
import mx.messaging.messages.CommandMessageExt; CommandMessageExt;
import mx.messaging.messages.ErrorMessage; ErrorMessage;
import mx.messaging.messages.HTTPRequestMessage; HTTPRequestMessage;
import mx.messaging.messages.MessagePerformanceInfo; MessagePerformanceInfo;
import mx.messaging.messages.RemotingMessage; RemotingMessage;
import mx.messaging.messages.SOAPMessage; SOAPMessage;
import mx.messaging.channels.HTTPChannel; HTTPChannel;
import mx.messaging.Channel; Channel;
import mx.messaging.ChannelSet; ChannelSet;
import mx.messaging.SubscriptionInfo; SubscriptionInfo;
import mx.messaging.FlexClient; FlexClient;
import mx.messaging.MessageAgent; MessageAgent;
import mx.messaging.SubscriptionInfo; SubscriptionInfo;
import mx.messaging.config.ServerConfig; ServerConfig;
Otherwise my main app loaded by the bootstraploader wouldn't run too, right?
What you suggest would be ok if we created a web application, but i'm not sure how to do this with air. We download the subapp over https, store it in app-storage and load the bytearray into main with allowContentByteCodeExecution set to true like this:
private function init():void
var swfFile:File = File.applicationStorageDirectory.resolvePath("TestRO.swf");
// Open the SWF file
var fileStream:FileStream = new FileStream();
// Read SWF bytes into byte array and close file
var bytes:ByteArray = new ByteArray();
// Prepare the loader context to avoid security error
var loaderContext:LoaderContext = new LoaderContext();
loaderContext.allowLoadBytesCodeExecution = true;
loaderContext.applicationDomain = new ApplicationDomain();
// Load the SWF file
swfLoader.loaderContext = loaderContext;
swfLoader.source = bytes;
so init is called from main which is loaded by the bootstraploader.
i think it's pretty ok this way, but unfortunately it doesn't work, so i would like to try your approach with allowDomain, but how can we do that with a loaded ByteArray? allowDomain("*") would be a bit too much
And how could it be that if i load the subapplication from main do nothing with it, call a remote method on main, that i get errors too? so loading in a sibling application domain breaks the classes lookup from its sibling applicationDomain? stange...
any more insights would be hightly appreciated!
NB if the recommendation is not to use bootstraploader, maybe you can inform the docs team to update it because now adobe actually recommends
the use of it for multi versioned apps.
After some more investigation i tried explicitly making the main and subapplication applicationdomains children of the bootstrapper appllication domain
instead of not passing a applicationcontext to the loadercontext i tried new ApplicationDomain(ApplicationDomain.currentDomain); which according to docuentation should be the same as not giving an application domain. But it gives me different result:
loading the main goes well.
now after loading the subapplication from main in which which ApplicationDomain is also explicitly set as a child of the bootstrap domain i get the following error:
TypeError: Error #1034: Type Coercion failed: cannot convert mx.styles::StyleManagerImpl@13650359 to mx.styles.IStyleManager2.
at mx.styles::StyleManager$/get impl()[E:\dev\gumbo_beta2\frameworks\projects\framework\src\mx\styles\StyleManager.as:92]
at mx.styles::StyleManager$/registerInheritingStyle()[E:\dev\gumbo_beta2\frameworks\projects \framework\src\mx\styles\StyleManager.as:423]
at mx.preloaders::Preloader/timerHandler()[E:\dev\gumbo_beta2\frameworks\projects\framework\ src\mx\preloaders\Preloader.as:530]
in the source of StyleManager where it fails is a comment which is probabley not for nothing:
private static function get impl():IStyleManager2
// FIXME (pfarland): Do we need to check compatibility first?
_impl = IStyleManager2(
the problem is that it's an air app so the solution of Alex to use Security.allowDomain() cannot be used or am i missing something here?
this whole thing is puzzeling me.... its the same for flex4 and flex 3.4
I my case however the sub-app is the first to even use any of the remote service stuff, which should mean that it is the first one to load those classes, right? There should be no conflicting instances of this class loaded to my knowledge. Or is the data always sent through the ultimate parent (the AIR wrapper in my case), which is why it would need to know about those objects as well? but that sort of defeats the purpose of modularizing in that case, if I have to bootstrap the classes into the parent anyway.
I would also be interested in knowing how to use allowDomain in the case of AIR apps. Do you set app-store: as the allowed domain, or?
Anyway, we decided to go without loadForCompatibilty for now . The system we are building right now is a prototype and is probably going to need an overhaul in a couple of years anyway and during that time it will be acceptable to update everything to the latest SDK once or twice per year, since we will keep full control of the source anyway.