Wednesday, October 21, 2009

Creating a Flex application with Maven that support Flash Player 10 and Flex SDK 3.4

Hello all,

I have been playing with Flex-mojos plugin (Thanks VELO) for two to three days, reading the recommended book(maven definite guide), etc.

I had come to LOOOOTS of old misleading blogs(which I'm sure this one will become!).
So First thing I want to say is that the day I wrote this article was OCTOBER 21, 2009
I'm using:
  • Flex-mojos 3.2.0
  • Flash Player 10
  • Flex SDK 3.4
  • RSL and caching capabilities to reduce swf/swc file sizes.
My approach is to provide you with the pom files and a Step by Step Guide to build the project.

Before getting into the code, I'm going to summarize what I am going to accomplish:

  1. A top level project that will have three modules:
    1. An RSL project that has only flex framework dependencies. (TopLevelLibrary)
    2. An RSL project that will depend on the TopLevelLibrary project. (MidLevelLibrary)
    3. An application that will use a component from the MidLevelLibrary project. (Flex-app)
Both RSL will be optimized to reduce the size of the application and to have the RSL load faster.
My Box is a Windows Vista. so I will create the project on C:\blog\examples\multi-level-flex-maven and I will call it PROJECT_HOME.


  1. Create the top level pom that will contain the three modules specified before in the folder PROJECT_HOME. As follows
  2. 
      4.0.0
    
      
        org.sonatype.flexmojos
        flexmojos-flex-super-pom
        3.2.0
      
    
      com.leonardovarela.blog.examples
      multi-level-flex-maven
      1.0-SNAPSHOT
    
      pom
      Parent Project Multi Level Flex Maven
      http://www.leonardovarela.com
      
        Leonardo Varela
        http://www.leonardovarela.com
      
      
        
          leonardo.varela
          Leonardo Varela
          leonardovarela@gmail.com
          http://www.leonardovarela.com
          Leonardo Varela
          http://www.leonardovarela.com
          
            Researcher
            Blogger
            Developer
            Freelancer
       
          -8
        
      
      
      
        3.4.0.9271
        3.2.0
        10.0.0
        10
        Flex-Maven-RSL
       
    
      
        
          
            org.sonatype.flexmojos
            flexmojos-maven-plugin
            ${flexmojos.version}
            
              true
              
                {artifactId}-{version}.{extension}
              
              ${flash.version}
            
            
       
          com.adobe.flex
          compiler
          ${flex.version}
          pom
       
     
          
        
        
          
            
              org.apache.maven.plugins
              maven-dependency-plugin
              2.0
            
          
        
      
    
      
      
        
          flex-mojos-repository
          http://repository.sonatype.org/content/groups/public
             true 
                         true  
        
        
          flex-mojos-repository2
          http://repository.sonatype.org/content/repositories/all-004/
             true 
             true  
        
      
      
        
          flex-mojos-repository
          http://repository.sonatype.org/content/groups/public
             true 
                         true  
        
      
      
      
        TopLevelLibrary
        MidLevelLibrary
        Flex-app
      
    
    
    We are defining the properties in the tag for the whole project, we are setting up flex-mojos 3.2 as a super pom(parent) for this project. The coordinates for this project are:
    1. groupid: com.leonardovarela.blog.examples
    2. artifactid: multi-level-flex-maven
    3. version: 1.0-SNAPSHOT
    We are defining the repositories and the plugin repositories: Make sure to include http://repository.sonatype.org/content/repositories/all-004/ which is the repository with the 3.4 version of Flex.
  3. Create the folder structure for your project:
    1. PROJECT_HOME/TopLevelLibrary
    2. PROJECT_HOME/MidLevelLibrary
    3. PROJECT_HOME/Flex-app
  4. Lets Create the Library projects.
    1. TopLevelLibrary project setup
      Inside the directory PROJECT_HOME/TopLevelLibrary create a pom file that we will use to build the optimized RSL with no dependencies. The pom should look like this:
      
        4.0.0
      
        
          com.leonardovarela.blog.examples
          multi-level-flex-maven
          1.0-SNAPSHOT
        
      
        com.leonardovarela.blog.examples
        TopLevelLibrary
        1.0-SNAPSHOT
      
        swc
      
        
        
              com.adobe.flex.framework
              framework
              ${project.flex.version}
              swc
              external
          
        
        
          com.adobe.flex.framework
          flex-framework
          ${project.flex.version}
          pom
          
            
              com.adobe.flex.framework
              playerglobal
            
          
          external
        
        
          com.adobe.flex.framework
          playerglobal
          ${project.flex.version}
          ${project.flash.player.classifier}
          swc
          external
        
        
          org.sonatype.flexmojos
          flexmojos-unittest-support
          ${project.flexmojos.version}
          swc
          test
        
       
       
          
            
              org.sonatype.flexmojos
              flexmojos-maven-plugin
              
                true
                
                  {artifactId}-{version}.{extension}
                
                ${project.flash.version}
              
              
                
                  
                    optimize
                  
                
              
            
          
        
        
      
      
      
      Please notice that the scope of the dependencies is External which will reduce the size of your RSL a LOT! Also notice the execution goal 'optimize'. Also understand that I am excluding playerglobal from flex-framework because by default it uses Flash Player 9, this is how we are supporting Flash Player 10!!! Now we need to add some code to the library! Here's what I'm sure you know how to do! But we will add some sample classes just to test.
      Now that we have defined the pom file lets create the default project structure either with a maven archetype or from your existing sources.
      1. PROJECT_HOME/TopLevelLibrary/src/main/flex/com/leonardovarela/blog/examples/toplevellibrary
      2. PROJECT_HOME/TopLevelLibrary/src/main/test/com/leonardovarela/blog/examples/toplevellibrary
      3. Add the following component(TopLevelLibraryComponent.mxml) to the package com.leonardovarela.blog.examples.toplevellibrary (Please note that the syntax highlighter removes the casing so please make box->Box, label->Label, image->Image and don't forget the <?xml version="1.0" encoding="utf-8"?> at the beginning of the mxml file):
        
        
          
          
        
        
      4. Get the image: America and place it on the same folder of the component (PROJECT_HOME/TopLevelLibrary/com/leonardovarela/blog/examples/toplevellibrary)
      5. You are all set for the top level library
    2. Now lets add another RSL that depends on the TopLevelLibraryProject.
      For that lets create another porject folder structure and another pom file.
      1. The project will be named MidLevelLibrary and its location will be: PROJECT_HOME/MidLevelLibrary so create that folder and inside a package structure similar to the last project:
        1. PROJECT_HOME/MidLevelLibrary/src/main/flex/com/leonardovarela/blog/examples/midlevellibrary
        2. PROJECT_HOME/MidLevelLibrary/src/main/test/com/leonardovarela/blog/examples/midlevellibrary<








      2. Now lets create the pom file for the MidLevelLibrary that uses the component of the TopLevelLibrary: The file should be like this:
        
        
          4.0.0
          
            com.leonardovarela.blog.examples
            multi-level-flex-maven
            1.0-SNAPSHOT
          
          com.leonardovarela.blog.examples
          MidLevelLibrary
          1.0-SNAPSHOT
          swc
          
            
              com.leonardovarela.blog.examples
              TopLevelLibrary
              1.0-SNAPSHOT
              swc
              external
            
            
              com.adobe.flex.framework
              framework
              ${project.flex.version}
              swc
              external
            
            
              com.adobe.flex.framework
              flex-framework
              ${project.flex.version}
              pom
              
                
                  com.adobe.flex.framework
                  playerglobal
                
              
              external
            
            
              com.adobe.flex.framework
              playerglobal
              ${project.flex.version}
              ${project.flash.player.classifier}
              swc
              external
            
            
              org.sonatype.flexmojos
              flexmojos-unittest-support
              ${project.flexmojos.version}
              swc
              test
            
          
          
            
              
                org.sonatype.flexmojos
                flexmojos-maven-plugin
                
                  true
                  
                    {artifactId}-{version}.{extension}
                  
                  ${project.flash.version}
                
                
                  
                    
                      optimize
                    
                  
                
              
            
          
        
        
      3. Now lets create a component that uses the component from the TopLevelLibrary: we will name it: MidLevelComonentThatUsesTopLevelLibrary.mxml and will live in the package com.leonardovarela.blog.examples.midlevellibrary and the contents should be:
        (Please note that the syntax highlighter removes the casing so please make panel->Panel and toplelvellibraryComponent->TopLevelLibraryComponent and don't forget the <?xml version="1.0" encoding="utf-8"?> at the beginning of the mxml file):
        
        
          
        
        
        
        We are done with the RSLs, now we want to proceed to create the Flex project that uses them.
  5. Lets create the Flex project
    Lets start with the folder structure.
    1. PROJECT_HOME/Flex-app/src/main/flex/
    2. PROJECT_HOME/Flex-app/src/main/test/
    Now lets create the pom file:
    
    
      4.0.0
    
      
        com.leonardovarela.blog.examples
        multi-level-flex-maven
        1.0-SNAPSHOT
      
    
      com.leonardovarela.blog.examples
      Flex-app
      1.0-SNAPSHOT
      
      swf
    
      
        
          com.adobe.flex.framework
          framework
          ${project.flex.version}
          swc
          caching
        
        
          com.adobe.flex.framework
          flex-framework
          ${project.flex.version}
          pom
          
            
              com.adobe.flex.framework
              playerglobal
            
          
          external
        
        
          com.adobe.flex.framework
          playerglobal
          ${project.flex.version}
          ${project.flash.player.classifier}
          swc
          external
        
        
          com.leonardovarela.blog.examples
          TopLevelLibrary
          1.0-SNAPSHOT
          swc
          rsl
        
        
          com.leonardovarela.blog.examples
          MidLevelLibrary
          1.0-SNAPSHOT
          swc
          rsl
        
        
          org.sonatype.flexmojos
          flexmojos-unittest-support
          ${project.flexmojos.version}
          swc
          test
        
      
      
        
          
            org.sonatype.flexmojos
            flexmojos-maven-plugin
            
               
                 
                   
                   wrapper
                  
                 
                   true
                   
                     {artifactId}-{version}.swf
                   
                   ${project.flash.version}
                 
                          
            
          
        
      
    
    
    
    Now that we have the pom, lets create the source code of the application that will use the RSLs:
    In the base package(PROJECT_HOME/Flex-app/src/main/flex folder) create the main application main.mxml with the following contents:
    (Please note that the syntax highlighter removes the casing so please make application->Application, label->Label, box->Box, midlelvellibraryComponent->MidLevelLibraryComponent and
    midlevelcomponentThatUsesTopLevelLibrary->MidLevelComponentThatUsesTopLevelLibrary and don't forget the <?xml version="1.0" encoding="utf-8"?> at the beginning of the mxml file):
    
    
      
       
      
      
    
    
    Now lets create a dumb test case just to illustrate the usage of the test case plugin.
    on the folder PROJECT_HOME/Flex-app/src/main/test/ create a TestApp.as file with the following contents:

    /**
     *  Copyright 2009 Leonardo Varela
     */
    package com.leonardovarela.blog.examples.test{
    
     import flexunit.framework.TestCase;
    
     public class TestApp extends TestCase {
    
      /**
       * Dumb Tests to exemplify unit tests
       */
      public function testDumbTest():void 
      {
            assertEquals("Test is incorrect", "America is the best soccer team ever", "America is the best soccer team ever");
      }
     }
    }
    
    

    OK!!!! We are good to give it a try!









  6. Executing the installation:
    Just go to the PROJECT_HOME location and type mvn -DflashPlayer.command=<path to your flash player> install
    where <path to your flash player> could be: C:\flash\FlashPlayer.exe

    This -D option is a workaround of a bug that I think is fixed on flex-mojos 3.3 but I haven't given it a test yet.









  7. Now the part where most of the trouble happens!
    Lets try to execute Flex-app-1.0-SNAPSHOT.html from PROJECT_HOME\multi-level-flex-maven\Flex-app\target
    You will get an RSL Error.... so what you need to do is to copy the swf dependencies(RSLs) to that folder. Go grab them from the target folders of the TopLevelLibrary and MidLevelLibrary Project and place them in the target folder of the Flex-app project.
    There are plenty of better ways to do this, but that was not the scope of this guide.
    If you want to submit an improved pom that copies dependencies automatically! You are very welcome.




  8. Hopefully you have been working with 3.4.09271 sdk and you will have no problems, if the page tells you that It cannot find the framework...swz then get the SDK from here: http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+3



  9. Copy and paste the framework_3.4.0.9271.swz file to the Flex-app target folder. Rename it to framework-3.4.0.9271.swz and execute the Flex-app-SNAPSHOT-1.0.swf file. That file can be found on the %FLEX SDK EXTRACT DIRECTORY%\frameworks\rsls In a web project you would have to have this file in the same location of your swf application, just like we are doing it here. NOTE: Make sure to rename it, We ARE changing the _(underscore) to a -(dash)

  10. Thanks for making it to the end of the step by step guide. As a Bonus: Here's the code:CODE!

  11. If you really appreciate this post, please post links to it from your community forums etc...

  12. Please fill the one question survey on the left side of the post... it will be just 10 seconds..

  13. I will create another post with Flex 3.4/RSLS/Cairngorm/BlazeDS/Hibernate soon! Please click on the ads to have time/money to do it!