Flexible Spring

As I mentioned in my prior post, I’ve been going through the great Flex in a Week from Adobe. I finally hit Day 3 and had a need to play with BlazeDS for the second lesson. Being a fan of the Spring Framework, I decided to use the recently released Spring Blaze DS Integration 1.0rc1 (Spring-Flex). This ended up turning in to a bigger beatdown than I expected, for several reasons.

I really wanted to use the Spring-Flex integration because I like the annotation-driven dependency injection option that Spring brings to the table. Unfortunately, I could not find a single comprehensive document or example showing how to setup a project from end-to-end using Flex and Spring-Flex. I started with my Spring template project, adding in the BlazeDS dependencies and configuration. I then stripped out the stuff I didn’t care about for this example. Then I went digging through the various reference guides and blog posts trying to figure out the correct configuration I needed on both the Java and Flex side.

After about three days of hair pulling, the pieces finally started to fall in to place. Once I understood the configuration, it became a breeze to configure services to be exposed by Spring-Flex and to call those services from Flex via a RemoteObject. I’ve linked the complete Java project and Flex project archive below:

Spring-Flex Project

Flexbuilder Project Archive

There is a README.txt file in the root of the Java project directory that walks through the setup. This project is configured to talk to a MySQL database using an iBatis DAO layer and includes the setup scripts, all run from Ant. The build file also makes use of Ivy to grab dependencies, thus reducing the number of jars I have to include.

The Flex project is configured to talk to the exposed employeeService on localhost, so you’ll need to change the configuration of the RemoteObject if you want to point to a different destination.

Here are some of my lessons learned that will hopefully help others:

#1: Life is easier if you keep BlazeDS’s services-config.xml file in the default location: WEB-INF/flex/services-config.xml. The version of this file that comes with the BlazeDS turnkey download has a small problem. It does not specify default channels, which is what FlexBuilder will use to figure out what is going on. Look at the version I have in the Java file and notice at the top:


You’ll want this in your services-config.xml file if you plan on specifying an application server in FlexBuilder.

#2: And on the subject of application servers, you actually don’t even need to specify the server technology. I built my solution as a standalone Flex project with a standalone Java project and had the two talking together without a problem.

The secret to making it work is in how you configure the RemoteObject in FlexBuilder. Here is the configuration for my RemoteObject:


Specifying the ChannelSet enables you to take control of where the RemoteObject is binding to instead of relying of FlexBuilder magic. Just change the URI to point to the correct location.

There is one little catch. You need to set the FlexBuilder build output directory to Tomcat’s webapps/flex directory (after you have deployed the war file), or you’ll get a security exception about breaking out of the sandbox. I’m guessing that the flex file is looking for the services-config.xml file to figure out what it is supposed to do, and if it is not in the correct directory relative to the SWF file, your application will barf. So deploy the flex.war file from the Java project first, then play with the flex half of it.

#3: Once you have the dependencies sorted out, configuring the Flex broker is literally a one-line configuration option. Check out web/WEB-INF/flexDispatch-servlet.xml in the Java project and notice this line:

That’s all you need. Really. This one line of config uses “sensible defaults” to initialize BlazeDS. It will read services-config.xml from the default location (see tip #1) and setup the endpoints for you based on the configuration.

#4: I’m a fan of annotation-driven configuration for Spring, and Spring-Flex does not disappoint. Here is the implementation of the EmployeeService class:

public class EmployeeServiceImpl implements EmployeeService {

    private EmployeeDao employeeDao;

    public List getEmployees() {
        return employeeDao.getEmployees();

    public Employee getEmployee(String id) {
        return employeeDao.getEmployee(id);

    public List getEmployeesByDepartment(String department) {
        return employeeDao.getEmployeesByDepartment(department);

    public void doCreate(Employee employee) {

    public void doUpdate(Employee employee) {

    public void doDelete(Employee employee) {
        employeeDao.deleteEmployee( employee.getId() );

The top @RemotingDestination tells Spring-Flex this is a service that is going to be exposed via BlazeDS. You can provide an optional parameter specifying which channels to use, if you have several configured. Then, each method you want to expose is annotated with the @RemotingInclude annotation. Methods that should not be exposed can be annotated with the @RemotingExclude annotation.

So if you’re following along with Flex in a Week, or have just been trying to get Spring-Flex up and talking to a Flex application, give the demo a try and look over the source code. This corresponds to the second video of Flex in a Week, Day 3. I wish I would have known some of these things starting out, so hopefully I can save other people some time.

2 thoughts on “Flexible Spring”

  1. You should definitely give GraniteDS a try – http://www.graniteds.org/
    It’s an open source (LGPL) alternative to LiveCycle DS so you get all the LCDS goodies for free and much more. It has Spring, Seam and Hibernate integration, Tide (a nice client-side entity cache and contextual framework for Flex) and also an ActionScript 3 class generator (including an Eclipse plugin). It’s reall great!

  2. Thanks, Marius. I’ve never heard of GraniteDS, but will take a look. I’m not a big fan of Seam and Hibernate, but Tide sounds interesting.


Leave a Reply

Your email address will not be published. Required fields are marked *