Thursday, October 9, 2008

Project Rosetta : Microsoft to target Flash developers

I found a new site called Project Rosetta, which is quite attracting. The purpose of this site is to collect articles, best practices for Flash developers who might be interested in Silverlight development.

I am quite disappointed because when I read the announcement, I hoped the site provide tools but this is not yet the case.

Wednesday, October 1, 2008

Maven and Flex Builder tutorial (Part III)

In the first part of this series, we explained the purpose of this tutorial, why we needed it and how we will proceed to reach the goal.

In the second part, we setup the Flex Builder project, configured it properly to be compatible with Maven, and modified some files for proper Flex debugging.

We are now at the point where we must now meet Maven, and try to build our project with this tool.

The POMs

Before we explain in detail how to Mavenize our project, let's first see what are the POMs needed and their purpose.

The project will be composed of 5 POMs, one parent POM and 4 child POMs.

The parent pom, at the root of the project, will be both a parent POM and an aggregator POM (so that executing this POM will build the whole application). The artifact id is flexandmavenapp.

The child POMs are:

one for the html templates so that when we build the WAR, we will also get the HTML wrapper. This is simply a JAR, where all the templates will be stored, and this JAR will be unpacked when we build the WAR artifact. The location of this POM is under the html-template directory and the artifact id is flexandmavenapp-html-template.

one for the Flex remoting configuration files. This is simply a JAR, where all the Flex remoting configuration files will be stored, and this JAR will be unpacked when we build the WAR artifact. The location of this POM is under the flexandmavenapp-config directory and the artifact id is flexandmavenapp-config.

one for the Flex code (MXML and ActionScript source files). It has an SWF packaging, so that Maven will produce an SWF file (thanks to the Flex mojos). This SWF artifact will also be copied when we build the WAR artifact. The location of this POM is under the flexandmavenapp-flex directory and the artifact id is flexandmavenapp-flex.

one for the web application part. It has a WAR packaging. This is where the final application will be build. It references all the three previous artifacts.The location of this POM is under the flexandmavenapp-web directory and the artifact id is flexandmavenapp-web.

Please note that all these four POMs have the first POM as parent, so that they can share some common configuration information (repository locations,...).

I have chosen com.jeffmaury (my name) as the group id, but your are free to change it if you want.

I have also chosen 1.0.0 for the version, the Maven conventions recommend to use a -SNAPSHOT suffix but  I feel now comfortable (because I did many tries before this writing !!!) with a stable approach.

The parent POM

The parent POM will declare the group id and the version that will be inherited by the child POMs.

Then we need also to declare some Maven repositories:

the Flex mojos repository: http://svn.sonatype.org/flexmojos/repository/ as a standard repository and a plugin repository

the restforflex repository: it is a repository I have built for one of my Flex open source project (see http://code.google.com/p/restforflex). Why do we need it. This is because our application has dependencies on the BlazeDS JAR files. Unfortunately, Adobe has deployed on the Maven central repository some of the BlazeDS JAR files, but not all of them. This repository will provide the missing BlazeDS JAR files.

Then, we need to declare the flex-mojos plugin as an extension to Maven, otherwise, Maven won't be able to manage SWF packaging. This is simply done by declaring the flex-mojos plugin with the extension flag to true.

The last thing to do is to declare the modules so that it acts as an aggregator, so just declare the directories:

html-template (and not the corresponding artifact id which is flexandmavenapp-html-template)

flexandmavenapp-config

flexandmavenapp-flex

flexandmavenapp-web

Create a file pom.xml at the root of your project. So, here is the POM: please don't execute it now as the child POMs have not been created yet !.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.jeffmaury</groupId>
  <artifactId>flexandmavenapp</artifactId>
  <packaging>pom</packaging>
  <name>Flex Builder and Maven integration tutorial</name>
  <version>1.0.0</version>
  <repositories>
    <repository>
      <id>flex-mojos-repository</id>
      <url>http://svn.sonatype.org/flexmojos/repository/</url>
      <releases><enabled>true</enabled></releases>
      <snapshots><enabled>false</enabled></snapshots>
    </repository>
      <repository>
          <id>restforflex</id>
          <url>http://restforflex.googlecode.com/svn/repo</url>
      </repository>
  </repositories>
  <pluginRepositories>
    <pluginRepository>
      <id>flex-mojos-repository</id>
      <url>http://svn.sonatype.org/flexmojos/repository/</url>
      <releases><enabled>true</enabled></releases>
      <snapshots><enabled>false</enabled></snapshots>
    </pluginRepository>
  </pluginRepositories>
    <build>
        <plugins>
            <plugin>
                <groupId>info.rvin.mojo</groupId>
                <artifactId>flex-compiler-mojo</artifactId>
                <version>1.0</version>
                <extensions>true</extensions>
            </plugin>
        </plugins>
    </build>
    <modules>
      <module>html-template</module>
      <module>flexandmavenapp-config</module>
      <module>flexandmavenapp-flex</module>
      <module>flexandmavenapp-web</module>
    </modules>
</project>

 

The first child POM: html-template

Now that the parent pom has been created, let's create the first child. We will start with the simpler one, html-template. As this is just a JAR artifact that must store the files that are under the html-template directory, we just need to create a JAR POM with the following restriction: as the files under this directory must not be moved because this will disturb Flex Builder, we just need to specify a non Maven resource directory. By the way, as we will add another file in this directory (pom.xml), we need to tell Maven not to package this file.

Create a file pom.xml in the html-template sub-directory. The POM will be:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.jeffmaury</groupId>
    <artifactId>flexandmavenapp</artifactId>
    <version>1.0.0</version>
  </parent>
  <artifactId>flexandmavenapp-html-template</artifactId>
  <name>Flex Builder and Maven integration tutorial (HTML files)</name>
  <build>
    <resources>
      <resource>
        <directory>${basedir}</directory>
        <excludes>
          <exclude>**/pom.xml</exclude>
          <exclude>**/target/**</exclude>
        </excludes>
      </resource>
    </resources>
  </build>
</project>

 

If you go into the html-template directory, you should run 'mvn package' or 'mvn install' as the parent POM is in the parent directory.

The second child POM: flexandmavenapp-config

This second artifact is used to stored the Flex remoting configuration files. It is a separate artifact because those files are needed for both the SWF file generation and the WAR artifact. It will be a JAR artifact (as Maven does not support ZIP artifacts).

As you may have noticed, we have not yet created this directory. So let's do it now.

In Flex Builder, right click your project, select New --> Folder, enter flexandmavenapp-config/src/main/resources as the folder name and click 'Finish'.

Then, copy the files from the directory flexandmavenapp-web/WEB-INF/flex into this directory (flexandmavenapp-config/src/main/resources).

Now, these files are present at two different locations in your project: under flexandmavenapp-config/src/main/resources and under flexandmavenapp-web/WEB-INF/flex.  We should delete the files under flexandmavenapp-web/WEB-INF/flex but this will cause the Flex Builder run/debug functionality to fail (because it will use these files).

The first solution would be to modify the Flex Builder/Eclipse WTP configuration file (org.eclipse.wst.common.component) so that it will take the files under flexandmavenapp-config/src/main/resources when deploying a web application but I didn't find information about the order in which the resources in this file.

So I decided to use Ant to copy this files from the flexandmavenapp-config/src/main/resources directory to the flexandmavenapp-web/WEB-INF/flex directory.

The solution is based on the following principles:

an Ant script file will copy the files from flexandmavenapp-config/src/main/resources to flexandmavenapp-web/WEB-INF/flex

an Ant based builder will be added to the project so that each time a file is modified into the project, the builder will be invoked and this will guaranty that the files in the flexandmavenapp-web/WEB-INF/flex are updated.

 

The Ant script file

This is quite a simple Ant file that simply execute a single task that copies files from one directory to another. In order for this file to be generic, this Ant file use a property called eclipse.project.name that is used to generate the name of the sub directories. This property will be given to Ant through the builder configuration.

Here is the content of the Ant file:

<?xml version="1.0" encoding="UTF-8"?>
<!-- ======================================================================
     ====================================================================== -->
<project name="project" default="default">
    <description>
            description
    </description>

    <!-- =================================
          target: default             
         ================================= -->
    <target name="default" description="--> Copy BlazeDS configuration files">
        <copy todir="${eclipse.project.name}-web/src/main/webapp/WEB-INF/flex" verbose="true">
            <fileset dir="${eclipse.project.name}-config/src/main/resources"></fileset>
        </copy>
    </target>

</project>

 

Store this file at the root of your project and call it maven2flexbuilder.xml.

Add the Ant builder

We will now create the Ant builder inside the Flex Builder project.

Right click the flexandmavenapp project, then click 'Properties', then select the 'Builders' tab and click 'New...'.

Select the 'Ant Builder' choice and click 'OK'. You should get the following screen:

image

Change the name to 'flexandmavenappbuilder', enter '${project_loc}/maven2flexbuilder.xml' for the 'Buildfile', enter '${project_loc}' for the 'Base Directory', then select the 'Properties' tab, unselect the 'Use global properties....' checkbox, and click 'Add Property'. Enter 'eclipse.project.name' as the 'Name', click 'Variables' and select 'project-name', click 'OK'. You should get the following screen:

image

Click 'OK' (three times) and your project is now properly configured.

Please don't forget that from now, you MUST ABSOLUTELY NOT modify the files in the flexandmavenapp-web/src/main/webapp/WEB-INF/flex directory, otherwise, the next time your project will be built, you will loose your changes. This is the only drawback of this solution.

So now, our flexandmavenapp-config artifact is Maven compliant in terms of directory layout, so we just need to write the POM and launch the build.

Create a file pom.xml in the flexandmavenapp-config sub-directory. The POM is quite simply as the directory layout is Maven compliant:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.jeffmaury</groupId>
    <artifactId>flexandmavenapp</artifactId>
    <version>1.0.0</version>
  </parent>
  <artifactId>flexandmavenapp-config</artifactId>
  <name>Flex Builder and Maven integration tutorial (config files)</name>
</project>

If you go into the flexandmavenapp-config directory, you should run 'mvn package' or 'mvn install' as the parent POM is in the parent directory.

So now, we're ready to process the next artifact, flexandmavenapp-flex.

The third child POM: flexandmavenapp-flex

This artifact will produce a SWF file, that represents our Flex user interface. It will compile MXML and ActionScript files (located under the src/main/flex sub-directory) and generate the SWF file.

So this artifact will have a SWF packaging and the corresponding Maven livecycle will be managed through the flex-mojos Maven plugins.

So we also need to configure several kind of information:

the Flex SDK dependencies (of type SWF).

the flexandmavenapp-config dependency as we need them to get the configuration files as the Flex compiler must have access to the main Flex remoting configuration file.

copy the Flex remoting configuration files to the Maven build directory so that the Flex compiler can access it in a Maven way: this is done through the Maven dependency plugin and that why the flexandmavenapp-config is a declared as a dependency.

configure the flex-mojos plugin with the location of the Flex remoting configuration file and the context root: the context root will be computed by Maven using the artifact id of the parent POM and adding the -web suffix (including the version).

Create a file pom.xml in the flexandmavenapp-flex sub-directory. The POM is detailed below:

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.jeffmaury</groupId>
    <artifactId>flexandmavenapp</artifactId>
    <version>1.0.0</version>
  </parent>
  <artifactId>flexandmavenapp-flex</artifactId>
  <packaging>swf</packaging>
  <name>Flex Builder and Maven integration tutorial (Flex files)</name>
  <dependencies>
    <dependency>
      <groupId>com.adobe.flex.sdk</groupId>
      <artifactId>playerglobal</artifactId>
      <version>3.0.0.477</version>
      <type>swc</type>
      <scope>external</scope>
    </dependency>
    <dependency>
      <groupId>com.adobe.flex.sdk</groupId>
      <artifactId>framework</artifactId>
      <version>3.0.0.477</version>
      <type>swc</type>
    </dependency>
    <dependency>
      <groupId>com.adobe.flex.sdk</groupId>
      <artifactId>framework</artifactId>
      <version>3.0.0.477</version>
      <type>resource-bundle</type>
      <classifier>en_US</classifier>
    </dependency>
    <dependency>
      <groupId>com.adobe.flex.sdk</groupId>
      <artifactId>rpc</artifactId>
      <version>3.0.0.477</version>
      <type>swc</type>
    </dependency>
    <dependency>
      <groupId>com.adobe.flex.sdk</groupId>
      <artifactId>rpc</artifactId>
      <version>3.0.0.477</version>
      <type>resource-bundle</type>
      <classifier>en_US</classifier>
    </dependency>
    <dependency>
      <groupId>com.jeffmaury</groupId>
      <artifactId>flexandmavenapp-config</artifactId>
      <version>1.0.0</version>
    </dependency>
  </dependencies>
  <build>
    <sourceDirectory>src/main/flex</sourceDirectory>
    <testSourceDirectory>src/test/flex</testSourceDirectory>
    <outputDirectory>
      ${project.build.directory}/flex-compiler
    </outputDirectory>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
          <execution>
            <goals>
              <goal>unpack-dependencies</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <includeGroupIds>com.jeffmaury</includeGroupIds>
        </configuration>
      </plugin>
      <plugin>
        <groupId>info.rvin.mojo</groupId>
        <artifactId>flex-compiler-mojo</artifactId>
        <executions>
          <execution>
            <goals>
              <goal>compile-swf</goal>
            </goals>
            <configuration>
              <services>
                ${project.build.directory}/dependency/services-config.xml
              </services>
              <contextRoot>
                ${project.parent.artifactId}-web-${project.version}
              </contextRoot>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Now, go into the flexandmavenapp-flex directory and enter 'mvn install'. If you have a pretty new Maven local repository, Maven will start downloading a lots of JAR and then start to build your SWF file. But, unless you are a user of flex-mojos, the build will FAIL. So you're probably wondering why. Here is the answer: although I take care to setup the required repositories (flex-mojos and restforflex) so that all dependencies can be satisfied (including the Flex SDK and BlazeDS), some part of the Flex SDK are not open sourced and thus cannot be deployed to a public repository. Don't be afraid, this will not force you to have a Maven repository only for this tutorial, why will simply install the missing artifacts to your local Maven repository. In order to do that, you must have the Flex SDK installed on your local machine.

The missing artifacts are:

com.adobe.flex:license:jar:3.0.0.477

com.adobe.flex:aglj32:jar:3.0.0.477

com.adobe.flex:rideau:jar:3.0.0.477

com.adobe.flex:flex-fontkit:jar:3.0.0.477

Installing the missing Flex artifacts

Go into the lib sub-directory of your Flex SDK directory and enter the following commands:

mvn install:install-file -Dfile=license.jar -DgroupId=com.adobe.flex -DartifactId=license -Dversion=3.0.0.477 -Dpackaging=jar

mvn install:install-file -Dfile=rideau.jar -DgroupId=com.adobe.flex -DartifactId=rideau -Dversion=3.0.0.477 -Dpackaging=jar

mvn install:install-file -Dfile=aglj32.jar -DgroupId=com.adobe.flex -DartifactId=aglj32 -Dversion=3.0.0.477 -Dpackaging=jar

mvn install:install-file -Dfile=flex-fontkit.jar -DgroupId=com.adobe.flex -DartifactId=flex-fontkit -Dversion=3.0.0.477 -Dpackaging=jar

Now, return to the flexandmavenapp-flex directory and run 'mvn install'. Now, all dependencies are resolved. You may still get an error from Maven because the flex-mojos Maven plugins require a 1.5+ JVM. If you were running Maven with a 1.4 JVM, update your JAVA_HOME environment to a 1.5 JVM and run 'mvn install' again and this will now be successful.

We are now ready to build the last POM of your solution.

The fourth child POM: flexandmavenapp-web

This artifact is a web application, so we will use the WAR Maven packaging. As we set a Maven directory layout (src/main/webapp), this will be quite simple.

When Maven will generate the WAR file, we just need to copy the configuration files from the flexandmavenapp-config artifact into the WEB-INF/flex sub-directory of the WAR: this will be done with the Maven dependency plugin. We will then declare the flexandmavenapp-config as a dependency but because we don't want the JAR file to be in the WEB-INF/lib sub-directory, we will use the provided Maven scope to prevent such copy.

When Maven will generate the WAR file, we also need to copy the HTML files from the flexandmavenapp-html-template artifact into the root directory of the WAR: this will be done with the Maven dependency plugin. This copy will be done in two steps: first, extract the files from the flexandmavenapp-html-template dependency in a temporary directory, then process these files are resources because we need to replace values in those template files. This is done with the Maven filtering feature. So we need to add a filter file to the project. The file is called filter.properties and is located under the src/main/filters sub-directory. The content of this file is given below:

swf=${pom.parent.artifactId}-flex-${pom.version}
title=${pom.artifactId}
application=${pom.artifactId}
width=600
height=400
bgcolor=#FFFFFF
version_major=9
version_minor=0
version_revision=28

You are free to modify the hard coded values to your needs if you want (size or background color for example).

We will then declare the flexandmavenapp-html-template as a dependency but because we don't want the JAR file to be in the WEB-INF/lib sub-directory, we will use the provided Maven scope to prevent such copy.

Please also note that we configure the Maven WAR plugin so that it will not copy the files from the WEB-INF/lib and WEB-INF/flex sub-directories as those directories are only here for the Flex Builder run/debug feature.

Create a file pom.xml in the flexandmavenapp-web sub-directory. The POM is detailed below:

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.jeffmaury</groupId>
    <artifactId>flexandmavenapp</artifactId>
    <version>1.0.0</version>
  </parent>
  <artifactId>flexandmavenapp-web</artifactId>
  <packaging>war</packaging>
  <name>Flex Builder and Maven integration tutorial (Web)</name>
  <dependencies>
    <dependency>
      <groupId>com.jeffmaury</groupId>
      <artifactId>flexandmavenapp-flex</artifactId>
      <version>1.0.0</version>
      <type>swf</type>
    </dependency>
    <dependency>
      <groupId>com.jeffmaury</groupId>
      <artifactId>flexandmavenapp-config</artifactId>
      <version>1.0.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>com.jeffmaury</groupId>
      <artifactId>flexandmavenapp-html-template</artifactId>
      <version>1.0.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>com.adobe.blazeds</groupId>
      <artifactId>blazeds-core</artifactId>
      <version>3.0</version>
    </dependency>
    <dependency>
      <groupId>com.adobe.blazeds</groupId>
      <artifactId>blazeds-common</artifactId>
      <version>3.0</version>
    </dependency>
    <dependency>
      <groupId>com.adobe.blazeds</groupId>
      <artifactId>blazeds-remoting</artifactId>
      <version>3.0</version>
    </dependency>
    <dependency>
      <groupId>com.adobe.blazeds</groupId>
      <artifactId>blazeds-opt</artifactId>
      <version>3.0.0.544</version>
    </dependency>
    <dependency>
      <groupId>com.adobe.blazeds</groupId>
      <artifactId>blazeds-proxy</artifactId>
      <version>3.0.0.544</version>
    </dependency>
    <dependency>
      <groupId>commons-httpclient</groupId>
      <artifactId>commons-httpclient</artifactId>
      <version>3.0.1</version>
    </dependency>
  </dependencies>
  <build>
    <resources>
      <resource>
        <directory>${project.build.directory}/html-template</directory>
        <filtering>true</filtering>
      </resource>
    </resources>
    <filters>
      <filter>src/main/filters/filter.properties</filter>
    </filters>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <executions>
          <execution>
            <phase>process-resources</phase>
            <goals>
              <goal>resources</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <outputDirectory>
            ${project.build.directory}/${project.build.finalName}
          </outputDirectory>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.1-alpha-2</version>
        <configuration>
          <warSourceExcludes>
            WEB-INF/lib/*,WEB-INF/flex/*
          </warSourceExcludes>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
          <execution>
            <id>copy-dependencies</id>
            <goals>
              <goal>copy-dependencies</goal>
            </goals>
            <configuration>
              <includeTypes>swf</includeTypes>
              <includeGroupIds>com.jeffmaury</includeGroupIds>
              <outputDirectory>
                ${project.build.directory}/${project.build.finalName}
              </outputDirectory>
            </configuration>
          </execution>
          <execution>
            <id>config</id>
            <goals>
              <goal>unpack-dependencies</goal>
            </goals>
            <configuration>
              <includeGroupIds>com.jeffmaury</includeGroupIds>
              <includeArtifactIds>
                flexandmavenapp-config
              </includeArtifactIds>
              <outputDirectory>
                ${project.build.directory}/${project.build.finalName}/WEB-INF/flex
              </outputDirectory>
            </configuration>
          </execution>
          <execution>
            <id>html-template</id>
            <goals>
              <goal>unpack-dependencies</goal>
            </goals>
            <configuration>
              <includeGroupIds>com.jeffmaury</includeGroupIds>
              <includeArtifactIds>
                flexandmavenapp-html-template
              </includeArtifactIds>
              <outputDirectory>
                ${project.build.directory}/html-template
              </outputDirectory>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

So, go to the flexandmavenapp-web sub-directory and enter 'mvn install'. The build will succeed and if you go into the target sub-directory, you will see a flexandmavenapp-web-1.0.0.war file. Our Flex/Maven application has been generated.

You can also generate the WAR file using the parent POM so that it will build all the four POMs. Go up one level in the directory hierarchy and type 'mvn install'.

Now, we just need to test the application.

Testing the application

The test will be simple to achieve: deploy the WAR file to your favorite J2EE application/servlet container and then open your browser to http://localhost:8080/flexandmavenapp-web-1.0.0/index.template.html if your J2EE application/servlet container is listening on port 8080.

You should see the following screen:

image

If you are using Tomcat (I did the test with Tomcat 4.1.31), simply drop the WAR file under the webapps sub-directory of your Tomcat installation and start Tomcat.

Conclusion

This third part has reached its end, and the series also.

I have uploaded a zip file of the whole directory structure to a public site: you can download this file at the following URL: http://sites.google.com/site/flexandmavenapp/Home/flexandmavenapp.zip?attredirects=0

Please feel free to comment if you think some points may be better explained. I plan to extend this series with the use of another Flex SDK (3.1 for example) and also with the next version of the flex-mojos Maven plugins. You can contact me at jeffmaury (at) jeffmaury dot com.