21 Replies Latest reply on Jul 15, 2010 10:32 AM by Flex harUI

    Casting loaded application to SystemManager

    ilya_k

      Greetings!

       

      I have RIA app which loads sub-app. Loaded sub-app implements ILoadable interface.

       

      App code looks simple nothing fancy as follows:

       

                 // loaded sub-application class reference

                  private var sccLoadable:ISCCLoadable;

                 

                  // swf loader reference

                  private var contentLoader:SWFLoader;


                  public function loadSwf(args:Object):void

                  {

                      componentUrl = args.url;

                     

                      contentLoader = new SWFLoader();

                      contentLoader.autoLoad = false;

                      contentLoader.showBusyCursor = true;

                      contentLoader.trustContent = true;

                      contentLoader.scaleContent = true;

                      contentLoader.percentHeight = 100;

                      contentLoader.percentWidth = 100;

                      contentLoader.addEventListener(Event.COMPLETE,  onLoadComplete, false, 0, true);

                      contentLoader.addEventListener(IOErrorEvent.IO_ERROR, onLoadError, false, 0, true);

                      contentLoader.source = componentUrl;

                      contentLoader.load();

                 }


                  public function onLoadComplete(event:Event):void

                  {

                      trace("[loadCompleteHandler]", "load of '"

                          + contentLoader.source + "' into AdminConsole complete.");


                      loadedApp = event.target.content as SystemManager;

                      contentLoader.removeEventListener(Event.COMPLETE, onLoadComplete);

                      contentLoader.removeEventListener(IOErrorEvent.IO_ERROR, onLoadError);

                      loadedApp.addEventListener(FlexEvent.APPLICATION_COMPLETE, onSubappComplete, false, 0, true);

                }


                  public function onSubappComplete(event:FlexEvent):void

                  {

                      trace("[onSubappApplicationComplete]", "Loaded sub-app application compete handler called");


                      // cast the loaded application to the Interface

                      sccLoadable = event.currentTarget.application as ILoadable;

                 ....

              }

       

      Sub-app looks as follows:

       

      <?xml version="1.0" encoding="utf-8"?>

      <mx:Application implements="ILoadable"

                      xmlns:mx="http://www.adobe.com/2006/mxml"

                      >


          <mx:Script>

              <![CDATA[

              ......

              ]]>

          </mx:Script>

      </mx:Application>

       

      When both - app and sub-app are deployed into "my-domain"  http://<server>:port/<my-domain> everything works. But due to some

      architectural decision sub-app should live on a server side but not in <my-domain>. So, when I moved out sub-app from "my-domain"
      the above solution stopped working just because I can not cast  loadedApp to SystemManager.
      loadedApp = event.target.content as SystemManager;  // returns null because
      When sub-app loaded from "my-domain" event.target.content is _subApp_mx_managers_SystemManager
      However when sub-app loaded from file system event.target.content is subApp.

       

      Is it security issue. And if it is, how to get it working?

       

      Thank you in advance.

       

       

       

       

        • 1. Re: Casting loaded application to SystemManager
          Flex harUI Adobe Employee

          I think you need a crossdomain.xml on the sub-app server

          • 2. Re: Casting loaded application to SystemManager
            ilya_k Level 1

            Thanks Alex. 

             

            I put crossdomain.xml in the root of domain in "my-domain" folder on the server.

             

             

             

            <?xml version="1.0"?>

            <!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">

            <cross-domain-policy>

              <site-control permitted-cross-domain-policies="all"/>

              <allow-access-from domain="*" secure="false"/>

              <allow-http-request-headers-from domain="*" headers="*" secure="false"/>

            </cross-domain-policy>

             

             

            Same issue. Is it something wrong with crossdomain file?

            • 3. Re: Casting loaded application to SystemManager
              ilya_k Level 1

              Clarification...

               

              Both app and sub-app are hosted on same node. App is loaded via HTTPS request as https://ilya-server:8283/scc,

              sub-app resides on same ilya-server but not in C:/services/web-container/webapps/scc but in C:/plugin/assets/swf

               

              Thank you

              • 4. Re: Casting loaded application to SystemManager
                Flex harUI Adobe Employee

                I am not an expert on this stuff, but what matters is the urls, not the file

                paths.

                 

                http://a.b.com is not the same as http://d.b.com

                 

                Using https: might require careful setting of the secure option.

                 

                What is the url to the sub-app?

                • 5. Re: Casting loaded application to SystemManager
                  ilya_k Level 1

                  Thank you, Alex, for looking into this...

                   

                  It appears that it is maybe Flash 4 bug. Maybe. Not sure but  it is why:

                  The sub-app.mxml  was created in Flash 4  project by copying sub-app.mxml file from another project.

                  Then in Project->Properties->FlexApplication dialog I have added sub-app.mxml as the

                  application to this project, built deployed it and... run into weird problem I described in previous post.

                  Then I removed  and recreated  the sub-app.mxml  as usual: Right click -> New -> New MXML Application. 

                  and restored the entire previous content. After that I was able to cast it to SystemManager.

                  So the difference between those two is only the way how sub-app.mxml was added to the project.

                  Strange. Does not make sense but it is what it is...

                   

                  Now after I passed the initial step I run into next problem. But before describing it I would like to

                  answer your question what is the url for sub-app.

                   

                  As I mentioned, sub-app swf lives on a server side not under application domain root but

                  somewhere on file system.

                  On server side, which is Java, I have FronController servlet. It processes HTTP GET/POST.

                   

                  GET request's query string contains information where to find sub-app swf-file.

                  in doGet() servlet locates and writes swf-file as a byte steam back to the client:

                   

                  @Override

                  protected void doGet(final HttpServletRequest request, final HttpServletResponse response)

                       throws ServletException, IOException

                  {                                                                                              

                              .....
                              int len;
                              final byte[] buffer = new byte[response.getBufferSize()];
                              final ServletOutputStream os = response.getOutputStream();
                              final FileInputStream is = new FileInputStream(requestedFile);
                              while (is.available() != 0)
                              {
                                  len = is.read(buffer);
                                  os.write(buffer, 0, len);
                              }
                              os.flush();
                              ....

                  }
                  After onSWFLoadComplete() callback is invoked I know that sub-app byte stream has been transfered to the client,  I cast it to SystemManager and
                  add applicationComplete()  listener.   Withing applicationComplete() I want to cast sub-app to the interface it implements:
                  This is sub-app:
                  <?xml version="1.0" encoding="utf-8"?>
                  <mx:Application
                      implements="com.xyz.scc.composites.ISCCLoadable"
                      layout="absolute" minWidth="955" minHeight="600"
                      >
                     
                      <mx:Script>
                          <![CDATA[
                              import com.xyz.scc.composites.ISCCLoadable;
                              import com.xyz.scc.composites.SCCLoadableWizardBase;
                             
                              import mx.core.UIComponent;
                             
                              private var _component:UIComponent;

                              /*
                              * ---- Interfce methods ----
                              */
                                         
                              public function init(queryString:String):void
                              {
                              }
                             
                              public function finalize():void
                              {
                              }
                             
                              public function get component():UIComponent
                              {
                                  // Returns _component object - visual component this application instantiates.                
                                  return _component;
                              }
                          ]]>
                      </mx:Script>           
                         
                  </mx:Application>
                  Interface:
                  package com.xyz.scc.composites
                  {
                      import mx.core.UIComponent;
                     
                     public interface ISCCLoadable
                      {
                          function init(args:String):void;
                          function finalize():void;
                          function get component():UIComponent;
                      }
                  }
                  Loading application:
                  private var sccLoadable:com.sybase.scc.composites.ISCCLoadable;
                  /**
                    * Invoked after sub-app has been added to display list
                  */
                  public function onSubappApplicationComplete(event:FlexEvent):void
                  {
                         trace("[onSubappApplicationComplete]", "Loaded sub-app application compete handler called");
                              
                        // cast the loaded application to the Interface
                        sccLoadable = event.currentTarget.application as com.xyz.scc.composites.ISCCLoadable;
                  }
                                 
                  Now I can not cast loaded sub-app to the ISCCLoadable interface which sub-app implements.
                  TypeError: Error #1034: Type Coercion failed: cannot convert TestLoad@18d315c1 to com.xyz.scc.composites.ISCCLoadable.
                  Although event.currentTarget = _TestLoad_mx_managers_SystemManager (@18d0f0b1)
                  What could it  be?
                  Thanks,
                  _Ilya.
                          

                  • 6. Re: Casting loaded application to SystemManager
                    Flex harUI Adobe Employee

                    It could be a bug, but I doubt it.  You have not really answered my

                    question. What is the url for the sub-app?  If you have a network monitor,

                    see if there is a request for the crossdomain.xml.  Without it, the SWF will

                    remain untrusted and you cannot access the classes in the sub-app.

                    • 7. Re: Casting loaded application to SystemManager
                      ilya_k Level 1

                      Oh, I thought I answered your question. Perhaps I was not clear enough.

                       

                      There is no URL as such for loading sub-app. Client sends HTTP GET request

                      to the HTTP Server "give me such-and-such file"  as follows:

                       

                      swfLoader = new SWFLoader();

                      ....

                      swfLoader.source = "/scc/pm?com.xyz.ua.plugins.sccmap,3.2.0,assets/swf/ResRegistrationApp.swf ";

                      swfLoader.load();

                       

                      Source value as usual defines a location of the resource (swf-file) but it is not URL strictly speaking but URI.

                      FronController knows how to translate request to the absolute pathname, say, to

                      C:\scc\plugins\sccmap\assets\swf\ResRegistrationApp.swf.

                      Then FrontController reads the file and sends it back to the client. After file is transmitted client continues work as usual.

                       

                      As far as suspicious behavior is concerned then after I created sub-app in Flash 4 New->MXML_Application I was able to

                      cast loaded content as SystemManger.  But I still can not cast loaded application to the interface it implements.

                       

                      I bet you are right that crossdomain.xml is required to make it working but I can not figure out what and where it should be.

                      Main application domain clear is something like a.com. But sub-app SWF is loaded from file system. How to make it trusted?

                       

                      I can not use network monitor because due to backward compatibility requirements I am running with SDK 3.3 event

                      in Flash 4.

                       

                      Thank you,

                      _Ilya

                      • 8. Re: Casting loaded application to SystemManager
                        Flex harUI Adobe Employee

                        If you are mixing versions of the SDK, you cannot use interfaces to

                        communicate as you have to use loadForCompatibility=true.

                         

                        Since you are specifying an absolute path to the servlet, I would expect the

                        sub-SWF comes from the root of your server, and that's where the

                        crossdomain.xml should go.  If you can dump out the loaderInfo.url of the

                        sub-app you'll be able to figure out where it thinks it came from.

                        1 person found this helpful
                        • 9. Re: Casting loaded application to SystemManager
                          ilya_k Level 1

                          sub-app URL:

                          https://localhost:8283/scc/pm?com.xyz.ua.plugins.sccmap,3.2.0,assets/swf/TestLoad.swf

                          loader.loaderURL for sub-app:

                          https://localhost:8283/scc/main.swf/[[DYNAMIC]]/1

                           

                          Absolute sub-app SWF-file  pathname on server side:

                          C:\project\scc32\deploy\SCC-3_2\plugins\SccManagementAgentPlugin\assets\swf\TestLoad.swf

                           

                          It is not clear to me what loaderURL points at but what is more important I do not think that my

                          cross-domain policy file is correct in  this scenario:

                           

                          <?xml version="1.0"?>

                          <!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">

                          <cross-domain-policy>

                            <site-control permitted-cross-domain-policies="all"/>

                            <allow-access-from domain="*" secure="false"/>

                            <allow-http-request-headers-from domain="*" headers="*" secure="false"/>

                          </cross-domain-policy>

                           

                          I tried to put crossdomain.xml in https://localhost:8283/scc, in https://localhost:8283/ and in https://localhost:8283/ROOT.

                          (I refer to actual folders on server side:

                          C:\project\scc32\deploy\SCC-3_2\services\EmbeddedWebContainer\webapps\scc,

                          C:\project\scc32\deploy\SCC-3_2\services\EmbeddedWebContainer\webapps,

                          C:\project\scc32\deploy\SCC-3_2\services\EmbeddedWebContainer\webapps\ROOT). 

                          Nothing seems to help. Either location or policy file are wrong or maybe something else...

                           

                          Thank you very much for your help,

                          _Ilya

                          • 10. Re: Casting loaded application to SystemManager
                            ilya_k Level 1

                            Found in http://livedocs.adobe.com/flex/3/html/help.html?content=deployingoverview_12.html

                             

                            Your system might be configured to allow a Flex application to directly access server-side resources on different domains or different computers without going through a proxy. These operations  fail under the following conditions:

                             

                            • When the Flex application's SWF file references a URL, and that URL is outside the exact domain of the SWF file that makes the request
                            • When the Flex application's SWF file references an HTTPS URL, and the SWF file that makes the request is not served over HTTPS

                            To make a data service or asset available to SWF files in different domains or on different computers, use a crossdomain policy file on the server that hosts the data service or asset. A crossdomain policy file is an XML file that provides a way for the server to indicate that its data services and assets are available to SWF files served from certain domains, or from all domains. Any SWF file that is served from a domain specified by the server's policy file is permitted to access a data service or asset from that server. By default, place the crossdomain.xml at the root directory of the server that is serving the data.

                             

                            Does it mean that I am in trouble and crossdomain.xml will not help?

                             

                            Thanks,

                            _Ilya

                            • 11. Re: Casting loaded application to SystemManager
                              Flex harUI Adobe Employee

                              If you use a browser to hit https://localhost:8283/crossdomain.xml

                              Do you see the xml file?  Make sure that's working.

                               

                              Next, try going back to http instead of https just to make sure that there

                              isn't some secure flag issue.

                              • 13. Re: Casting loaded application to SystemManager
                                Flex harUI Adobe Employee

                                I am suggesting you try http instead of https.

                                 

                                If you still have problems, re-post your latest SWFLoader settings.  Are

                                both the main SWf and sub-app being compiled with the same version of Flex?

                                If so, which one?

                                • 14. Re: Casting loaded application to SystemManager
                                  ilya_k Level 1

                                  Q: I am suggesting you try http instead of https.

                                  A: I am doing it now...

                                   

                                  Q: Are both the main SWf and sub-app being compiled with the same version of Flex? If so, which one?

                                  A: Yes, they are. I do not mix SDK versions. They compiled with Flex  SDK 3.3.0.

                                   

                                  Thank you.

                                  _Ilya

                                  • 15. Re: Casting loaded application to SystemManager
                                    ilya_k Level 1

                                    It will take a while to turn off security in this enterprise app - too many layers.

                                     

                                    There is related question:

                                    In same scenario main app linked dynamically with Flex RSLs and custom RSLs.

                                    Sub-app, which loaded from outside of the exact domain of the main SWF file, linked

                                    dynamically as well with Flex RSLs and same custom RSLs.

                                     

                                    Main app loaded itself and loads RSLs.

                                     

                                    At run-time, when sub-app loaded, will it require all RSLs it linked with, to be at same location where it

                                    loaded from? And will it load them as if they are different from those which have been loaded by main app?

                                     

                                    Thanks,

                                    _Ilya

                                    • 16. Re: Casting loaded application to SystemManager
                                      Flex harUI Adobe Employee

                                      Just use a new simple testcase so you odn't have to worry about security.

                                       

                                      A sub-app is compiled with urls to the RSLs.  It will try to use them.

                                      1 person found this helpful
                                      • 17. Re: Casting loaded application to SystemManager
                                        ilya_k Level 1

                                        Thanks Alex!

                                         

                                        If I understand/understood you correctly, sub-app has to be packaged and deployed with RSLs

                                        and it will try to use them at run-time.

                                         

                                        Is there any way to link sub-app so it would use same RSLs that main app does?

                                         

                                        Thank you very much,

                                        _Ilya

                                        • 18. Re: Casting loaded application to SystemManager
                                          ilya_k Level 1

                                          And my primary concerns is not custom RSLs which I understand should be packaged with every sub-app but

                                          Flex framework RSLs swz. May sub-app in the my scenario reuse Flex RSLs which have been loaded when

                                          main app loaded?

                                           

                                          Thanks,

                                          _Ilya

                                          • 19. Re: Casting loaded application to SystemManager
                                            Flex harUI Adobe Employee

                                            The sub-app will load the swz RSLs again, but they will have already been

                                            cached by the player when the main app fetched and loaded the RSLs.

                                            • 20. Re: Casting loaded application to SystemManager
                                              ilya_k Level 1

                                              It came to my surprise, Alex. I know that signed Flex RSLs have been cached in Flash Player cache already. Why sub-app needs to load them again? And what will happen after sub-app unloaded and then loaded again? I hope that this time sub-app does not load signed RSLs again since they also have been cached I believe with diff URL. If it does, what is the point to link sub-app with RSLs? What is happening with unsigned RSLs - Flex's and custom? Does sub-app loads them  over and over again every time it loaded even they have been cached in browser cache?

                                               

                                              Thanks,

                                              _Ilya

                                              • 21. Re: Casting loaded application to SystemManager
                                                Flex harUI Adobe Employee

                                                The RSL system isn't that smart.  When you build an app, you don't know if

                                                it is a sub-app or not.  Sub-apps generally should be able to run on their

                                                own.  Thus the system will try to load the RSLs each time.  You can use

                                                -load-externs and -static-rsls if you want to make the sub-app dependent on

                                                the main app and save loading.