17 Replies Latest reply on Nov 13, 2012 11:30 AM by alaa@codeplus

    HELP: How to set WSDL at runtime (in Flex 4)?

    hshs350

      Hi,

       

      My flex application needs to communicate with a Web Service whose location is not known until after deployment; the service's location is known and static during development.  This means that my application should be able to communicate with the service whose wsdl url will be different from the "wsdl" value embedded in the Flex-generated code. 

       

      I can compute the wsdl url of the deployed service in the application at runtime.  However, I am unable to get the application to talk to the service running at the new location.

       

      Specifically, in application_creationCompleteHandler(), I do:

       

      ....

      var wsdl:String = hostString+"axis2/myService?wsdl";

      myWSvc = new MyWSvc(wsdl);

      ...

       

      In the constructor of MyWSvc(), which is the subclass of the auto-generated class for the My Web Service, I do:

       

      public function MyWSvc(runtimeWSDL:String=null) {

           super();

       

           if (runtimeWSDL != null) {

                wsdl = runtimeWSDL;

                _serviceControl.loadWSDL(wsdl);

                //model_internal::loadWSDLIfNecessary();

           }

      }

       

      This does not work; the auto-generated code always uses the WSDL value embedded in the auto-generated class for the My Web Service. 

       

      I would greatly appreciate your expert help in solving or getting around this issue.

       

      Much thanks,

       

      --Hyong

        • 1. Re: HELP: How to set WSDL at runtime (in Flex 4)?
          Darius

          Hi, I have same issue with Flex 4, this is our first Flex app and all I can find online is referring to earlier versions. We have 3 versions of the web service, dev, qa and prod and the URLs are fixed for each. For now I will create 3 separate classes and try to use the correct class during ANT deployment compilation for each env. Another approach is to setup a settings.xml that would be loaded at compilation and then use the values in the pregenerated class. That should work if the developer does not regenerate the code in eclipse overwriting the changed code. I'm still not clear on this second approach as the info online is all over the place and looks like much is not relevant with Flex 4.

           

          Did you find a solution?

          • 2. Re: HELP: How to set WSDL at runtime (in Flex 4)?
            hshs350 Level 1

            Hi,

             

            Unfortunately, no.  My workaround is to comment out the wsdl assignment and web service initialization code in the auto-generated constructor and execute them in the constructor of the subclass.  This is not satisfactory as the code in the auto-generated constructor have to be manually commented out every time the wsdl is complied.

             

            --Hyong

            • 3. Re: HELP: How to set WSDL at runtime (in Flex 4)?
              Darius Level 1

              I just started to continue working on this.

               

              I added this var in to the ANT build.xml and its passed in during the compilation:

               

              <define name="CONFIG::webServiceURL" value="'http://www.xxxxx.com/webservice_test/echocf7remote.cfc?wsdl'"/>

               

              Then in the pre-generates stabs I set the var at the top:

               

              private static const wsdlURL:String = CONFIG::webServiceURL;

               

              and modify the code bellow:

               

              //wsdl = "http://www.xxxxxx.com/webservice_test/echocf7remote.cfc?wsdl";
              wsdl = wsdlURL;

               

              It works but the developer needs to be careful and understand that if the class gets re-generated they will have to revert to the SVN copy.

               

              Next I need to figure out how to load in the correct external config file based on the user provided environment value to the deployment shell script.

              • 4. Re: HELP: How to set WSDL at runtime (in Flex 4)?
                Darius Level 1

                Here is what I did.

                 

                I set the settings for each environment in separate settings.xml files in SVN under seperated directories (dev,qa,prod).

                 

                Here is the syntax of the settings.xml files. Each will have its respective URLs.

                 

                <flex-config>

                <compiler>

                    <define>

                        <name>CONFIG::webServiceURL</name>

                        <value>'http://www.xxxxxx.com/webservice_test/echocf7remote.cfc?wsdl'</value>

                    </define>

                </compiler>

                </flex-config>

                 

                The deploy.sh script asks for the environment value (dev,qa or prod) among other params, and then passes that in to the Ant like this (note there are extra params for our setup):

                 

                ant -v -f build.xml -Dprojectname=${PROJECTNAME} -Dbranchname=${BRANCHNAME} -Dversion=${VERSION} -Denvironment=${ENV} -Dbuilddir=${BUILD_DIR} >> ${LOG_FILE}

                 

                These params are used inside the build.xml

                 

                After the Ant script checks the code out from SVN in to a staging directory, we load the proper settings.xml from the proper directory based on the user specified environment (in the deploy.sh).

                 

                <load-config filename="${staging.conf}/${settings.conf}/${environment}/settings.xml"/>

                 

                ${staging.conf} is defined in the build.properties and ${environment} is passed in the Ant call in the deploy.sh based on user provided input.

                 

                So if the user specifies 'dev' during the deploy.sh execution, then we would load the /build/staging/config/dev/settings.xml

                 

                Then in the pre-generates stabs I set the var at the top:

                 

                private static const wsdlURL:String = CONFIG::webServiceURL;

                 

                and modify the code bellow from hardcoded:

                 

                //wsdl = "http://www.xxxxxx.com/webservice_test/echocf7remote.cfc?wsdl";

                 

                to using the var:

                 

                wsdl = wsdlURL;

                 

                The nice thing is that all of the settings.xml 's are stored in the SVN and the correct version is used based on the environment provided by the user input during deployment script execution.

                 

                Perhaps there is a more elegant way of doing this but this works and we already use Ant, SVN and a deployment shell script so it fits right in for us.

                 

                • 5. Re: HELP: How to set WSDL at runtime (in Flex 4)?
                  luismsmoreira

                  Darius,

                   

                  With this solution you still need to change the hardcoded wsdl manually right?

                  So, if you refresh the service in flash builder, you need to change the wsdl again.

                   

                  I have this problem too, and everytime I need to publish an application, I have to change the wsdl manually. Did you find a better solution?

                  • 6. Re: HELP: How to set WSDL at runtime (in Flex 4)?
                    hshs350 Level 1

                    Unfortunately no.

                     

                    --Hyong

                    • 7. Re: HELP: How to set WSDL at runtime (in Flex 4)?
                      Kimmo Jokinen

                      I think I found a work-around (tested with flexsdk 3.5 in Flash builder 4) for the problem that survives service refreshs. It does not require one to manually edit the super class.

                       

                      First everything in the super class constructor needs to be copy pasted in to the inherited class' constuctor because the super class' can't be called as this would require modifying it after every refresh. In the inherited class' constuctor, the line with wsdl assignment needs to be removed. This effectively means the constructor does not generate the endpoints etc. from the wsdl used when importing the service.

                       

                      Next, the inherited classes constructor should not be allowed to call the super class' constructor. This does not work automatically as flex compiler automatically adds the call to super() if it is not found in the inherited class' constructor. From docs: "If the superclass constructor is not explicitly called, the compiler  automatically inserts a call before the first statement in the  constructor body". This means that super() must be found in the constructor. Luckily compiler only checks that super() is found.

                       

                      Now to the work-around:

                      // this need to be commented off
                              //wsdl = "snipped";
                      // wsdl == null, so it should not be called
                              model_internal::loadWSDLIfNecessary();
                              
                              if (1 == 0) {
                                  Alert.show("should not come here!");
                                  super();
                              }
                      
                      • 8. Re: HELP: How to set WSDL at runtime (in Flex 4)?
                        luismsmoreira Level 1

                        This is a good workaround, but you have to replicate the code of the super class into the service class.

                        I made some tests and it works with "simple" services, but if you use FB Data Management, the super class have lots of code that you have to replicate. And when you change something in the webservice, it will regenerate the super service class, and you have to replicate this code into the service class again.

                        So, it's easier to comment the wsdl in the super class every time that you compile, instead of replicating all the code again (If you made changes in the webservice).

                         

                        In this bug page, someone says that this was solved with a new init() function that you can override. I think that this correction was been made in the SDK 4.5, but I didn't test yet.

                        https://bugs.adobe.com/jira/browse/FB-27121

                        • 9. Re: HELP: How to set WSDL at runtime (in Flex 4)?
                          hugoFlex Level 1

                          I am also experiencing the same issue with this bug.  The workaround I am using is to comment out the model_internal::loadWSDLIfNecessary(); line that is located in the auto generated super class.

                           

                          In hopes that the bug was fixed in the Flex 4.5 SDK, I downloaded Flex 4.5 SDK along with Flash Builder Burrito.  However, the code generation works exactly the same from what I can tell.  It is also not clear from reading the comments in the bugs link (https://bugs.adobe.com/jira/browse/FB-27121), what the fix was exactly and what users are supposed to do to apply the fix.  Any ideas anyone?

                           

                          Has anyone else tried downloading Flex 4.5 SDK with any better luck at seeing how to implement the fix discussed in the bugs link?  If so, can you please share?

                          • 10. Re: HELP: How to set WSDL at runtime (in Flex 4)?
                            luismsmoreira Level 1

                            I have tried the SDK 4.5 with burrito without success too.

                            I don't know if I'm right, but I think that a new release of the fiber library correct this bug, but its not available yet.

                            The fiber is included with the flash builder, so I'm waiting for the Flash Builder 4.5 final release.

                            • 11. Re: HELP: How to set WSDL at runtime (in Flex 4)?
                              hugoFlex Level 1

                              That makes sense.  Thank you for replying.

                              • 12. Re: HELP: How to set WSDL at runtime (in Flex 4)?
                                hugoFlex Level 1

                                Ok, I've confirmed that this is now fixed in the Flash Builder 4.5 release.  fiber.swc in the Referenced Libraries is also now at version 4.5.  All I had to do was import my project in the new Flash Builder 4.5 and it regenerated the super class with the new preInitializeService.

                                 

                                The following code now exists in the preInitializeService method in the _Super service class (in my sample _Super_HelloWorld.as) instead of in the constructor as it was in 4.0.

                                 

                                [code language="actionscript3"]

                                    //init initialization routine here, child class to override

                                    protected function preInitializeService():void

                                    {

                                        _serviceControl.service = "HelloWorld";

                                        _serviceControl.port = "HelloWorldSoap";

                                        wsdl = "http://localhost/DotNetPractice/HelloWorld.asmx?wsdl";

                                        model_internal::loadWSDLIfNecessary();

                                    }

                                [/code]

                                 

                                ==========================

                                 

                                This can be overriden in the sub-class (in my sample HelloWorld.as) like so:

                                 

                                 

                                package services.helloworld

                                {

                                import com.adobe.fiber.core.model_internal;

                                 

                                public class HelloWorld extends _Super_HelloWorld

                                {

                                override protected function preInitializeService():void{

                                super.wsdl = "http://dev/HelloWorld.asmx?wsdl";

                                }

                                }

                                }

                                • 13. Re: HELP: How to set WSDL at runtime (in Flex 4)?
                                  luismsmoreira Level 1

                                  Hi, I have checked that today too.

                                   

                                  It's nice to have this problem solved, but the stupid thing is that we have to pay for the update that correct this bug.

                                  Al least is a small price and solve me a big problem.

                                  • 14. Re: HELP: How to set WSDL at runtime (in Flex 4)?
                                    hugoFlex Level 1

                                    yes, I agree...it's good it's fixed even though there is a price to it.

                                     

                                    fyi, this post is a modification to my original post in terms of formatting alone...In my original post, I was trying to format my code post using [code] tags but it didn't work.  I found out that syntax highlighting is handled by clicking on the >> in the toolbar of the rich text editor in these Adobe forums powered by Jive Clearspace, but now can no longer edit my original post.  So just in case there's any confusion, below is my post again with the correct formating (with the code tags meant for syntax highlighting removed) - syntax highlighter in the Adobe forums is somewhat hidden in the toolbar.

                                     

                                     

                                    ===============================

                                    Ok, I've confirmed that this is now fixed in the Flash Builder 4.5 release.  fiber.swc in the Referenced Libraries is also now at version 4.5.  All I had to do was import my project in the new Flash Builder 4.5 and it regenerated the super class with the new preInitializeService.

                                     

                                    The following code now exists in the preInitializeService method in the _Super service class (in my sample _Super_HelloWorld.as) instead of in the constructor as it was in 4.0.

                                     

                                     

                                        //init initialization routine here, child class to override
                                        protected function preInitializeService():void
                                        {
                                            _serviceControl.service = "HelloWorld";
                                            _serviceControl.port = "HelloWorldSoap";
                                            wsdl = "http://localhost/DotNetPractice/HelloWorld.asmx?wsdl";
                                            model_internal::loadWSDLIfNecessary();
                                        }
                                    

                                     

                                     

                                    ==========================

                                     

                                    This can be overriden in the sub-class (in my sample HelloWorld.as) like so:

                                     

                                     

                                    package services.helloworld
                                    {
                                    import com.adobe.fiber.core.model_internal;
                                    
                                    public class HelloWorld extends _Super_HelloWorld
                                    {
                                    override protected function preInitializeService():void{
                                    super.wsdl = "http://dev/HelloWorld.asmx?wsdl";
                                    }
                                    }
                                    }
                                    

                                     

                                    • 15. Re: HELP: How to set WSDL at runtime (in Flex 4)?
                                      alaa@codeplus

                                      OK, I know that this port is a year old, but I am having problem changing the WSDL using a an XML config file.

                                       

                                      The problem:

                                       

                                      Using Flash Builder 4.5 Connect to Data wizard I end uo with auto-genrated files _Super_SampleWebService.as and SampleWebService.as with

                                       

                                      As mentioned by hugoFlex, you can overwrite the preInitializeService()function inside SampleWebService.as to have a new WSDL location. However, if you are reading it from a config file this class runs before the my Config class actually reads the values from my config.xml file.

                                       

                                      As a work around, I added a timer and now my preInitializeService()looks like this:

                                       

                                      protected override function preInitializeService():void{

                                           //super.preInitializeService();

                                          super.serviceControl.service = "DashboardService";

                                           super.serviceControl.port = "DashboardServiceSoap";

                                           if(Config.config.hostIP == ""){

                                                timer = new Timer(1000, 3);

                                                timer.addEventListener(TimerEvent.TIMER_COMPLETE, test);

                                                timer.start();

                                           }

                                           else{

                                                if (timer != null && timer.running) { timer.stop();}

                                                super.wsdl = Config.config.hostIP;            

                                           }

                                       

                                           function test(e:TimerEvent):void{

                                                preInitializeService();

                                           }

                                       

                                      **sorry couldn't figure out how to create a code block

                                       

                                      This actually worked for setting the wsdl location. However, my actual service doesn't seam to work anymore. For example calling methods defined in this web service are not working. I did some debugging and it appears that the wsd = null. So changing the wsdl this way does not get reflected through out the code.

                                       

                                      Any ideas?

                                      • 16. Re: HELP: How to set WSDL at runtime (in Flex 4)?
                                        Kimmo Jokinen Level 1

                                        It seems you don't have the call to:

                                         

                                        model_internal::loadWSDLIfNecessary();

                                         

                                        after setting the wsdl. I cannot see the source for that method but I suppose it does some initializing based on the given wsdl.

                                         

                                        You also need to import the internal package for that to work:

                                         

                                        import com.adobe.fiber.core.model_internal;

                                        • 17. Re: HELP: How to set WSDL at runtime (in Flex 4)?
                                          alaa@codeplus Level 1

                                          Kimmo, you are correct. This solved it. I forgot about model_internal::loadWSDLIfNecessary(); It is in the parent class in the method I am overriding. I should have thought of that. Thank you again.