5 Replies Latest reply on Feb 6, 2008 1:02 AM by cf_matt

    Flex Builder 2 + Coldfusion 8 + BlazeDS = headache!

    cf_matt
      I’m using flex 2 and I’ve tried referencing a coldfusion cfc with a return type of xml using mx:HTTPService, when I output the cfc in coldfusion or the browser it says its xml and its fine. When I try and access it through flex it doesn’t recognise it as xml.

      If I copy the XML in to a text file and name it .xml flex connects to it fine. Very strange.

      I’ve tried using mx:RemoteObject, this doesn’t work at all so obviously I need dataservices set up on the server.

      So I setup BlazeDS on our Coldfusion 8 test box but its proving to be a bit of a nightmare.

      We have a file mapping set up to access our file server, which is a different box.

      The url is:
      http://192.168.1.21:8700

      the file path to coldfusion is:
      C:\JRun4\servers\cfusion\cfusion-ear\cfusion-war\WEB-INF

      I don’t have an option to have the files compile in a different folder e.g \\web-svr\mysite\flex\

      When I go to compile the flex file, I get errors saying flex-config.xml doesn’t exist, it also will only compile to the flex server root

      I’m wondering if I should be using flex 3, although I can’t at the moment because my beta I installed a while ago has expired.

      I’m thinking now of forgetting blaze and trying flash remoting services as they are built into coldfusion 7.02 (which is on our main development box

      If there is anyone out there that can help with this i would really appreciate it!
        • 1. Flex Builder 2 + Coldfusion 8 + BlazeDS = headache!
          greenhippo
          Im afraid i cant help you as i have not configured it with coldfusion before, but might be worth your while posting your question on BlazeDS forums too
          • 2. Re: Flex Builder 2 + Coldfusion 8 + BlazeDS = headache!
            Ratsnackbar Level 2
            Well actually I have not set up Blaze DS either but ColdFusion8 already has LCDS built into it so you really should not have to set up Blaze DS. I would suggest using RemoteObjects over Remoting regardless unless you happen to need Push Technology. I have an old Email saved that I had sent to a friend on how I set up one application for remoting. Not sure it applies to what you want but I could post it if you want.
            • 3. Re: Flex Builder 2 + Coldfusion 8 + BlazeDS = headache!
              cf_matt Level 1
              Thanks greenhippo and Ratsnackbar
              Ratsnackbar - I didnt know the services were built in. If this is the case i'm confused as to why it isnt working at all, I did try just using a mx:RemoteObject but it didnt seem to work.

              Could I see the e-mail you sent, it might help!

              Thanks

              Matt
              • 4. Re: Flex Builder 2 + Coldfusion 8 + BlazeDS = headache!
                Ratsnackbar Level 2
                It's very possible this method will not work for you but I have found it a quick and easy way to connect to cfc's on the back end. I would suggest the RemoteObjects using Flex Remoting as long as you do not need to push data out to clients from the server without their interaction.

                Note:If you have ColdFusion 8 installed you should not need to use BlazeDS. It already has FDS installed though it is not multi threaded unless you get a license. I believe they call it Live Cycle Data Services ES now. Flash Remoting is already available also. Normally you would have to configure at least one XML file on the server but my method listed below avoids that.

                Email Starts----------------------------------------------------------------------------------- --------------------------

                If you would like to see my development environment setup you can check out my response in this post;

                http://www.adobe.com/cfusion/webforums/forum/messageview.cfm?forumid=60&catid=585& threadid=1334317&enterthread=y

                because I an sure as hell not going to type it again.

                It might help to understand how I set things up. Especially the bit about compiling directly to the server. (Ya gotta love that trick.) I don't even like to do a file copy across the network manually if I do not have to. However it's a long post.

                I really hate having to configure XML Files and if there is anyway I could get away with it I did not want to have to configure an xml block for every one of my cfc "services". The App I was building at the time could have hundreds of cfc's. That would be one big xml file, so I went looking for a better way to do it. In the book Flex 2 Training from the Source they describe a datamanager class for connecting to webservices using the singleton patter. Later I found that someone had written the same type of thing for ColdFusion RemoteObjects which is posted here.

                http://jeff.mxdj.com/creating_a_remote_object_datamanager_in_actionscript_30_for_.htm

                This was cool and got me part of the way down my path to Laziness but it still means you have to configure the services in an XML file on the server side. So I pulled out my Handy Dandy Lazy ******* Pocket Reference and got to work.

                (Sorry for the length of this by the way. Seems I spend my hard won extra time in talking about how I acquired it.)

                ****************************Code Begins******************************
                package com.ratsnackbar.actionscript.managers{
                import com.ratsnackbar.actionscript.events.DataManagerResultEvent;

                import flash.events.EventDispatcher;
                import flash.utils.*;

                import mx.rpc.AbstractOperation;
                import mx.rpc.events.FaultEvent;
                import mx.rpc.events.ResultEvent;
                import mx.rpc.remoting.mxml.RemoteObject;

                /**
                * DataManager - singleton class which enforces only
                * a single object is created for each service. To
                * access DataManager, use getDataManager(CFSvc:String,Source:String)
                * CFSvc should be the name of the service you are trying to reach on the ColdFusion server.
                * Normally this is going to be "ColdFusion" for most "Lazy *******" implementations.
                * Source should be the source path. Ex. "com.myDomain.coldfusion.cfc.myCFCName"
                */
                public class DataManagerCF extends EventDispatcher{
                private var CFsvc:RemoteObject;
                private var CFSource:String;
                private var eventName:String;

                //hashmap of instances for each service
                private static var instanceMap:Object = new Object();

                public function DataManagerCF(pri:PrivateClass,dest:String,CFSource:String){
                this.CFsvc = new RemoteObject();
                CFsvc.destination = dest;
                CFsvc.source = CFSource;
                }

                public static function getDataManager(CFsvc:String,Source:String):DataManagerCF{
                var CFSource:String = Source;
                if(DataManagerCF.instanceMap[CFSource] == null){
                DataManagerCF.instanceMap[CFSource] = new DataManagerCF(new PrivateClass(),CFsvc,CFSource);
                }
                var dm:DataManagerCF = DataManagerCF.instanceMap[CFSource];
                return dm;
                }

                public function makeRemoteCall(methodName:String, eventName:String,...args:Array):void{
                this.eventName = eventName;
                var op:mx.rpc.AbstractOperation = CFsvc[methodName];
                CFsvc.addEventListener("result", doResults);
                CFsvc.addEventListener("fault", doFault);
                if(args.length > 0){
                op.send.apply(null,args);
                } else {
                op.send();
                }
                }

                private function doResults(result:ResultEvent):void{
                CFsvc.removeEventListener("result",doResults);
                var e:DataManagerResultEvent = new DataManagerResultEvent(eventName, result.result);
                this.dispatchEvent(e);
                }

                private function doFault(fault:FaultEvent):void{
                CFsvc.removeEventListener("fault",doFault);
                this.dispatchEvent(fault);
                }

                public override function toString():String{
                return "DataManagerCF";
                }
                }

                }

                /** PrivateClass is used to make
                * DataManager constructor private
                **/
                class PrivateClass{
                public function PrivateClass() {}
                }
                ***************************************Code Ends*******************************

                Note you will also want to get the DataManagerResultEvent class which I believe you can get from the Flex 2 TFTS errata site.

                I have plans to rework it later on to use a different method for creating a singleton and add my own flavor of security and user validation but for now this is all I can give you.

                Still with this you do not have to configure your services on the CF8 server to use them. Just use "ColdFusion" for the service and the class path from your webroot to the cfc as the "Source" when you instantiate this class and you are golden.

                I have set it up so that instead of an instance for each service now it has an instance for each specific CFC which makes for more overhead but greater "Flex"ability, less overall code and I can program without ever having to terminal into my server and try to remember how to configure the services-config file. :D

                For Example in one of my classes that uses something like these lines to set up the connection.

                private static const CFSERVICE:String = "ColdFusion";
                private static const CFC_PATH:String = "com.myDomain.coldfusion.cfc.myGateway";
                private var dm:DataManagerCF = DataManagerCF.getDataManager(CFSERVICE,CFC_PATH);
                private var fm:FaultManager = new FaultManager();

                To make a call to one of the CFC's and then handle the results I do something like this.

                public function loadSomeArray():void{
                dm.addEventListener("myEvent", myResultHandler,false,0,true);
                dm.addEventListener("fault", handleFault,false,0,true);
                dm.makeRemoteCall("getSomethingFromCFC","myEvent");
                }

                private function myResultHandler(event:DataManagerResultEvent):void{
                anArray = event.result as Array;
                //Do some more stuff here...........Or Don't........See If I care.
                }

                private function handleFault(event:FaultEvent):void{
                fm.genericFaultHandler(event);
                }



                ------------------------------------------------------------------------------------------ ----------------------------------

                So anyway if you do not need things like Synchronized Record Locking or server push technology then this is a quick and efficient way to get to your CFC.

                -Joe

                Courtesy of the Lazy ******* Pocket Reference.
                • 5. Re: Flex Builder 2 + Coldfusion 8 + BlazeDS = headache!
                  cf_matt Level 1
                  Thanks for that Ratsnackbar

                  I shall give that a go and let you know how i get on!

                  Thanks again

                  Matt