5 Replies Latest reply on Oct 19, 2009 12:00 AM by Jens Wegar

    Remote services call from loaded sub-app is nullified

    Jens Wegar Level 1

      I seem to be hitting issues with the whole sub-app theory all the time. My problem this time is that I have a AIR wrapper, which using SWFLoader loads a sub-app. The sub-app should connect to a remote PHP service (service created using the Data /Services wizard in FB4b1). If I set loadForCompatibility=false, then everything seems to work fine. However, if I set loadForCompatibility=true, then it seems to nullify the actual service request. Also, I get a type conversion error:

       

      TypeError: Error #1034: Type Coercion failed: cannot convert Object@1d82ffd9 to mx.messaging.messages.ErrorMessage.

       

      I attached screenshots of what Charles web debugging proxy shows when  loadForCompatibility=false (request-ok.png) and what it shows when  loadForCompatibility=true (request-error.png). The AIR wrapper doesn't use any web services, the sub-app is the first one to use any remoting classes.

       

      Any thoughts anyone?

        • 1. Re: Remote services call from loaded sub-app is nullified
          Arnoud Bos Level 1

          Same problem here...

           

          You should create a bootstaploader according the adobe documents:

           

          http://livedocs.adobe.com/flex/gumbo/html/WS2db454920e96a9e51e63e3d11c0bf69084-7f06.html

           

          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?

           

          thanx Arnoud

          • 2. Re: Remote services call from loaded sub-app is nullified
            Flex harUI Adobe Employee

            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.

             

             

             

            Alex Harui

            Flex SDK Developer

            Adobe Systems Inc.

            Blog: http://blogs.adobe.com/aharui

            • 3. Re: Remote services call from loaded sub-app is nullified
              Arnoud Bos Level 1

              Hi Alex,

               

              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;

              import mx.messaging.errors.MessagingError;

               

               

              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();

              fileStream.open(swfFile, FileMode.READ);

               

              // Read SWF bytes into byte array and close file

              var bytes:ByteArray = new ByteArray();

              fileStream.readBytes(bytes);

              fileStream.close();

               

              // 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.

               

              thanx

              Arnoud Bos

              • 4. Re: Remote services call from loaded sub-app is nullified
                Arnoud Bos Level 1

                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 _TestROModule_FlexInit$/init()

                at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::kickOff()[E:\dev\gumbo_beta2\frameworks\projec ts\framework\src\mx\managers\SystemManager.as:2606]

                at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::preloader_completeHandler()[E:\dev\gumbo_beta2 \frameworks\projects\framework\src\mx\managers\SystemManager.as:2532]

                at flash.events::EventDispatcher/dispatchEventFunction()

                at flash.events::EventDispatcher/dispatchEvent()

                at mx.preloaders::Preloader/timerHandler()[E:\dev\gumbo_beta2\frameworks\projects\framework\ src\mx\preloaders\Preloader.as:530]

                at flash.utils::Timer/_timerDispatch()

                at flash.utils::Timer/tick()

                 

                 

                in the source of StyleManager where it fails is a comment which is probabley not for nothing:

                 

                 

                private static function get impl():IStyleManager2

                    {

                        if (!_impl)

                        {

                            // FIXME (pfarland): Do we need to check compatibility first?

                 

                            _impl = IStyleManager2(

                                Singleton.getInstance("mx.styles::IStyleManager2"));

                        }

                 

                        return _impl;

                    }

                 

                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

                 

                help!

                 

                Arnoud

                • 5. Re: Remote services call from loaded sub-app is nullified
                  Jens Wegar Level 1

                  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.