Flex, Spring, iBATIS, Cairngorm: Bringing It All Together

Over the past years I have been implementing Flex projects in many different settings. They range from business intelligence applications running against large data warehouses to simple tools that perform a very custom business function. From the beginning, using Flex 1.5 to now with Flex 2.0, I have experienced quite a few challenges and what I consider best practices when developing Flex Rich Internet Applications.  

I believe in creating a consistent, modular, and repeatable architecture. The architecture must be sufficient to support small applications as well as extremely robust enterpirse applications. A key to project success is to create an architecture that new developers can rapidly integrate themselves into and begin to be productive on day one. I feel that Flex combined with Spring, iBATIS, and Cairngorm help me reach these goals of a patterened based, repeatable architecture.

I have put together a sample application that I hope will communicate a series of Flex best practices. This Contact application implements one set of standard CRUD constructs. You should be able to understand how to architect an enterprise application down to a simple tool with this example. One thing I find very helpful about Cairngorm is how it organizes itself in the project space. You can break out modules to separate work for your team. It works in large and small shops.

I would also like to acknowledge the work done by Cairngorm Docs, Christophe Coenraets, and Adobe Labs. I have learned a great deal regarding the technology in this post from those sources as well as many other RIA blogs.

 Experience the application:

Cairngorm Example Application

Flex Makeup:

Flex provides a solid framework for building highly interactive Rich Internet Applications. Flex is made up of the following programming aspects:

  • ActionScript 3.0:  ActionScript 3.0 is a powerful, object-oriented programming language that is ideally suited for rapidly building RIAs. AS3 facilitates rapid development for large applications, handling large data sets, and is object oriented. Java developers will find an easy transition to Flex Actionscript development. AS3 is an ECMAScript compliant language.
  • MXML:  MXML is the XML-based language that developers use to lay out components in Flex applications. It provides a declarative approach to controlling an application’s visual appearance.
  • Flash 9: Flex is compiled into Flash .swf. This .swf is executed on the client by the Flash Virtual Machine. This allows applications built in Flex to be executed on virtually any platform that supports Flash 9. That includes PCs, hand-held devices, POS Terminals, PDAs, etc…

For more information regarding Flex you can find it at http://www.adobe.com/products/flex. The Flex API documentation can be found here.

Spring Makeup:  

Spring is a popular Java framework that provides a central automated configuration for writing your application objects. Springs lightweight container is capable of assembling loosely-coupled components which is the basis for reuse.

The DAO implementation support allows Spring to easily integrate with persistence frameworks like Toplink, Hibernate, JDO, and iBATIS. One key beneift of using Spring is if you ever need to change your persistence framework you can do so by decoupling your existing framework and plugging in a new persistence framework. You will retain the majority of your code base.

You can find more information about Spring at http://www.springframework.org.

iBATIS Makeup:

iBATIS is a data mapping framework that couples objects with stored procedures or SQL statements using an XML structure. iBATIS allows simple integration to your database of choice.

I like iBATIS for the flexibilty of the SQL entered in the SQLMaps. Many of the Flex applications I have written reside on top of a data warehouse. I need to create complex SQL that runs effeciently on databases like Netezza, Oracle, Teradata, and Informix.

More information about iBATIS can be found at http://ibatis.apache.org.

Cairngorm Makeup:

Cairngorm is an architectural framework that offers a starting point for RIA development. It directs consistency, realiabiliy, and modularity in Rich Internet Development for the User Interface by implementing reliable design patterns.

Using Cairngorm allows you to break up project work across large teams. Flex aids in this by allowing you to easily produce an application wrapper to build modules in Flex tied together by Cairngorm.

The Cairngorm architecture is built to allow you to handle user gestures on the client, manage client state, and encapsulate business logic in the client.

In this article we will discuss how Cairngorm implenets Command, Delegate, and Service Locator patterns to interact with a Spring/iBATIS service model.

The Cairgorm programming model is made of:

  • Value Object:  The Cairngorm Value Object acts as a marker interface to help improve readability of code. The VO is nothing more than a mapping to your service bean. This VO is used to help transform incoming object lists to map to flex view objects like a datagrid.
  • Event: The event describes the type of object that will be processed when the event is fired. The event sets an event type to be listened to by the controller. The Cairngorm Event class is required for event processing.
  • Front Controller: This class controls user actions by binding the event to a specific command. That marrage of these two components allows Flex to detect user gestures and return data to the model.
  • Command: The command class enforces the binding of the Event between the Front Controller. The command is responsible for initiating external calls through the Business Delegate.
  • Business Delegate: The Business Delegate implements the Responder inteface that handles data returned as the result of a service call. I try to match my Business Delegate to my server side service method implementation. A delegate can call other services as needed, but that can cause code maintainability issues for the application.
  • Service Locator: The Business Delegate locates the application level service and passes references of the Commands Result and Fault handlers.
  • Model Locator: The Model Lcoator is used to instanciate the applications model and/or models. The locator grants access to data objects that the Command will apply results too for the View layer to assign to components like a datagrid.

Flex-Cairngorm Architecture        Spring-iBATIS Architecture

Flex-Cairngorm Architecture                       Spring-iBATIS Architecture

Application Configuration for Flex, Spring, Cairngorm, and iBATIS
Step 1: Get the project files
  1. Download cairngorm-spring-iBATIS.zip here. ***This zip file contains all of the files required to run this example project. You do not need to download items 3 through 6 below unless you want to check out the open-source projects themselves.
  2. Expand cairngorm-spring-iBATIS.zip to a Tomcat /webapps location or other j2ee web server.
  3. Download the Spring framework at Spring framework (version 2.0) at http://www.springframework.org/download
  4. Download Cairngorm 2 for Flex at http://labs.adobe.com/wiki/index.php/Cairngorm
  5. Download iBATIS at http://ibatis.apache.org
  6. Download MySQL at http://dev.mysql.com/downloads
Step 2: Setting up Cairngorm

To deploy with Cairngorm you need to simply unpack the Cairngorm.swc and relocate it to:

{context-root}\WEB-INF\flex\user_classes

Step 3: Setting up Spring
  1. Copy spring.jar to {context-root}\WEB-INF\lib directory of your web application
  2. Modify the web.xml file of your web application. Add the context-param and listener definitions as follows:  
    <context-param>     
         <param-name>contextConfigLocation</param-name>
         <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>                        
    
    <!-- Spring Session attribute and binding listener support -->
    <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
  3. Copy SpringFactory.class and SpringFactory$SpringFactoryInstance.class from your compiled source location to {context-root}WEB-INFclassescomappfoundationcommonfactories. This code developed by Jeff Vroom
  4. Register the Spring factory in {context-root}\WEB-INF\flex\services-config.xml:
    <factories>  
         <factory id="spring" class="com.appfoundation.common.factories.SpringFactory"/>
    </factories>
    
Step 4: Setting up iBATIS
  1. Locate ibatis-common-2.jar, ibatis-dao-2.jar, and ibatis-sqlmap2.jar
  2. Copy those jar files to:  {context-root}WEB-INFlib
  3. Modify your sql-map-config.xml in: {context-root}WEB-INF
    <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
    "http://ibatis.apache.org/dtd/sql-map-config-2.dtd“>                          
    
    <sqlMapConfig>
          <sqlMap resource=”../sqlmaps/Contact.xml” />
    </sqlMapConfig>
    
Step 5: Register the Spring Beans
  1. Locate your applicationContext.xml in {context-root}\WEB-INF
  2. Modify the applicationContext file to include your Spring beans as follows:
    <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE beans
            PUBLIC "-//SPRING//DTD BEAN//EN"
            "http://www.springframework.org/dtd/spring-beans.dtd“>
    <beans>
         <!– START Load application properties –>
         <bean id=”propertyConfigurer”
           class=”org.springframework.beans.factory.config.PropertyPlaceholderConfigurer”>
           <property name=”location”><value>classpath:../application.properties</value></property>
         </bean>
        <!– END Load application properties –>                          
    
     <!–  START DB connection info –>
      <bean id=”dataSource” class=”org.apache.commons.dbcp.BasicDataSource”
             destroy-method=”close”>
           <property
             name=”driverClassName”><value>${jdbc.driverClassName}</value></property>
           <property name=”url”><value>${jdbc.url}</value></property>
           <property name=”username”><value>${jdbc.username}</value></property>
           <property name=”password”><value>${jdbc.password}</value></property>
       </bean>    <bean id=”transactionManager”
           class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”>
           <property name=”dataSource”><ref local=”dataSource”/></property>
        </bean>
     <!–  END DB connection info –>    
     <!–  START iBATIS config –>
      <bean id=”sqlMapClientTemplate”
         class=”org.springframework.orm.ibatis.SqlMapClientTemplate”>
        <property name=”sqlMapClient” ref=”sqlMapClient” />
      </bean>
       <bean id=”sqlMapClient” class=”org.springframework.orm.ibatis.SqlMapClientFactoryBean”>
           <property name=”dataSource” ref=”dataSource” />
           <!–  this needs to point to where the sql-map-config.xml file is –>
           <property name=”configLocation” value=”classpath:../sql-map-config.xml” />
       </bean>
     <!–  END iBATIS config –>                          
    
     <!–  START DAO config –>
      <bean id=”contactDao” class=”com.appfoundation.vms.dao.ibatis.ContactDaoImpl”>
       <property name=”sqlMapClientTemplate” ref=”sqlMapClientTemplate” />
      </bean>
     <!–  END DAO config –>
     <bean id=”contactService” class=”com.appfoundation.vms.services.ContactServiceImpl”>
         <property name=”contactDao”><ref bean=”contactDao”/></property>       
     </bean>
    </beans>
    
Step 6: Configure the Flex Remote Services
  1. Locate and open remoting-config.xml in {context-root}\WEB-INF\flex.
  2. Add the following destination:
    <destination id="contactService">     
         <properties>
                <factory>spring</factory>
                <source>contactService</source>
          </properties>
    </destination>
    
Step 7: Set up the MySQL Database Table

I am using MySQL Server 5.0 to run this example database. You can switch to your preferred database by changing the application.properties that iBATIS reads into its connection object. Those properties are injected into the iBATIS persistence framework by Spring.

  1. Locate MySQL-Setup.txt in {context-root}\WEB-INF\db
  2. Create a new database catalog named client 
  3. Run the two SQL statements to set up the contacts table and insert a default record
Step 8: Running the Application
  1. Open a browser, access http://host:port/context-root/CairngormExampleProject.mxml, and run the application. For example, I run the application using http://localhost:8080/cep/CairngormExampleProject.mxml in my browser.

11 Comments so far

  1. Michal Kuklis on May 29th, 2007

    very helpful, thanks!

  2. Matt Madhavan on July 30th, 2007

    Hey,
    Very helpful. Do you have any ideas on acegi integration? I would appreciate it.

    Thanks
    Matt

  3. cgiamett on July 31st, 2007

    Matt,

    Based on what I read about Acegi Security System for Spring is that you can integrate it with an existing Spring project.

    You could create a series of Spring services that either wrap Acegi or possible call the Acegi services directly.

    Wrapping Acegi would allow you to use Flex to make calls for authentication, authorization, instance-based access control, etc…

    Hope that helps.

  4. Matt Madhavan on August 20th, 2007

    Hi,
    When I try to run your application, I am getting the following exception! Any ideas?
    Matt

    java.lang.RuntimeException: javassist.NotFoundException: flex.bootstrap.BootstrapServlet
    at javassist.CtClassType.getClassFile2(CtClassType.java:204)
    at javassist.CtClassType.prune(CtClassType.java:1237)
    at javassist.scopedpool.ScopedClassPool.cacheCtClass(ScopedClassPool.java:201)
    at javassist.ClassPool.get0(ClassPool.java:447)
    at javassist.ClassPool.get(ClassPool.java:413)
    at org.jboss.lang.AnnotationHelper.getCtClass(AnnotationHelper.java:112)
    at org.jboss.lang.AnnotationHelper.getAnnotationsInternal(AnnotationHelper.java:98)

  5. cgiamett on August 22nd, 2007

    In your WEB-INF be sure you have the flex server installed. That should correct your issue. Let me know if that does not work for you.

  6. Hernan on May 12th, 2008

    I tried this example… And I figured out how to put it into Eclipse to get started to play with.

    It works with a few changes.

    1. put the “com”, “assets”, “META-INF” and “WEB-INF” into your web o WebContent.
    2. Into “src” put all your Java classes.
    3.Put the mysql-connector into “common\lib” -tomcat 5.x- or into “lib” for -tomcat 6.x- servers.

    Enjoy it.

  7. Gerome Goldberg on June 12th, 2008

    I have tomcat 5.5.26 running, and when I deploy the /cep directroy to webapps, I get the following. what am i doing wrong?

    SEVERE: Error listenerStart
    Jun 12, 2008 4:22:34 PM org.apache.catalina.core.StandardContext start
    SEVERE: Context [/cep] startup failed due to previous errors
    2008-06-12 16:22:34,203 INFO [org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/cep]] - Shutting down Log4J

  8. cgiamett on June 12th, 2008

    This application was built using Tomcat 5.0.28 and Java 1.4. Your issue is likely due to using the newer Tomcat J2EE container running in Tomcat 5.5.26.

  9. farzana on June 22nd, 2008

    I am not able to run the application, i am runningo out of eclipse..apparently i am not able to load the jdbc driver for mysql, not sure why though, its on my classpath

    i can connect using basic jdbc but not using spring

    can you please help

    -farzana

  10. cgiamett on June 23rd, 2008

    You can’t run this project directly in Eclipse unless you centralize your Spring data services and add an endpoint URL to your Flex Services.

  11. chakradhar on August 7th, 2008

    very helpful my project , thank u

Leave a reply

*
To prove you're a person (not a spam script), type the security word shown in the picture.
Anti-Spam Image