Tagged: flex

My first brush with Cairngorm

So after reading “Professional Cairngorm” I decided that I would try using Cairngorm on my next project. Well that project is is the final stages of completion and I’d like to share my thoughts.

The project was a dynamically driven Flex app embedded in a web-browser that could also run on AIR. The application was read-only and did not collect data from the user but simply presented data one way. This app consisted of a your typical main screen, featuring configurable “portlets” that gave teasers into the deeper content contained within. It also had primary top navigation each of which drove to sub-screens which could render their data-sets in various customizable layout views, each of which having its own set of second level navigation to navigate within that sub screen. The data was stored in an XML implementation of an “Content Store” interface which could also be swapped out with a SQLite or web-service backed version if necessary. The lower level service layer that stored and managed all of the content as well as the navigation meta-data was wired together using Spring Actionscript and also leveraged other libraries like AS3 Commons.

For the application logic itself (i.e. how the views render, how the user navigates around, what screen renders what data etc) was all handled by using Caringorm 2.2.

By default, Cairngorm seems to drive the developer to be extremely granular with their Command, CairngormEvent and Delegate declarations. What this means is that if you are not careful, you will end up with an absolute overload of classes for a simple application. Instead I took the approach consolidating domain related functionality into larger Delegate classes which could handle more than one type of small specific operation. My Delegate classes abstracted away my lower level service layer (where the content and navigation meta-data was stored) away from the application and fulfilled its contracts through the delivery of VOs to the commands, subsequently to the model and finally to the views via Flex data binding.

I also tried to limit the number of events down to a total of four, one for bootstrapping Spring, one for handling a screen change, one for rendering the correct body and finally one for launching external resources. The number of VOs (value objects) I ended up with was fairly large (about 10) as I was very careful to create granular VOs so that I had zero coupling with the underlying service layer which was hidden away by the Delegate classes. The underlying service layer certainly had its own VO like objects which I could have permitted to bubble up to the model/view, but taking the decoupled VO approach is the way to go in an MVC framework such as Cairngorm. You can end up replicating a lot of properties etc, but it is worth it in the long run as your VOs help you gel your domain model without tying it to the underlying implementation.

In the past I’ve played around with PureMVC, as well as my own custom MVC like framework for throwing together quick Flex apps. Overall I would say that my experience with Cairngorm in this small app was a positive one. There was a slight learning curve to get going, but it was not difficult at all if you have used other MVC frameworks in any other language. Cairngorm is heavily dependent upon Flex/AS3’s internal data binding and that can be a positive or negative depending on your personal views, however I found it to be quite powerful and convenient.

On the downside, the most awkward thing in Cairngorm for me was the Model (ModelLocator), for a small app like this one it was fine, but it just seems like a giant “global variable” store (not seems, it is in fact one) and if you are doing a complex app, I feel it would be necessary to break this up into different model’s for different parts of the application. Ideally each view should not be directly bound to your custom ModelLocator as Cairngorm forces this which basically couples your view directly to a specific model implementation. Instead a DI approach might be better.

Thankfully this application did not have to use the ServiceLocator as I was using in-process services (not web-services or remoting). Why was I thankful? Well when I looked at the ServiceLocator the whole thing made me cringe! The documentation on how to use it as well as the source, plus the fact you declare an wire it up in MXML…. It just seemed like a combination of bad naming and bad implementation. Secondly, unless you are using the hardwired web-service, http object or remoting versions in that class, the ServiceLocator in Cairngorm appears to be useless out of the box without customization. You just can’t easily plop in your own services bound by an arbitrary key. Why don’t they support custom abstractions of a “service” beyond the default “remote” three provided in Flex? Why does a “service” have to be remote in Cairngorm? Why should it care?

Overall… like I said my experience was fairly positive and would use it again for a similar project. That said, I do have some issues with the framework. I also fundamentally don’t understand why this framework is the “de-facto” standard promoted by Adobe and seemingly viewed as required knowlege for any “real Flex/AS3 developer”. Shouldn’t knowing the principles of MVC be more of a requirement than simply the nuts and bolts of a specific framework implementation?

Next stop… I am going to try out some other AS3/Flex MVC frameworks. I’ll report back on those.

Advertisements

Security Sandbox Violation during run and debug after moving or copying a Flex project in Flex Builder

Ugh, this is one of those classic examples of getting sidetracked in your daily work because of some annoyances with Flex Builder. Today I copied an existing Flex Builder project in Eclipse to another directory (new renamed project). I then edited the project settings (renamed the project) before importing the new copied project into Eclipse. This worked great and Eclipse immediately imported the new project and recognized it as a Flex project.

The problem came up when I tried to debug my app. When I hit debug I got the dreaded *** Security Sandbox Violation *** (Adobe’s equivalent of the blue screen of death) once my app attempted to make an UrlLoader request for a sibling resource to the SWF. Now, at this point I was frustrated as this was an exact cloned copy of the project that still worked under the original project name in Eclipse.

Turns out, that during a true “Create new Flex Builder Project” setup in Eclipse, Flex Builder adds your project’s bin-release and bin-debug directories to the local Flash Players global security settings as a trusted resource. This is necessary so you can debug/run your Flex projects in eclipse without getting the Security Sandbox Violations when accessing local resources.

Now how to fix this?

Simply go here: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html

and proceed to add your copied/new project’s bin-debug and bin-release dirs. Then next time you run, the security sandbox exceptions will go away, just as if you originally created the project in Flex Builder’s “wizards” of smart.

Book Review: Professional Cairngorm

This is a review of the book Professional Cairngorm by Jeremy Wischusen. When describing his motivations for writing this book the author tells a story about experience with Flex/AS3 development, but none of it using Cairngorm, then he had a job interview…. And in typical fashion, when he answered no to the “cairngorm experience” question, the interviewer basically said that if you have not used “Cairngorm” you don’t know anything about Flex/AS3. What a joke! This is a side rant, but I can relate to this guy as I have done about a year and a half of pretty serious AS3 development without Cairngorm, and after having read this book, I really don’t see why Cairngorm is such a major “must know” AS3/Flex MVC framework. The author does a good job covering the history of this framework, and all said and done, it sounds likes some flash developers originally threw the framework together then Adobe Consulting threw its official “stamp of approval” on it, and there you go. Everyone must learn Cairngorm…..

So that said, just take a look at Chapter 3, which describes the Cairngorm’s “ServiceLocator”. Wow, if that does not seem like an overly convoluted set of classes and interfaces just to lookup HTTP/WS/RMI services, then I am not sure what it is.

Moving on….. to the book. This is a decent book, and the author is correct that for a newcomer to Cairngorm, there is not a ton of very good documentation out there for those starting with this framework. The author does a fairly good job of presenting the framework and how it works in a simple straightforward approach. Roughly the first 1/2 of the book is dedicated to discussing the inner working of the major Cairngorm players, the last 1/2 of the book covers a detailed step by step case study (blog app) followed by good coverage of the communities Cairngorm complaints, expert tips and 3rd party extensions.

Complaints about this book: First off I felt like the author may have been rehashing a lot of the material that is already out there, given the many references to official docs and other resources that were cited. The second complaint is the horrible formatting of the code samples. The wrapping of code lines is awful and so is the spacing between methods etc. Very hard to read and they could have done a better job with that.

Overall: Do you need to learn Cairngorm in about a day? Get this book.

Skill levels/Audience: Targeted towards people with zero Cairngorm experience, but intermediate to advanced AS3/Flex experience. Backgrounds with other MVC frameworks is helpful in understanding the material. This book is NOT for people brand new to Flex/AS3.

FYI, last year I played around with PureMVC, and this year (2010) after reading this book, I am going to make an effort to do at least one or two projects using Cairngorm. Lets see how it goes and I will report back!

Upgrade to Spring AS 0.8 and others

The Spring Actionscript project is maturing and as they do, they keep teasing apart the entire project. So I am now upgrading from 0.7 to 0.8 and if you are to, here is what you can expect. (change log here)

a) If you were using the older AS3Reflect library, well now they moved that again over to as3commons.reflect. Also note that the ClassNotFoundError which used to be in AS3Reflect has now moved to as3commons.lang. The have been factoring out a lot of stuff, however Spring AS still is dependent on these new libraries so you must download those SWCs and link them in.

b) Looks like as3commons now has a logging package, ugh, yet another! I already have support for Spicelib logging as well as the default Flex logging framework built into my framework, so I guess I might need to take a look at the new as3commons logging to see if I will create an adapter for that.

c) If you are still referencing the older Prana Framework xml schemas in your xmlns declaration (in applicationContext.xml) you will need to update those to use the new schema location over at springactionscript.org. It should look like the below:

<pre><?xml version="1.0" encoding="utf-8"?>
    <objects xmlns="http://www.springactionscript.org/schema/objects"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springactionscript.org/schema/objects
                        http://www.springactionscript.org/schema/objects/spring-actionscript-objects-1.0.xsd">

d) as3commons.reflect now dumps traces of errors during the pre-instantiation phase for all singletons. This seems to occur for objects who’s constructor expects a non-null parameter, but the reflect code is passing NULL for all parameters. In my case, my app comes up A-OK and functions fine, however if you are running in debug mode you will see all this trace output from as3 reflect.

e) lastly, if you have any sort of a build script, in my case a Groovy GANT script, make sure to update those for the new library dependencies.

Those are the only items I really ran into when upgrading. All my FlexUnit tests passed A-OK so it looks like I am good to go. Good luck.

Also check out the Spring AS docs located here

It looks like since I last looked, they added quite a few new interested features:

a) They fixed the import issue finally, now you can import other XML files as well as import them if they are embedded in your app

b) You can define your app context “xml” within MXML directly inline your Flex app which may be of use

c) Yea! the  “” (blank) value in a value declaration is fixed.

Spring AS & Prana woes with blank prop or constructor args

UPDATE: The bug described here appears to be fixed as of 0.8

So I’ve been doing a fair amount of work with Spring Actionscript v0.7.1 (formally the Prana Framework). In AS3 you can define methods and/or constructors that take optional arguments. Optional arguments must always be defined after the required arguments and they are noted by the presence of a default value in the method/constructor signature as such:

package my {
   public class MyClass {

      //constructor
      public function MyClass(reqArg1:String, opArg1:Boolean=false, opArg2:String=null):void {
         // your constructor code for MyClass here;
      }

   }
}

When you are defining a bean in Spring AS you can define it’s constructor arguments as so:

<object id="myClassInst"       class="my.MyClass"       scope="prototype">                          <!-- required arg 1-->   <constructor-arg value="val4ReqArg1"/>   <!-- pass false for optional boolean arg 2 -->    <constructor-arg value="false"/>    <!-- intentionally pass BLANK to 3rd optional arg -->    <constructor-arg value=""/></object>

Well when running this  you will get an error like this for the 3rd argument:

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at org.springextensions.actionscript.ioc.factory.xml. parser.support.nodeparsers::KeyValueNodeParser/parse()
at org.springextensions.actionscript.ioc.factory.xml. parser.support::XMLObjectDefinitionsParser/parsePropertyValue()
at org.springextensions.actionscript.ioc.factory.xml. parser.support::XMLObjectDefinitionsParser/parseProperty()
at org.springextensions.actionscript.ioc.factory.xml. parser.support::XMLObjectDefinitionsParser/parseProperties()

This is a bug in Prana (see here http://jira.springframework.org/browse/SESPRINGACTIONSCRIPTAS-49), to get around this until it is fixed, you will need to pass some dummy value, that your constructor code will interpret as a BLANK, such as literally the string “BLANK”. Stupid? Yes, but until this is fixed in Spring AS this is the solution unfortunately!

Easy Multipart file uploads / POSTs using URLStream or AS3HttpClientLib

When working on a cross runtime Zinc/AIR method method of posting files to a remote server, I came across Mike Stead’s URLFileVariable and URLRequestBuilder classes which makes the process of uploading multiple files (or ByteArray’s of data) via an HTTP POST much easier. Click here get his code

The basic concept is this: assuming you have one or more ByteArray’s of file data and the filenames to go with them, you prepare one or more URLFileVariable’s. The URLFIleVariable’s are added to the URLVariables as follows:

// create the standard "URLVariables"
var vars:URLVariables = new URLVariables(); 
// lets set a ByteArray of JPG data with the filename "myFile.jpg" against the POST variable "file1"
vars.file1 = new URLFileVariable(myByteArray, "myFIle.jpg");

Now at this point, as in my case, I am passing these URLVariables to either an AIR implementation of an HTTP client (using URLStream) or a Zinc implementation (using AS3HttpClientLib). This was all described here in another post.

In my AIR implementation of an HTTP client abstraction I use an URLStream and the code that deals with the URLVariables works something like the following.


/* Standard URLStream code that interacts with URLVariables
which contain Mike Stead's URLFIleVariables and uses his URLRequestBuilder */

var stream:URLStream = new URLStream();

// [ REGISTER for your stream listeners here...

/* use Mike Stead's URLRequestBuilder to properly build the 
URLRequest and encode it to contain all the multi-part data and filenames in the "vars" created above */
var req:URLRequest = new URLRequestBuilder(vars).build();

// ensure a POST because URLRequestBuilder only specifies POST if the variables contains files.
req.method = URLRequestMethod.POST; 

// define some URL to post to
req.url = "http://my.something.com.xyz/url_to_post_to.xyz";

// fire off the POST
stream.load(req);

// as the load completes, your event handlers for the stream should take over

Now on the other hand, if you happen to be using AS3HttpClientLib (as described in one of my other posts) you will be coding the equivalent of the URLStream code above, however using AS3HttpClientLib as follows. Here we do not use the URLRequestBuilder but simply manually retrieve the appropriate information from Mike’s URLFileVariable instance.

....

// our AS3HttpClientLib HttpClient
var client:HttpClient = new HttpClient();

...
// [Remember to setup your "client" event hooks as described in the AS3HttpClientLib docs here]

// create a new POST request
var postReq:HttpRequest = new Post();

// lets create an Array to hold all the different "parts" of this multipart post
var parts:Array = new Array();

/* lets push the URLFileVariable we created earlier into the parts Array 
according to how AS3HttpClientLib expects it, as a Part object. Here
we are simply creating a new Part and populating it with the data
that we defined up above when we created the URLFileVariable */

parts.push(new Part("file1",vars.file1.data, "application/octet-stream", [{name:"filename",value:vars.file1.name}]));

// create a multipart that points to the "parts" Array
var mp:Multipart = new Multipart(parts);
postReq.setMultipart(mp);
					
// create a URI
var uri:URI = new URI("http://my.something.com.xyz/url_to_post_to.xyz");	

// fire off the request
client.request(uri,postReq);

Thanks again to Mike Stead’s UrlFileVariable and URLRequestBuilder classes for helping me make an generic HTTP multipart post process easier and I hope my post will give those reading some help along the way on implementing their own.

Strange IMPORT failure in Spring AS

So I’ve started to think about splitting up the main applicationContext.xml file in one of my projects. The current one is getting quite large. Spring AS has the ability to import bean/object definitions from another XML file of your choice such as the following example where my context defines one object “yObject” and then declares an import to bring in another XML file which contains further object definitions:

<objects....>
  <object id="yObject" class="my.package.YObject"/>
  <import file="subConf.xml"/>
</objects>

The contents of “subConf.xml” file look as follows:

<objects....>
<object id="zObject" class="my.package.ZObject"/>
</objects>

After booting up Spring AS, I can successfully retrieve “yObject” however “zObject” is null. I have also tried specifying the subConf.xml file explicitly via a full path to no avail. I’ve been following the docs to the tee and this simply has made no sense! So after hours of fiddling with this and going through debugging the source code for Prana directly I found that when the following header that is in the objects tag the e4x “xml.descendants(“import”)” call within XMLObjectFactory._addImportLocationsIfAny() yields zero results.

<objects xmlns="http://www.pranaframework.org/objects"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.pranaframework.org/objects
http://www.pranaframework.org/schema/objects/spring-actionscript-objects.xsd">

When I remove all the xmlns/schema info OUT of the tag. The xml.descendants(“import”) works fine. Huh? Seems like an e4x bug?

[UPDATE 1/24 this is now fixed in the Prana source in SVN]

Prana Framework is now under the Spring umbrella

Great news and I’ve been hoping for this for quite a while. Spring has taken the Prana Framework under its wing and added it as an official Spring extension called Spring Actionscript. Here is another post about this.

When I first got into developing in AS3/Flex this past summer I immediately began looking for some sort of “Spring like” bootstrap/DI container for AS3 apps. Well the playing field was pretty slim. The two main ones out there were SpiceFactory’s Parsley project and the Prana Framework. I tended to like Prana’s because at the time it was much closer to Spring and quite lightweight. I also compared the functionality and activity on the forums and it appeared that Prana was getting more traction. As I posted previously, due to the uncertainty of who would come out the winner in the AS3 IOC world I ended up putting in a light IOC container abstraction layer in my AS3 API as to not be bound too tightly to any one implementation… as my app was only calling variations of <code>getObject()</code> to fetch services etc.

So here we are several months later and with this news that Spring is officially making Prana it’s AS3 extension of Spring, I think we made the right decision. This is great news

Advanced HTTP operations in Flex outside of AIR

I am currently pretty deep into a Flex/AS3 RIA desktop app project whereby I have several advanced needs. Such as to download partial files to the desktop (byte-range requests), execute HEAD requests to get remote file sizes, execute multipart POSTs, talk to some REST apis, and finally be able to read any write HTTP headers….. outside of AIR? Good luck with URLStream, URLRequest, URLRequestMethod and URLRequestHeader

Due to security sandbox restrictions, unless your application is running within Adobe AIR you are restricted to simple GETs and POSTs. You are also NOT allowed to touch the following headers:

Accept-Charset, Accept-Encoding, Accept-Ranges, Age, Allow, Allowed, Authorization, Charge-To, Connect, Connection, Content-Length, Content-Location, Content-Range, Cookie, Date, Delete, ETag, Expect, Get, Head, Host, Keep-Alive, Last-Modified, Location, Max-Forwards, Options, Origin, Post, Proxy-Authenticate, Proxy-Authorization, Proxy-Connection, Public, Put, Range, Referer, Request-Range, Retry-After, Server, TE, Trace, Trailer, Transfer-Encoding, Upgrade, URI, User-Agent, Vary, Via, Warning, WWW-Authenticate, x-flash-version.

That’s basically all of the ones I needed to touch…..so what to do? In my case I was developing some file management functionality that runs in both Adobe AIR as well as MDM Zinc. Amongst other protocols such as FTP, I needed to be able to pull file updates over HTTP as well (+authentication, HEAD checks etc). So I had to create an generic IHttpClient interface abstraction which then allowed me to implement runtime specific clients. So for the AIR side of things I was good to go by using all of Adobe’s URL* classes right out of the box and they work great for the AirHttpClient implementation of my interface. However for my Zinc client I was still stuck, until I ran across a fantastic little HTTP library out there that provides a custom HTTP library built on top of the Flex socket stack.

The AS3 library that ended up being used in my ZincHttpClient was: as3httpclientlib. as3httpclientlib solved all of my problems when running outside of the AIR environment. With as3httpclientlib you can do all of the following and more:

* GET, HEAD, PUT, POST, DELETE
* multipart/form-data (PUT and POST)
* HTTPS support using AS3Crypto TLS
* Post with application/x-www-form-urlencoded
* Reading chunked (Transfer-Encoding)

If you have the need to access a bit more advanced HTTP functionality and need to do it outside of the AIR runtime. I HIGHLY recommend as3httpclientlib. I have put this library through the works doing byte range requests, HEAD requests, header manipulation and downloading and posting all sorts of file sizes, the library works great. My only note is that it is a tad slower than URLStream based HTTP downloads under Adobe AIR, regardless, this little HTTP library is worth it. Kudos to the AS3HttpClientLib team!

Local IO write performance in Zinc improved

Looks like the folks over at MDM have improved their local IO write support (windows only) with the release of v3.0.10 of MDM Zinc. This is probably due to Adobe AIR and people’s complaints about the lack of better support for writing ByteArray data to disk in Zinc. Note that this new feature is only available when you are running on a PC
(mac/linux still have to use the old HEX conversion method)

In a previous post I wrote about the slow performance of writing binary data in Zinc. However now it is definitely faster, however still not as fast as writing under Adobe AIR. Regardless, it looks like MDM has listened to their users and made a step to improve things and that is great.

Here is an example of how to write a ByteArray to disk now under 3.0.10. Note this is faster than the old HEX conversion method and is much faster and less code:

var data:ByteArray = // some byte array of your data
mdm.FileSystem.BinaryFile.setDataBA(data);
mdm.FileSystem.BinaryFile.writeDataBA("c:\some\path\to\file");

Kudos to the folks at MDM for adding this new feature.