May 22 2009

Flex Authorize Tag

adam

It is a very rare event when I am asked to code an application which doesn’t have some security constraints. Most Java MVC frameworks provide some type of role based security for the UI out of the box. No such thing exists in Flex. I decided, after casting about for an existing solution, to write an authorize tag for myself. This component has the following properties which need to be set:

  1. roles – one or more roles (strings) which are to be evaluated against.
  2. userRoles – one or more roles(strings) which the user has
  3. components – one or more components which will be effected if evaluation of roles against userRoles fails.
  4. type – type of evaluation to be performed one of:
    • ‘hasAny’ – evaluates true if userRole exists in any of the roles
    • ‘hasAll,’ – evaluates to true only if userRoles contains all roles
    • ‘hasNone’ – evaluates to true if userRoles does not contain any of the roles.
  5. behaviour – the behviour to be applied to the specified components:
    • Disable – disables the components if evaluation fails
    • Vanish – causes the components visible property to be set to false if evaluation fails
    • Collapse – causes the components visible and includeInLayout properties to be set to false if evaluation fails

Here is the code, please feel free to copy it and use it. Any feedback would be appreciated:

package com.express.security {
import flash.events.Event;
import flash.events.EventDispatcher;
 
import mx.collections.ArrayCollection;
import mx.collections.ICollectionView;
import mx.collections.IList;
import mx.collections.ListCollectionView;
import mx.collections.XMLListCollection;
import mx.core.UIComponent;
import mx.events.CollectionEvent;
import mx.events.FlexEvent;
 
public class Authorize extends EventDispatcher{
 
   public static const HAS_ANY : String = "hasAny";
   public static const HAS_ALL : String = "hasAll";
   public static const HAS_NONE : String = "hasNone";
 
   public static const DISABLE : String = "disable";
   public static const VANISH : String = "vanish";
   public static const COLLAPSE : String = "collapse";
   private static const BEHAVIOUR_ENUM : String = DISABLE + "," + VANISH + "," + COLLAPSE;
 
   /**
    * Roles which will be evaluated against the type rules and user's roles.
    */
   private var _roles : ICollectionView;
 
   /**
    * Roles which the current user has. These will be evauated aginst the type rules and roles.
    */
   private var _userRoles : ICollectionView;
 
   /**
    * Components which will have behaviour applied to them based on the evaluation outcome.
    */
   private var _components : ICollectionView;
 
   /**
    * Specifies the type of evaluation which will be applied to the roles
    */
   [Inspectable(enumeration="hasAny,hasAll,hasNone")]
   public var type : String;
 
   /**
    * Specifies the type of evaluation which will be applied to the roles
    */
   [Inspectable(enumeration="disable,vanish,collapse")]
   public var behaviour : String;
 
   public function Authorize() {
      super();
      addEventListener(FlexEvent.CREATION_COMPLETE, handleCreationComplete);
   }
 
   private function handleCreationComplete(event : FlexEvent) : void {
      evaluate();
   }
 
   public function evaluate() : void {
      var result : Boolean = false;
      if (_roles != null && _userRoles != null && type != null) {
         if (type == HAS_ANY) {
            result = evaluateAny();
         }
         else if (type == HAS_ALL) {
            result = evaluateAll();
         }
         else if (type == HAS_NONE) {
            result = evaluateNone();
         }
      }
      applyResult(result);
   }
 
   protected function evaluateAny() : Boolean {
      for each(var userRole : String in _userRoles) {
         if (containsRole(_roles, userRole)) {
            return true;
         }
      }
      return false;
   }
 
   protected function evaluateAll() : Boolean {
      for each(var userRole : String in _userRoles) {
         if (!containsRole(_roles, userRole)) {
            return false;
         }
      }
      return true;
   }
 
   protected function evaluateNone() : Boolean {
      for each(var userRole : String in _userRoles) {
         if (containsRole(_roles, userRole)) {
            return false;
         }
      }
      return true;
   }
 
   protected function containsRole(roles : ICollectionView, role : String) : Boolean {
      for each(var userRole : String in roles) {
         if (role == userRole) {
            return true;
         }
      }
      return false;
   }
 
   protected function applyResult(result : Boolean) : void {
      for each(var comp : UIComponent in _components) {
         switch(behaviour) {
            case DISABLE :
               comp.enabled = result;
               break;
            case VANISH :
               comp.visible = result;
               break;
            case COLLAPSE :
               comp.visible = result;
               comp.includeInLayout = result;
         }
      }
   }
 
   public function get roles():Object {
      return _roles;
   }
 
   public function set roles(val:Object):void {
      _roles = convertToCollection(val);
      evaluate();
   }
 
   public function get userRoles():Object {
      return _userRoles;
   }
 
   public function set userRoles(val:Object):void {
      _userRoles = convertToCollection(val);
      _userRoles.addEventListener(CollectionEvent.COLLECTION_CHANGE, handleCollectionChange, false, 0, true);
      evaluate();
   }
 
   public function get components():Object {
      return _components;
   }
 
   public function set components(val:Object):void {
      _components = convertToCollection(val);
      _components.addEventListener(CollectionEvent.COLLECTION_CHANGE, handleCollectionChange, false, 0, true);
      evaluate();
   }
 
   private function handleCollectionChange(event : Event) : void {
      evaluate();
   }
 
   public function convertToCollection(value : Object) : ICollectionView {
      if (value is Array) {
         return new ArrayCollection(value as Array);
      }
      else if (value is ICollectionView) {
         return ICollectionView(value);
      }
      else if (value is IList) {
         return new ListCollectionView(IList(value));
      }
      else if (value is XMLList) {
         return new XMLListCollection(value as XMLList);
      }
      else {
         // convert it to an array containing this one item
         var tmp:Array = [value];
         return new ArrayCollection(tmp);
      }
   }
}
}

Feb 25 2009

Integrating Spring Security with BlazeDS and Flex RIAs

adam

I have found a couple of tutorials on this lying around the web, however they all take slightly different approaches, and although the information was useful, I think there is a cleaner way to do the integration. Keeping in mind of course that now that the spring guys have released the spring-flex module there will hopefully be complete integration with Spring Security soon without the need to even wire it up the way I describe here.

What I am going to describe here uses:

  • Spring 2.5.5
  • Spring-Security 2.0.4 (core & tiger)
  • BlazeDS 3.2
  • Flex3

My approach is not to protect end-points using BlazeDs’s security. The reason is that I often expose my services as web services as well as AMF endpoints and I don’t want to create my security mappings twice. Instead I use method invocation based security and protect the services directly. All that BlazeDS needs to do is get the users credentials out of the request and delegate to SpingSecurity to create a SecureContext, authenticate and put the authentication object in the SecureContext (effectively thread local). After that normal Spring Security applies and secure methods will be protected in the normal way.

A typical security scenario in one of my applications goes something like this: Either none of the application or a small part of the application is available anonymously as is the login service. Users access them without credentials, usually the User doesn’t even have menu options to navigate to UI areas with secure functions until they have logged in. After a successful login I will cache the user’s credentials on the client and re-log them in on each service request. This keeps the server completely stateless, all state is stored on the client. I configure a lightweight cache on the server since if someone logs in once they will likely make many more login requests (one for every service they are going to use). This reduces database hits. I implement a service registry on the client which stores the credentials and automatically adds them to all RemoteObjects and HttpServices.

I’m going to work this assuming that you already have a Flex/BlazeDS/Spring application going. It can be as simple as hello world, there is an excellent article on how to do this using the new spring-flex solution here . The way that i am applying security means that it is largely irrelevent whether you are using the Adobe SpringFactory or the spring-flex MessageBrokerHandlerAdapter.

Step1. Add spring-security to your web application’s lib my pom entry looks like this:

<dependency>

   <groupId>org.springframework.security</groupId>

   <artifactId>spring-security-core</artifactId>

   <version>2.0.4</version>

   </dependency>

<dependency>

<groupId>org.springframework.security</groupId>

<artifactId>spring-security-core-tiger</artifactId>

<version>2.0.4</version>

</dependency>

   </dependencies>

Step2. Add the spring security filter to your web.xml

<filter>

<filter-name>springSecurityFilterChain</filter-name>

<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

</filter>

<filter-mapping>

<filter-name>springSecurityFilterChain</filter-name>

<url-pattern>/data/messagebroker/*</url-pattern>

</filter-mapping>

This will secure everything and is mostly necessary if you are going to use other transports than just AMF via BlazeDS.
Step3. Configure Spring Security. I am just going to put a very basic config here. For details on configuring spring security you can look at the spring security documentation here

<security:http auto-config=“true”>

<security:intercept-url pattern=“/**” filters=“none”/>

</security:http>

<security:global-method-security>

<security:protect-pointcut

expression=“execution(* net.oneadam.app.services.*Manager.*(..))”

access=“ROLE_ADMIN”/>

</security:global-method-security>

<authentication-provider>

   <user-service>

<user name=”adam” password=”adamspassword” authorities=”ROLE_USER, ROLE_ADMIN” />

   <user name=”bob” password=”bobspassword” authorities=”ROLE_USER” />

   </user-service>

  </authentication-provider>

This configuration passes everything through at the URL level and relies on method level security. I have used pointcuts here since it doesn’t require me to cut and paste classes and methods in order to demonstrate how annotations work. The above pointcut requires the user for all methods in any class ending in the word Manager in the services package to have the role ROLE_ADMIN.
Step4. Implement the flex.messaging.security.LoginCommand Interface so that the doAuthentication creates a UsernamePasswordAuthenticationToken and authenticates using Spring Security, if it is successful it should put the authentication object into the SecureContext where it will be accessible to your application and the Spring Security annotations or security pointcuts. here is my implementation:

package net.oneadam.web.security;

import java.security.Principal;

import java.util.List;

import java.util.Map;

import javax.servlet.ServletConfig;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.springframework.context.ApplicationContext;

import org.springframework.security.AbstractAuthenticationManager;

import org.springframework.security.Authentication;

import org.springframework.security.context.SecurityContextHolder;

import org.springframework.security.providers.AbstractAuthenticationToken;

import org.springframework.security.providers.UsernamePasswordAuthenticationToken;

import org.springframework.web.context.support.WebApplicationContextUtils;

import flex.messaging.FlexContext;

import flex.messaging.io.MessageIOConstants;

import flex.messaging.security.LoginCommand;

public class SpringSecurityLoginCommand implements LoginCommand {

   private static final Log LOG = LogFactory.getLog(SpringSecurityLoginCommand.class);

   private AbstractAuthenticationManager authenticationManager;

   public Principal doAuthentication(String username, Object credentials) {

String password = extractPassword(credentials);

if (password == null) {

   return null;

}

  

if(authenticationManager == null) {

   init();

}

Authentication auth = new UsernamePasswordAuthenticationToken(username, password);

try {

   SecurityContextHolder.getContext().setAuthentication(authenticationManager.authenticate(auth));

   LOG.info(“User [" + username + "] logged in.”);

   return (AbstractAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();

}

catch (RuntimeException e) {

   LOG.info(“User [" + username + "] failed authentication.”);

   throw e;

}

   }

   /**

* We are not going to perform Authorization at this level since we would like SpringSecurity

* to manage Authorization at the method level.

*/

   @SuppressWarnings(“unchecked”)

   public boolean doAuthorization(Principal principal, List roles) {

return true;

   }

   public boolean logout(Principal principal) {

HttpServletRequest request = FlexContext.getHttpRequest();

if (request != null && request.getSession(false) != null) {

   try {

request.getSession().invalidate();

   }

   catch (IllegalStateException e) {

// Expected.

   }

}

request.getSession(true); // Session re-created to avoid Flex error when

// it also attempts to invalidate the session.

LOG.info(“User [" + principal.getName() + "] logged out.”);

return true;

   }

   public void start(ServletConfig config) {

//My tests show this never gets called

   }

   public void stop() {

authenticationManager = null;

   }

   @SuppressWarnings(“unchecked”)

   protected String extractPassword(Object credentials)

   {

   String password = null;

   if (credentials instanceof String)

   {

   password = (String)credentials;

   }

   else if (credentials instanceof Map)

   {

   password = (String)((Map)credentials).get(MessageIOConstants.SECURITY_CREDENTIALS);

   }

   return password;

   }

   private void init() {

HttpServletRequest request = FlexContext.getHttpRequest();

ApplicationContext ctx =

   WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());

authenticationManager = (AbstractAuthenticationManager) ctx.getBean(“_authenticationManager”);

   }

}

You will notice that the doAuthentication method just returns true. That is because I am not interested in securing BlazeDS destinations. I prefer to secure the service facade methods themselves, that way if I expose them using CXF or some other Web Service transport my security does not have to be redone.
Step5. Wire up security in the services-config.xml file to use your SpringSecurityLoginCommand it will look something like this:

<security>

<login-command class=“com.renewtek.cmf.web.security.SpringSecurityLoginCommand” server=“Tomcat”>

   <per-client-authentication>true</per-client-authentication>

</login-command>

<security-constraint id=“roleuser”>

   <auth-method>Custom</auth-method>

   <roles>

<role>ROLE_USER</role>

<role>ROLE_ADMIN</role>

   </roles>

</security-constraint>

   </security>

The roles are actually unnecessary since I return true from all authorization requests at this level. I have just left them in for completeness. If you wanted to reject a request at this level that is where you would put the roles and if you are using the Adobe style of defining destinations in your remoting-config.xml file then you could say what destinations are allowed for what roles. What is important to the strategy I described above is the per-client-authentication entry. it needs to be set to true since we don’t want to use server based sessions. it is false by default.


Jan 9 2009

Optimistic Locking with JPA, Flex & BlazeDS

adam

Optimistic locking in JPA relies on a version field which can be a number or a date of some type. Using date objects can be problematic if they are not detailed enough. For example a date which does not persist at least milliseconds is likely not to be accurate enough to do versioning. I generally use a Long since it is going to survive a very long time indeed, even in a high transaction system. The version filed is identified using the @Version annotation and when an object containing a version field is updated JPA will read up the version number in the database before attempting to do the update and if the version numbers do not match then it will throw an OptimisticLockException. It is a good practice to make the version field private and not to provide getters and setters. it is critical that the field not be altered except by the JPA implementation.

Ok, so far so good, we implement this strategy on systems where we have a greater proportion of reads to writes and we would like data to be highly available. Basically a user can always get a read, no matter what, however if they want to do a write we will check that the object they are modifying has not been written to since they read it. Very many web based application use this strategy today and as I described above it is supported out of the box with JPA. Of course there are endless arguments about how you manage the OptimisticLockException, but that is a separate issue.

When your web application is using DTOs or some other representation of the system data which is not your actual domain another level of complexity enters the frame. If the DTOs don’t carry the version field with them and re-present it for the update then the whole optimistic lock strategy is dead in the water. If the web tier represents an object without keeping the version field then when it the user requests to update the domain, JPA must retrieve it again, over-write the fields provided and then perform the update. Of course if someone had changed the data between the user’s read and write, that would be over-written.

So we have established that maintaining the version field into the web tier is critical. We already established that the version field should not be user modifiable so it would be good to make the version field in the DTOs private as well. If you are hand mapping between DTOs and your domain then you will need to use reflection to map this field across. I generally user dozer and it allows you to set is-accessible=”true” in a field description which tells it to access this field directly without using the getter and setter.

When you add Flex and BlazeDS to the picture (and of course that means an ActionScript domain) you add a whole new level of complexity and at this point a real problem arises. Of course BlazeDS will auto-magically transform your Java DTOs into your ActionScript domain and perform all transport in AMF3. Thats peachy, but unfortunately it does not transport private fields without getters or setters. That means that although your version field gets mapped onto the DTO when it arrives on the Flex client, it is gone.

Well that just won’t do, we already established that without the version field we have no locking strategy at all. Currently my only work around is to provide getters and setters on the DTOs. This ensures that they make the trip to the client and back but it risks the client accidentally altering them and inadvertently causing an OptimisticLockException. I’m a little unhappy with this and intend to spend a little bit of time with the BlazeDS source code to see if there is something that can be done to allow private field mapping. If you are interested stay tuned or feel free to post your ideas as comments here.


Oct 22 2008

Flex MVC

adam

When you look around at all the postings with Flex code examples and advice, it seems clear that the Flex community is largely made up of graphic artists and refugees from the last popular drag and drop programming framework (probably .NET). There are definitely some people out there coding high quality Flex applications but if the code snippets on the web are anything to go by then they are in a tiny minority.

I come from a structured programming background and have been writing Java/J2EE applications almost exclusively for the past 5 or 6 years, I love user interface programming and have done a lot of work on web based UIs, mostly with Javascript, Ajax and HTML. When I first saw the Flex 3 beta and heard that Adobe was going to open source Flex I was blown away, I immediately downloaded the beta Flex Builder 3 and jumped in.

Of course I started Googling for solutions to the problems I was having and pretty soon I realized that most of the code examples, although functional, were a pile of pants. It seems like most of the flex community has never heard of separation of concerns. People just seem to open up a script block and go for it right there in the middle of a presentation page, sometimes they don’t even bother to do that, they just inline it inside the event they are interested in. I must admit that I initially thought this was some kind of joke. A club of deviant bloggers trying to see how successful they could be in encouraging newbies to write rubbish code.

Strangely the problem when you are coding Flex is exactly the opposite to when you are coding Java web applications. In Java structure is easy to find and you want an MVC framework which will make things quicker. In Flex writing applications is quite quick but you desperately need some structure since you know that a couple of months down the track you are going to be supporting your application or building new modules for it and you can quickly see that what you are writing is a no holds barred mess.

When you google for Flex best practice you get very little and what there is is mostly very general and stolen from the last Agile, TDD slide set the presenter watched… There are exceptions and there are some people out there doing really nice code. Some guys at Adobe had a misguided attempt to develop an MVC framework, presumably with the intention of trying to correct the horror code that was beginning to be associated with the Flex brand. Cairngorm was born. Cairngorm is basically a Singleton-fest who’s only redeeming feature, IMHO, is the ServiceLocator class.

Nobody was thinking too deeply the day Cairngorm was born. They have few ideas and no structural assistance for separating plumbing code from the view. Most likely coders who go to the trouble of implementing a Cairngorm application will at least try to work out some type of mediator or code behind implementation of their own since core separation of view and controllers has to constantly be wired in manually in Cairngorm. Of course using Cairngorm is considerably better than using no structure at all, but all in all it is pretty lame.

After some time spent suffering and becoming seriously tempted to write my own MVC framework I came across PureMVC. The guys at PureMVC have a very nice ActionScript 3 implementation of their MVC framework which finally provides some proper structure for separating concerns. They provide a Mediator base class for extending to do your plumbing code. PureMVC also uses a more registry based approach rather than just encouraging you to conjure up singletons whenever you get to lazy too sort out your code properly. It is by no means a perfect framework, I do find myself using quite a bit of boiler plate code but with care, this can largely be factored out into factories or utility classes.

There definitely needs to be more work in the Flex community on application structure and separation of concerns. There is still a lot of work to do in developing a best practice for binding form fields. The Flex Binding framework seems to verge on Voodoo and behaves very unpredictably for anyone who is not aware of what is really going on under the covers. i don’t think that a really good MVC framework has been written for Flex but at least there are some options starting to spring up.


Oct 22 2008

Flex MenuBar – allowing top level elements to be selected

adam

Out of the box the MenuBar control kind of insists that you have children for every top level menu item in order to navigate. If you don’t have any children for a MenuBarItem you don’t get an ITEM_CLICK event when it is clicked. Fixing this is pretty simple but can be a little annoying since you need to listen for MouseEvent.CLICK as well as MenuEvent.ITEM_CLICK.

Putting another listener on the menu bar is pretty simple but you need to look out for the user clicking on the menu bar but not on a menu item. My click listener looks simething like this:

public function handleMenuClick(event : MouseEvent) : void {

if(event.target is MenuBarItem) {

var menuItem : MenuItem = event.target.data as MenuItem;

if(menuItem.children == null) {

app.views.selectedIndex = menuItem.navIndex;

}

}

}

In the above example i am using a very basic custom MenuItem for the data structure of my menu. It just contains the Label, Icon and a navigation index which I apply to my ViewSstacks (in the above case the ViewStack is ‘app.views’) as the selectedIndex the class looks like this:

public class MenuItem {

public var label : String;

public var icon : String;

public var navIndex: int;

public var children : Array;

public function MenuItem(label : String, navIndex : int, icon : String) {

this.label = label;

this.icon = icon;

this.navIndex = navIndex;

}

}

If the children Array is null, I know that it is a navigation target.


Oct 14 2008

Flex Form Fields Submit on Enter

adam

It’s just a small thing but it can be quite annoying when you have to use the mouse in order to submit a form, particularly something like a login form where you just want to quickly type in your details and get into the application. HTML web forms have this behaviour by default, however in Flex you have to ask for it. i have not yet found a way to do it for the whole form but you simply add a listener to the FlexEvent.ENTER event for each field on the form.

It will look something like this:

<form field>.addEventListener(FlexEvent.ENTER, doLogin);

Where doLogin, obviously, is your login function and <form field> is a field on your form.


Mar 17 2008

Testing Flex

adam

Flex applications are reasonably easy to write, and they certainly build themselves a lot faster than standard web applications which need a rich user interface. Testing them is a bit of a problem though. I looked as ASUnit initially, but the whole framework was so Windows-centric that I gave up in disgust. I could tell after a very short time that even if I got it working on my Mac there would be no way to run it in an automated build loop.

After that I started playing with FlexUnit. This framework is much more generic and quite simple to use. The most confusing thing about it is that there seems to be a FlexUnit project on Sourceforge as well as Google code and they don’t appear to have anything to do with each other. I couldn’t make head ‘nor tail of the Sourceforge one but the version on Google code, which appears to have some Adobe support behind it was simple to install and use and this article gives quite detailed instructions about how to use it.

Testing in Flex is still not always that easy, even when you have a reasonably easy to use framework like FlexUnit. You still have to write code which can be unit tested. This is the real value of rigorously testing your code. You have to write your code in such a way as it can be tested. When you do this your code becomes more loosely coupled and more highly decomposed. This leads to not only more testable code, but to more re-usable code…”Vive le testing”

Once you have tests you need a constant integration loop to run your tests and keep you honest. Initially we didn’t think this would be possible, turns out we were wrong. Antennae is an open source project on Google code which addresses exactly this problem. A detailed explanation of how to install and use it can be found in the Flex Cookbook. There is a fair bit of mucking around involved, but with a bit of determination you can reasonably easily get your Flex codebase to build and execute it’s FlexUnit tests in a constant integration loop.


Mar 8 2008

Multiline Labels

adam

Doh, blew quite a bit of time on this thinking that there must be some way to make a Label multiline… there isn’t! Have to use a Text control. Note to self: Google first, think and experiment later.


Feb 16 2008

Flex BlazeDS Spring an Integration Story

adam

At the Melbourne Spring User Group (MSUG) meeting in Feb I presented on integrating an Adobe Flex Rich Internet Application with a J2EE services tier using Spring as the integration glue and BlazeDS for lightweight binary data transfer using ActionScript message Format (AMF). I have made the slides from that presentation available here.

Many people seem to think that their has to be some hard decision made about whether to go with the sexy flash based user interface of a Flex application, or the robust, scalable dependability delivered by a Java based application. I say “Why not have the best of both worlds?”. The approach I outline is completely Open Source and free and it is trivially easy to configure BlazeDS to use the Spring bean factory to expose a standard Spring service facade to remoting calls by a Flex application.

Documentation for BlazeDS can be found here. An explanation of the Adobe example Spring factory can be found here. it contains the source code as well. You will need to copy it and paste it into your project source tree.

I hope this is useful to people.


Jan 20 2008

Flex as a J2EE MVC Tier

adam

I began my web programming life using Perl and PHP and I don’t like the idea of becoming a language snob, however, I have to admit I have been somewhat of a Java purist over the past couple of years in particular and I saw no reason to make an exception for the presentation tier.

I was thinking the other day about that saying: ‘When your only tool is a hammer, everything looks like a nail‘. This came up when I was looking at working AJAX functionality into a Spring MVC web application. I had already worked JQuery into the UI for effects and to speed up querying the DOM. I had an custom tag library called SpringLayout, which I was using to integrate error messages and speed up validation responses. I had Yahoo! tabs going for client side tabs, and I started thinking about how difficult this application would be to maintain, particularly if that person wasn’t me.

What I was really after was a Rich Internet Application (RIA). Because Java is my hammer, the RIA looked like a nail. But I started wondering whether there might be an easier way to achieve the rich user experience without sacrificing the well tested and proven Java application… along came Flex 3. Flex uses a component based approach based on ActionScript. I’m not going to go into the details of the Flex application framework, except to say that writing RIAs is extremely simple and intuitive using Flex and flex builder.

One of the interesting side effects of moving to a non-Java presentation tier technology is that you quickly become aware of areas where you have allowed application logic to bleed into the presentation tier. Without some type of artificial barrier, such as having to translate objects into ActionScript, it is quite possible for POJO based applications to leak some of their business logic out into the MVC layer. Kept to a minimum this is not the end of the world, however I prefer to have a complete separation, particularly since we often have to expose business services to automated clients.

BlazeDS has been an interesting tool in coming to terms with Flex as the client for my java based applications. It is an open source offering from adobe, allowing Flex clients to make RPC calls or access JMS queues and topics and has recently been released as a Beta. It performs the translation to ActionScript Message Format (AMF) transparently, greatly easing the effort in developing a transport and translation service for your Flex client. It is essentially a cut down version of the Adobe LiveCycle Server.

I will be blogging in more detail on the technical issues I have come across in coding in Flex and using Flex Builder as well as plugging in BlazeDS.