Archive for the ‘ flex ’ Category

Flex: Annoyed with COMPC Ant task

In my continuing journey with TeamCity, I’ve discovered something highly annoying… not with TeamCity but with Adobe.

I’m trying to build a master configuration with an Ant script that will automatically build several child modules. First thing I realize is that I have to override the path properties of the child Ant script with relatives paths from the parent script. Ok, that makes sense since it’s a subtask being called from the scope of the parent, so the paths have to be from that directory.

Then I try to call COMPC in the child Ant script. It chokes hard with:

[compc] command line: Error: unable to open 'api/src/Manifest.xml'

“That’s odd,” I think. I know I’m passing it the right path (contained in the ${src.dir} property). However, just to check, let’s echo out the contents of the path I’m sending to the child script.

<fileset id="dir.contents" dir="${src.dir}" includes="*"/>
<property name="file.name" refid="dir.contents"/>
<echo>${file.name}</echo>

I run the script again, and lo and behold, guess what echoes out?

 [echo] Manifest.xml

wtf?

Ant says that the file exists in the path contained in the ${src.dir} property, but the COMPC task says it doesn’t exist?

<compc output="${build.dir}/${build.file}" debug="false">
	<include-namespaces uri="${namespace}" />
	<namespace uri="${namespace}" manifest="${src.dir}/${manifest.filename}" />
   ...

Still haven’t figured this one out, because I’m now stuck in the process of throwing darts with a blindfold on, simply guessing which directory COMPC thinks it’s starting from, because, of course, there’s no way to output anything from inside the COMPC task.

ARGH!!!

I’ve had a task I assigned to myself open for some time now. I needed to figure out how to implement Flex/ColdFusion messaging for our clients. There were three (3) criteria for success:

  1. It needed to integrate seamlessly with our existing Cairngorm Extensions
  2. It needed to allow for application level messages
  3. It needed to allow for client specific messages

The trick was to create an abstract class that multiple departments could use, because internally we use ColdFusion, Java and .NET to produce and consume messages. In our department, we use ColdFusion, so I had to create a concrete implementation of the abstract class called ColdFusionMessagingDelegate which handles the construction and publication of an AsyncMessage to a ColdFusion Event Gateway.

Other departments’ implementation of this process will be different, so I couldn’t force an implementation in the abstract class.

Additionally, in the application I was using for testing, I wanted to have two categories of messages:

  1. Messages intended to be produced and consumed by individual clients
  2. Messages intended to be consumed by any client

To that end, I created another abstract class at the application level that simply passed along specific a Flex Producer and Consumer for each category. I then created two concrete classes. One specified the Producer and Consumer for the application, and the other specified the Producer and Consumer for that individual client.

Here’s a diagram showing the architecture.

Generic Messaging Architecture

Generic Messaging Architecture

So far, it’s working great in the development test lab, but I still need to get with my colleagues for a group code review and hopefully fine tune the code and the architecture a bit more.

ColdFlash!

I see a trend happening at Adobe that I believe others may be detecting but no one has come out and said it yet. This trend will have a significant impact on software engineers who are experienced and/or committed to the Adobe stack of technologies – specifically to ColdFusion developers.

I have seen the question, “Why do I need to learn Flex?”, floating around for about two years now from many ColdFusion developers. These dedicated folks have noticed the ongoing trend of companies moving their user interfaces from straight HTML/Javascript to Flex.

Aside from noticing the trend being enough of a motivator to learn Flex (and it should be), the trend at the technology level should be additional motivator.

Blurring the Lines

The reason I entitled this article ColdFlash! is that I believe that by the time ColdFusion 11 is released to the public, the lines between ColdFusion and the Flash Platform will be practically eliminated to the point where entire applications can be written in the Actionscript language. ColdFusion will simply be another package available to Actionscript developers, much the same as data visualization.

Let’s take a look at some of the things that led me to this conclusion.

  • Back in ColdFusion MX 7, the ability to use ColdFusion on server-side Actionscript was introduced.
  • ColdFusion 8 greatly enhanced the ability to integrate ColdFusion with Actionscript applications with the inclusion of LCDS Lite, or using BlazeDS.
  • The ability to use ColdFusion functionality from Actionscript is finally marketed with ColdFusion 9, which, to me, indicates that Adobe is going to start expanding on this.
  • Enhanced Flash Remoting in ColdFusion 9. BlazeDS installed by default with the ability to upgrade to LiveCycle Data Services 2.6.1

A World of RIA

The era of static web applications is coming to an end. Everywhere you look, there are Flex web sites, Flex web applications, Flex business applications, iPhone apps, Android apps, AJAX sites and applications, and even Silverlight (but since this is an Adobe related article, we won’t focus on “that” technology).

Using these technologies allows developers to create interactive, responsive, intelligent, and user-friendly applications that people actually enjoy using – because in the end that’s what it’s all about. I’ve seen many apps created that perfectly fulfill the requirements established for it, but are disliked by the users because of the technical restrictions the old world of HTML placed upon it.

Of course, we’re still living in the world of HTTP, but with Adobe’s AMF protocol, it’s not as painful because our payloads have been drastically reduced – which increases responsiveness even further.

I believe what I’m trying to get at here is that RIA can no longer be considered a fad, a passing fancy, or a dead-end trend. Just like technologies such as ASP, ColdFusion and PHP completely transformed the Internets from a vast collection of non-interactive HTML pages into a data-aware, responsive universe, the RIA trend is the child of that revolution. Applications can now not only present data, but present it more quickly, more intelligently and in a more visually engaging way.

If you are ColdFusion developer, and not even considering learning some of the technologies is what is now called the Flash Platform, you are ensuring your continuing progression towards being along the same career path of a COBOL programmer. Granted, that’s an extreme example, and may not be accurate, but it conveys what I’m trying to get across.

It’s Still J2EE

For me, the most powerful feature of working with ColdFlash is that it’s all built on the Java platform. You could have Java developers, and ColdFlash developers in the same organization with no loss in productivity or community.

In fact, one of the things we’ve been considering in my team is the possibility of coverting some of our heaviest ColdFusion Components into Java code to increase our performance (sidebar: Let’s go ColdFusion team! We need even more speed on CFC creation) when sending back large arrays of objects to our Flex clients.

It’s Time to Evolve

In conclusion, I want to say that I don’t believe ColdFusion as a language is going away, Adobe has proven that it’s going to be a core component of the Flash Platform, but I do believe it is going to evolve into ColdFlash and that the best career move that ColdFusion developers can make right now is to learn Flash, AIR, and Flex.

In 2-3 years when the Flash Platform becomes more integrated, employers are going to be looking for the whole package, not just a ColdFusion developer, and not just an Actionscript developer.

Cairngorm 3: The cat is out of the bag

Now that I can officially talk about Cairngorm 3, I thought I’d put some of my thoughts down (more for my future reference, but feel free to follow along).

Alex Uhlmann officially announced the release of Cairngorm 3 beta on October 5th, and from my limited access to the documentation and code, I have a few opinions.

Cairngorm 3 != MVC

I think that it is a positive thing that Adobe Consulting decided to take their hat out of the ring of application architecture providers. The next release of Cairngorm is a complete paradigm shift for the project, in that it is – to simplify it a bit – a set of best practices and support libraries that developers can use within an application architecture such as Mate, Swiz or Parsley.

After I learned this fact, I was surprised that they kept the same project name, but it is a strong brand which will retain the current developer base and level of interest.

I also think that it lays the groundwork for a more free-market environment for other application architectures available today, or soon to be available. I know that a large consideration we made at DaVita was that since Cairngorm was produced by Adobe Consulting, that it would always be a strong contender, and most likely the proverbial 400-pound gorilla. Now that there is not an “official” application architecture supported by Adobe, then the weight of the brand is removed from the decision making. Now becomes about who has the architecture that is best implemented, best documented, easiest to integrate, etc.

It’s Smart Business

Looking at it strictly from a consulting business perspective, this approach to application development support is much more sustainable and has higher revenue-generating potential. If a shop chose to implement the Cairngorm 2 architecture, they may require assistance initially to get up to speed but eventually they become highly proficient and that well dries up.

In addition, it limits their business to people who implement Cairngorm 2.

Now that Cairngorm 3 can enhance and extend any architecture available – since it is about applying best practices – their consulting possibilities are now limitless. It doesn’t matter if you choose to use Mate, or PureMVC, because the Cairngorm 3 libraries can enhance them to support enterprise Flex development.

It’s a win-win situation. They get more business and more expertise, which in turn generates more ideas for Cairngorm, and makes their package more useful as time goes on.

Past Imperfect

However, I now wish I could turn back the clock 1 year and change the decision we made to implement Cairngorm 2 architecture. After doing internal testing of the major packages available, Cairngorm was not our main choice from a technical perspective, but was the top contender from the business perspective, and so we bit the bullet and adapted.

At the time, Mate was my choice for our application development efforts, and now we may have the discussion again internally about moving over. I know it won’t happen, for we’ve invested far too much time and effort into adopting Cairngorm, but I at least want to have the conversation.

Exciting Times

Lastly, I will say I am excited about this new direction that Adobe has taken, and we’ve already begun to play around with some of the code in-house. I’ll post reviews once I’ve had a chance to digest most of it.

1   Preface

At work, we’re investigating using ColdFusion Event Gateways to handle certain complex types of communication between our Flex user interfaces and ColdFusion, so yesterday I jumped on Google and started researching and ran into some roadblocks. However, after some monkeying around and more poring over of documentation and articles, I finally got a basic example working.

As usual, now that I’ve discovered how to set up a somewhat advanced feature of a platform, I’m sharing the knowledge in a comprehensive article. The documentation available for getting ColdFusion and Flex to communicate via event gateways was scattered, incomplete, or incomprehensible. In many of the articles, there were a lot of words, but little or no code, which does not help developers at all. Don’t tell me how it works, SHOW me how it works.

2   Creating a ColdFusion Listener Component

The listener component is the ColdFusion code that will receive any message sent from your Flex client via the DataServicesMessaging gateway type in your ColdFusion admin (more on that later). The basic structure is simple – just need one method named onIncomingMessage() in your component.

Create a file called InterceptFlex.cfc somewhere in your webroot and put the following code in it.

InterceptFlex.cfc

<cfcomponent output="false">
   <cffunction name="onIncomingMessage" returntype="any">
         <cfargument name="event" type="struct" required="true" />

	</cffunction>
</cfcomponent>

3   Setting Up Your Event Gateway

Now you need to go to your ColdFusion Administrator so that you can create an event gateway that specifies that any message coming in on a certain destination will be sent to the InterceptFlex component.

3.1   Destinations

There is a destination already set up for you in the \WEB-INF\flex\services-config.xml file (or \WEB-INF\flex\messaging-config.xml file if you are running BlazeDS) called ColdFusionGateway, and we’re just going to use that for this example.

You just need to make one change for this sample application to work. Open up the XML file and find the ColdFusionGateway destination. In the <properties> block add the following server property:

<properties>
   <server>
      <durable>false</durable>
      <allow-subtopics>true</allow-subtopics>
   </server>

   ...
</properties>

3.2   Gateway Setup

Now, go to the Gateway Instances section of your ColdFusion Administrator and start creating a gateway.

  1. The gateway ID can be anything, and you can just call it “test” for now.
  2. Select DataServicesMessaging as the type.
  3. The CFC path is the physical path to your InterceptFlex.cfc file you created.
  4. the configuration file is located in the \WEB-INF\cfusion\gateway\config\ directory, and you can use the one already set up named flex-messaging-gateway.cfg. So find that file and enter the path here.
  5. Click the Add Gateway Instance button.
  6. Start the gateway instance you just created.

4   Sending Messages From Flex

This application is a slight modification from the code provided in the Adobe article Introduction to the Flex Message Service, which I highly recommend you read if you’re new to Flex Messaging.

Create a new Flex application called Chat and paste this code into the Chat.mxml file. This code will connect to the ColdFusionGateway destination and send the message object to ColdFusion. ColdFusion, in turn, uses the event gateway instance we set up to send that object to the onIncomingMessage() method of the InterceptFlex.cfc component.

<?xml version="1.0" encoding="iso-8859-1"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*"
    pageTitle="Simple Flex Chat" creationComplete="createChat()">

    <mx:Script>
        <![CDATA[

        import mx.messaging.Consumer;
        import mx.messaging.Producer;
        import mx.messaging.events.MessageAckEvent;
        import mx.messaging.events.MessageFaultEvent;
        import mx.messaging.events.MessageEvent;
        import mx.messaging.messages.AcknowledgeMessage;
        import mx.messaging.messages.AsyncMessage;
        import mx.utils.ObjectUtil;

        private var chatPublisher:Producer;
        private var chatSubscriber:Consumer;

        private function createChat():void
        {
            chatPublisher = new Producer();
            chatPublisher.addEventListener(MessageFaultEvent.FAULT, onProducerFault);
            chatPublisher.destination = "ColdFusionGateway";

            chatSubscriber = new Consumer();
            chatSubscriber.addEventListener(MessageAckEvent.ACKNOWLEDGE, onConsumerAck);
            chatSubscriber.addEventListener(MessageEvent.MESSAGE, receiveChatMessage);
            chatSubscriber.destination = "ColdFusionGateway";
            chatSubscriber.subtopic = "simpleChat";
            chatSubscriber.subscribe();
        }

        private function onProducerFault(faultEvent:MessageFaultEvent):void
        {
            output.text += "[Error: " + faultEvent.message.toString() + "]\n";
        }

        private function onConsumerAck(ackEvent:MessageAckEvent):void
        {
            output.text += "[Got ack for subscribe or unsubscribe operation]\n";
        }

        // Note: these are the event-handling methods from above, now moved into the separate source file:

        private function sendChatMessage():void
        {
            var msg:AsyncMessage = new AsyncMessage();
            msg.body = input.text;
            msg.headers["username"] = "Me";
            msg.headers["gatewayid"] = "test";
            chatPublisher.subtopic = "simpleChat";
            chatPublisher.send(msg);
            input.text = "";
        }

        private function receiveChatMessage(msgEvent:MessageEvent):void
        {
            var msg:AsyncMessage = AsyncMessage(msgEvent.message);
            output.text += msg.headers["username"] + ": " + msg.body + "\n";
        }
        ]]>
    </mx:Script>

    
    <mx:Panel title="Simple Flex Chat">
        <mx:TextArea id="output" width="500" height="220" />
        <mx:TextInput id="input" width="500" enter="sendChatMessage()" />
        <mx:ControlBar horizontalAlign="center" width="500">
            <mx:Button id="clearBtn" label="Clear" click="output.text =''" />
        </mx:ControlBar>
    </mx:Panel>

</mx:Application>

5   Respond to the Flex Client

Now that ColdFusion has received the message, we’re simply going to respond back. You can enhance this to do anything you wish – send out emails, update database tables, log messages – but for now we’re just going to send a message back that let’s the Flex client know that the mechanism works.

<cfcomponent output="false">
   <cffunction name="onIncomingMessage" returntype="any">
      <cfargument name="event" type="struct" required="true" />

      <cfscript>
      x = structNew();
      x.body = "hello right back at ya";
      x.destination = "ColdFusionGateway";
      x.headers = structNew();
      x.headers['username'] = "System";
      x.headers['DSSubtopic'] = "simpleChat";
      x.lowercasekeys = "yes";
      </cfscript>

      <cfreturn x />
   </cffunction>
</cfcomponent>

One of those esoteric details that took me forever to find out was how to apply a subtopic to a message in ColdFusion. In Flex, it’s absurdly simply, you simply say message.subtopic = “myTopic”;, but in ColdFusion, you have to set a header key named DSSubtopic with the topic name (see above).

6   Conclusion

To be safe, restart your ColdFusion instance, then fire up the simple Flex chat app and type in a message. After a few seconds, you will receive a message from System in the history box.