Help with Introspection using ActionScript 3

Brian LeGros | April 12th, 2008 | programming  

Ok, I need help. I’ve been able to discover the coolness that is getQualifiedClassName() and getDefinitionByName() and describeType() when it comes to working with introspection/reflection in ActionScript 3. I am stuck however. I want to get a hold of all the class names available in the compiled Flash movie at runtime. I’m writing a library that will look for custom metadata on classes and associate functionality with the classes (or possibly objects) if they are annotated in a specific way. Right now, short of asking for a list of those classes from the developer, I don’t know of a way to build a bootstrap function/class that will introspection into the Flash movie and get me a list of them. I was thinking maybe if I could find a way to programmatically access the manifest file that would work, but again I can’t find a way to do that.

Does anyone know how to do this or am I doomed to introspecting on objects and programmer declared references rather than classes?

UPDATE: I found a feature request in the Flex 3 JIRA database. Basically it’s not in Flex yet, nor is it supported by the Flash movie, but 4 people have voted for the feature thus far. That being said, please vote for this feature so we can get one of the final pieces to reflection built into Flex. BTW - If anyone wants questions answered with regards to Flex, check out the flexcoders mailing list over on Yahoo. Everyone probably knows about it but I’m slow.

Made it through the April Adogo

Brian LeGros | April 3rd, 2008 | news  

Well, looks like I made it through the April Adogo meeting with both my presentations on BlazeDS. I put quite a bit of work into the presentations, so thanks to all of those who attended the presentation. We’ve updated the Meetings page with links to the recordings if anyone is interested. I have to apologize for the quality of the sound, however; I think I accidentally messed up the white noise calibration. In any case, thanks to the Adogo for having me as always.

Adogo April Meeting Tomorrow

Brian LeGros | March 31st, 2008 | news  

Well I’ve finally put the finishing touches on my Adogo presentation for tomorrow night on the “Mechanics of BlazeDS” and “Remoting and Messaging with BlazeDS”. I originally called the 2nd presentation “RPC and Messaging with BlazeDS”, but I didn’t have an opportunity to integrate SOAP/REST into the picture, so I’m renaming it. In any case, I was able to throw together a pretty cool little sample app that should allow for some audience participation (pending my laptop can spare the memory). Hopefully some of my former co-workers from CFI can make it out. Sebastian and I will be driving out right after work, so see you all there.

Also, there will be food this time around thanks to TekSystems, so worst case, come out, be fed, and ridicule my meager presentations.

:)

Presenting at the Adogo in April

Brian LeGros | March 18th, 2008 | news  

It’s been a while since I’ve presented at the Adogo, so I figure I owe the group a couple of presentations. Based on the feedback we’ve been getting from the mailing list, I’m going to take a little bit of a different approach to this month’s meeting. We’re going to do 2, 30 minute presentations, one focusing on the conceptual and one focusing on the practical. The topics this month will be “The Mechanics of BlazeDS” (conceptual) and “RPC and Messaging Using BlazeDS” (practical). For those of you who are interested in seeing how Java will integrate with Flex, I will be showing off how to integrate POJO’s for use with RPC.

Hopefully I can keep the presentations short and the content simple and interesting. If anyone decides to stop by, make sure to hold me to that goal during the meeting. Primers should be posted soon. See you on April 1st, same time and place as always.

Thanks to the Acadiana Adobe User Group

Brian LeGros | March 12th, 2008 | news  

Yesterday I stopped by the Acadiana Adobe User Group in Lafayette, LA for Ray’s presentation on Adobe AIR. He showed off a time allocation app using Flex and then HTML/JS. He was able to show us a few quirks with SqlLite’s DATETIME datatype that Adobe added as well as some gotcha’s with respect to using HTML/JS with Spry. It was cool to see another user group in action. The Acadiana group has been meeting on and off for many years and they all seem to get along very well. Thanks to everyone in attendance for warm welcome and best of luck with the group.

acts_as_conference 2008 : Rails on AIR

Brian LeGros | February 9th, 2008 | conferences  

Peter Armstrong, author of Flexible Rails, gave this presentation which focussed on how Flex and AIR can consume REST’ful resources. Peter unfortunately had a hard drive crash about an hour before his presentation so needless to say his presentation didn’t go as planned. Although he didn’t really have any slides (because they were all destroyed) he was able to borrow the laptop of a fellow conference go’er and show us some code examples.

The code examples were geared towards introducing MXML and Actionscript to Rails developers. I feel pretty comfortable with both, but it’s always good to see different approaches to coding in Flex, especially code using HTTPService since I spend more time using RemoteObjects. I would have liked to seen, if only mentioned, the topic of component development (visual and non-visual) and data binding, but I can understand why it was omitted since most Rails developers aren’t familiar with UI practices other than your standard web stack.

Towards the end of the presentation, Peter revealed Ruboss, a Flex framework built specifically for consuming REST’ful resources. Ruboss uses a controller to expose an Actionscript interface to translate CRUD operations to their REST’ful equivalents. He said he’s going to be releasing it over the next few weeks under his new company, so watch Ruboss.com for more details.

We’ve asked Peter to give a Connect presentation at an Adogo meeting later this year on Flex/AIR and Rails. The Orlando community can definitely benefit from Peter’s work with Flex/REST and we hope to pimp that to its fullest … j/k Peter, keep up the great work.

Looking for an easier way to use Java and Flex?

Brian LeGros | January 20th, 2008 | programming  

Marcel Overkijk has taken advantage of the recent open sourcing of Flex to provide a plug-in for the Grails framework to expose AMF endpoints from your Grails application. The AMF end points are created via a service class in Grails. Grails, being built on Groovy, can very easily utilize any Java code, requires little work to configure, and can bundle a WAR for you with a single command. The plug-in looks really promising as does its road map which looks like it will have tools comparable to some of the other remoting packages available for Flex. This plug-in is built for use with BlazeDS, Adobe’s recent open sourcing of a subset of its LiveCycle Data Services product. Although I haven’t tried it yet (and its not recommended for production use), this is a great option to dumping a bunch of JARs into a shared Flex context or trying to setup your own BlazeDS server. Why not let Grails (and this plug-in) do the work for you? Seems like a much easier deployment option, IMO.

I’m also excited to look at Marcel’s code to see if I can learn anything to help in the implementation of an idea I had a while back regarding a Java factory for Flex to create objects from JSR 223 compatible languages using Java’s new script invocation API.

Thanks for the hard work Marcel! I look forward to messing around with the plug-in.

January Adogo Meeting - Flex 3 Pre-release Tour with Ben Forta

Brian LeGros | January 5th, 2008 | news  

For those who aren’t following the Adogo blog, the January meeting promises to be a good one as we have been chosen by Adobe to be the only stop in Florida for the Flex 3 Pre-release Tour. For our leg of the tour we are extremely fortunate to have Ben Forta, Senior Technical Evangelist for Adobe, as our guest speaker. We’re going to be giving away tons of schwag as well as some pretty nice software licenses. We’re getting to use a conference room at Westgate Lakes thanks to the Porges and are going to have Pizza Hut cater most likely.

I’m really proud of all the work we’ve done at the Adogo (Adam, Max, and myself) and getting Orlando as a stop on this tour helping to affirm that. In the few months since last August, we have been able to create the beginnings necessary to revitalize the Adobe community in the Orlando area. We still have a lot of work to do to get the word out, but we’ve got a good foundation to build on.

Hope to see everyone at the next meeting (January 21st @ 7:00 PM at Westgate Lakes near the Smokehouse)!

Uses for non-visual Flex components

Brian LeGros | December 13th, 2007 | programming  

Recently, I've been interested in examining the features of non-visual components as it applies to Flex. I don't hear them talked about a lot (at least in the small part of the blog-o-sphere that I read), but I think there are some uses for these types of components that could really catch on in the community. I've tried to put together a sample application to show an example of some of the ideas I'm playing with in my head.

So the big place where I see non-visual components having a use is when attempting to bridge the stateless and stateful portions of a Flex application, mainly in the area of remote services. When I design a web service or remote object to be used by Flex, I typically build it in Java (or ColdFusion) and I design the service such that its methods operate in a stateless fashion. For example, when I call a method on my service, I don't expect previous calls to that method to influence the results of my current call; at least from the perspective of the caller. Additionally, I have the expectation that more information may be required when calling the method since the remote object receiving the call has no context in which to interpret the method call besides the method itself. Now I'm know an argument can be made about whether something truly is stateless or not, but that's not the goal of this post. Let's work with this ad hoc definition of stateless for now.

Flex provides us with a very simple, global means to get a hold of these services: RemoteObject, WebService, HttpService; there are other means by which to connect to remote services, but for now let's take the simple example of stateless RPC-based services. Typically in my Flex applications, I want to emulate a synchronous call from the application to the service (using something that implements IResponder or mapping the result/fault methods manually). Ideally I should have a class abstracting these calls to improve cohesion in the application; frameworks like to use command, delegate, or proxy classes, for example. During the emulation of this synchronous call I usually have my result/fault handler call out to a method on a class to change the state of an object (e.g. - setting values on the ModelLocator in Cairngorm), consequently firing propertyChanged events and/or custom events to update visual components via data binding.

All that being said, there are a couple of things with this approach that I want to address. First, I'm making the assumption that the class which abstracts the interactions with my service should also remain stateless. No where in the creation of the object am I changing its state so that the behaviors associated with the object may have a different context when executed. Second, I'm making the assumption that the behavior of this abstracting class must be separate from the data it uses. Propagating a change in an object's state via events is the back-bone of Flex data-binding. Not only that, but data binding is very simple to use and code, why shouldn't this simplicity be available in the ActionScript class abstracting the call to the remote service?

So that's enough conceptualizing for now, let's look at some example code. Please note the entire working example can be found at this location.

In this example, we have a very simple phone directory application. A SearchView exists which takes input from the user and announces a custom event (SearchEvent) passing that user input as its payload (i.e. - SearchCriteria). This event is handled by the Application class which in turn calls the find() method on an instance of SearchComponent. SearchComponent is a non-visual component which uses data-binding to propagate changes from the stateless world into my stateful Flex application. The code for SearchComoponent can be found below:

  1. package com.brianlegros.nvc_example.component
  2. {
  3.    import flash.xml.XMLDocument;
  4.    import mx.collections.XMLListCollection;
  5.    import mx.collections.ListCollectionView;
  6.    import mx.collections.IList;
  7.    import mx.collections.ArrayCollection;
  8.    import flash.net.URLRequest;
  9.    import flash.net.URLLoader;
  10.    
  11.    import com.brianlegros.nvc_example.vo.Employee;
  12.    import com.brianlegros.nvc_example.vo.SearchCriteria;
  13.    
  14.    public class SearchComponent
  15.    {
  16.       [Bindable]
  17.       public var locations : IList;
  18.      
  19.       [Bindable]
  20.       public var departments : IList;
  21.      
  22.       [Bindable]
  23.       public var employees : IList;
  24.      
  25.       private var data : XML;
  26.      
  27.       public function SearchComponent() : void
  28.       {
  29.          var request : URLRequest = new URLRequest("results.xml");
  30.          var loader : URLLoader = new URLLoader(request);
  31.          loader.addEventListener(Event.COMPLETE, function() : void
  32.             {
  33.                data = XML(loader.data);
  34.                
  35.                locations = findLocations();
  36.      
  37.                departments = findDepartments();
  38.             }
  39.          );
  40.          
  41.          this.employees = new ArrayCollection();
  42.       }
  43.  
  44.       private function findLocations() : ArrayCollection
  45.       {
  46.          var temp : ArrayCollection = new ArrayCollection();
  47.                  
  48.          for each(var item : XML in this.data.employee.location)
  49.          {
  50.             if(!temp.contains(item.toString()))
  51.             {
  52.                temp.addItem(item.toString());
  53.             }
  54.          }
  55.          
  56.          return temp;
  57.       }
  58.      
  59.       private function findDepartments() : ArrayCollection
  60.       {
  61.          var temp : ArrayCollection = new ArrayCollection();
  62.                  
  63.          for each(var item : XML in this.data.employee.department)
  64.          {
  65.             if(!temp.contains(item.toString()))
  66.             {
  67.                temp.addItem(item.toString());
  68.             }
  69.          }
  70.          
  71.          return temp;
  72.       }
  73.      
  74.            
  75.       public function find(criteria : SearchCriteria) : void
  76.       {       
  77.          var temp : ArrayCollection = new ArrayCollection();
  78.                  
  79.          for each(var item : XML in this.data.employee)
  80.          {
  81.             if(criteria.firstName.toUpperCase() == item.firstName.toString().toUpperCase()
  82.             || criteria.lastName.toUpperCase() == item.lastName.toString().toUpperCase()
  83.             || criteria.nickName.toUpperCase() == item.nickName.toString().toUpperCase()
  84.             || criteria.location == item.location
  85.             || criteria.department == item.department)
  86.             {
  87.                var employee : Employee = new Employee();
  88.                employee.firstName = item.firstName.toString();
  89.                employee.lastName = item.lastName.toString();
  90.                employee.nickName = item.nickName.toString();
  91.                employee.location = item.location.toString();
  92.                employee.department = item.department.toString();
  93.                employee.phone = item.phone.toString();
  94.                
  95.                temp.addItem(employee);
  96.             }
  97.          }
  98.          
  99.          this.employees = temp;
  100.       }
  101.    }
  102. }

There a few things to note about this component for the purpose of this example:

  • A method on a remote service/object is not actually being called, I'm using an XML document to simulate that process.
  • I am not actually emulating a synchronous call, I'm allowing the current thread to block on the method call. If I were to emulate the synchronous call, I would suggest using anonymous functions as the result and fault handlers for the remote service/object. The code in this example would be short and not warrant a named method mapping (this is done a lot in JavaScript when registering event handlers).
  • Yes, my coding style kinda sucks, get over it.

Now when the find() method is called it does not return anything, instead it updates the component's internal state via the employees property which then fires a propertyChanged event which is handled by ResultsView to populate a datagrid. Additionally, notice that when the object is constructed it makes a call to fetch location and department information to which controls in the SearchView are bound and updated when construction is complete. These values from these controls are used to filter the search performed by the user.

Going back to the conceptual, there are a few questions that come to mind:

  1. Aren't components supposed to be reusable? - From my POV, it feels like Flex has already done a great job of handling re-use through the RemoteObject, HttpService, and WebService classes. It seems that if re-usability is needed it would be at the service rather than the non-visual component. The non-visual component in my example is literally acting as a perspective for its service, or what potentially could be a group of services. Right now, however, I'm not sure if there are huge performance issues that may result from having multiple component perspectives for a single or series of services. I would assume for RemoteObject it may not be as big as a hit as it would be for a web service. Maybe this would be based on the remoting implementation you choose (i.e. - LCDS, BlazeDS, WebORB, Granite Data Services, etc).
  2. Aren't you just causing side-effects on objects? - In my opinion, it's not doing anything different than what Flex is doing with its visual components. In fact, what I think justifies this particular approach is the fact that you have the ability to notify anyone watching the object when its state has changed; I've always considered side effects as changes in state that I potentially didn't know about as the caller. The Flash movie instance is stateful; why not take advantage of this environment to add state to the classes abstracting our services? I'm building these non-visual components to satisfy the needs of my application, so I will know how they should behave and can to document that formally based on the constructs of the language. Now, if you ask me if this approach should be used for building an API-like interface to a set of remote services, then I would have to say no. The implementer of an API doesn't know how their code will be used in the context of an application, consequently keeping these components as stateless as possible is to the benefit of the API developer; context is limited to the execution of a method call. I think the Twitter API for Flash Developers is a great example of this.
  3. Where do I put all of these non-visual components? - This question I believe involves much more conversation about the implementation of these non-visual components. The example application is extremely simple and does not represent the issue of how to handle event propagation. In the example, all events are being propagated to the Application class and emulating a sort of global event system similar to those that I've seen in Flex frameworks with which I've worked. In fact, this is how easyMVC handles its event registration in the ControllerFactory; a ControllerEvent with a user provided type is registered on the Application and no matter where the event is dispatched, it's told to bubble to the Application to be handled by a mapped method in a custom Controller class. I have to admit that I like this approach much better than Cairngorm and PureMVC's approach of building their own global event system. I know both camps have their own reasoning for why they've done it, but I don't think that what Adobe has provided is worth re-writing. On the other hand, does the hierarchical nature of MXML bind visual component layout and construction too close such that without global event systems we can't be productive as Flex developers? On a side note, data binding in practice isn't always the answer to our problems; how a component can take advantage of these non-visual components and still interact with the components it needs to is a mystery to me. This may come back to the nature of MXML as well.
  4. Do I need a framework if I use this approach? - This is something I'm still trying to figure out. The biggest use of Flex frameworks I've found is a structured approach for making calls to remote services. I feel like frameworks have way too much boiler plate code and if this approach is practical, a good alternative may exist in place of adopting a framework. It seems to me like Flex frameworks have come from the mindset of the web world where stateless HTTP is king. We don't have to use the Front Page Controller pattern to build rich UI's; I think it's time to move on to different interpretations of the MVC pattern. I always find myself asking, did developers in the Java Swing world find themselves turning to a framework or were the constructs of Swing enough to be productive. If people were productive with Swing and it was a widget toolkit for AWT, why can't the same be true for Flex and Flash?

All this being said, this is just my latest idea. As you can tell, I still have a lot of unanswered questions. We are the process of implementing this approach on a much larger scale at work and hoping to solve the questions listed above. I'm always interested in feedback, so please rip this to shreds. I am far from experienced in this arena and am always open to what others have to say despite what some may think.

NOTE: For those who are interested, I began along this line of thinking based of the latest buzz-worthy topics in the programming community. It interested me as to how OSGI implemented their component architecture in Java w/o some language level support (e.g. - formal properties) and why it so popular. I was also intrigued by a proposal put together by Joe Noxel, from the Java Posse, regarding additions to Java for some of the language level elements already present in Flex. Additionally, SOA has come into debate by some of the more experienced professionals in software engineering and SCA (see Apache Tuscany as an example) has been identified as a potentially better alternative. So all this talk, combined with the little amount of component programming I've done with COM+ and .NET, made me wonder. If there is such a huge draw towards component-oriented design is there anything in Flex that we can do to take advantage of these practices? Does having formal properties and support for events as it presents itself in Flex aid developers with the tools necessary to utilize component-oriented design? Is one of those areas specifically the perspective of bridging the gap from the stateful component to the stateless service? Now I know a component has a much richer definition than I'm limiting it to, but this is just the point. To what extent can we, and should we, use components within Flex?

November Adogo Meeting Tonight

Brian LeGros | November 6th, 2007 | news  

Just a reminder, the November Adogo meeting is tonight at Devry in Milenna @ 7:00 PM as usual. We will have a presentation on on "Continuous Integration" by Ryan Miller as well as a presentation on "AIR, Flex, and Twitter" from Adam Fortuna. If you haven't already, join our Google Group so we can send you a Google Calendar invitation for our next meeting.

It promises to be great meeting, so I hope you can make it :)