Maven: The Complete Reference

Developing with Flexmojos

Chapter 13

13.1. Introduction

This chapter provides an overview of the Flexmojos project for people interested in using Maven to develop Flex applications and libraries.

13.2. Configuring Build Environment for Flexmojos

Before you attempt to compile Flex libraries and applications with Maven, you will need to complete two configuration tasks:

  • Configure your Maven settings to reference a repository which contains the Flex framework
  • Add the Flash Player to your PATH to support Flex unit testing
  • (Optional) Configure your Maven Settings to include the Sonatype plugin group

13.2.1. Referencing a Repository with the Flex Framework

To setup your Maven environment for Flexmojos, you have two options: you can reference the Sonatype Flexmojos repository directly in a pom.xml, or you can install Nexus and add the Sonatype Flexmojos repository as a proxy repository in your own repository manager. While the most straightforward option is to reference the repository directly, downloading and installing Nexus will give you the control and flexibility you need to cache and manage artifacts generated by your own build. If you are just interested in getting up and running with Flexmojos, read the section called “Referencing Sonatype’s Flexmojos Repository in a POM” next. If you are interested in a long-term solution which can be deployed to support a development team, continue to the section called “Proxying Sonatype’s Flexmojos Repository with Nexus”.

Note

If your organization is already using Sonatype Nexus to proxy remote repositories, you may already have customized your ~/.m2/settings.xml file to point to a single Nexus group. If this is your situation, you should add a Proxy repository for the Sonatype Flexmojos repository group at ${flexmojos.repository}[${flexmojos.repository}]. Add this new repository to the Nexus Repository Group that is referenced by your development team. Adding a proxy repository for this remote group and then adding this group to your Nexus installation’s public repository group will give clients of your Nexus instance access to the artifacts from the Sonatype repository.sonatype.org Nexus instance.

Referencing Sonatype’s Flexmojos Repository in a POM

Flexmojos depends on a few artifacts which are not currently available from the Central Maven repository. These artifacts are available from a Repository hosted by Sonatype. To use Flexmojos, you will need to reference this repository from your project’s pom.xml. To do this, add the repositories element shown in Adding a Reference to Sonatype’s FlexMojos Repository in a POM to your project’s pom.xml.

Adding a Reference to Sonatype’s FlexMojos Repository in a POM. 

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>test</groupId>
    <artifactId>test</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <module>swc</module>
        <module>swf</module>
        <module>war</module>
    </modules>

    *<repositories>
        <repository>
            <id>flexmojos</id>
            <url>${flexmojos.repository}</url>
        </repository>
    </repositories>*

</project>

The XML shown in Adding a Reference to Sonatype’s FlexMojos Repository in a POM, will add this repository to the list of repositories Maven will consult when it attempts to download artifacts and plugins.

Proxying Sonatype’s Flexmojos Repository with Nexus

Instead of pointing directly at the Sonatype Flexmojos repository, Sonatype recommends that you install a repository manager and proxy the Sonatype public repository. When you proxy a remote repository with a repository manager such as Nexus, you gain a level of control and stability not possible when your build relies directly on external resources. In addition to this control and stability, a repository manager also provides you with an deployment target for binary artifacts generated by your own builds. For instructions on downloading, installing, and configuring Nexus, refer to the Installation chapter in Repository Management with Nexus.

13.2.2. Configure a Flexmojos Proxy Repository in Nexus

Once Nexus is installed and started, complete the following steps to add a proxy repository for the Sonatype public repository. To add a new proxy repository:

  1. Click on the Repositories link under Views/Repositories in the Nexus menu on the left-hand side of the Nexus user interface.
  2. Click on Repositories to load the Repositories panel.
  3. In the Repositories panel, click on the Add.. button and select Proxy Repository as shown in Figure 13.1, “Adding a Proxy Repository to Sonatype Nexus”.
figs/web/flex-dev-nexus-add-proxy.png

Figure 13.1. Adding a Proxy Repository to Sonatype Nexus

Once you’ve created a new Proxy repository, you will need to configure it to point to the Sonatype Flexmojos repository.

  1. Select the new repository, and then
  2. Select the Configuration tab in the lower half of the window.
  3. Populate the following field with the values shown in Figure 13.2, “Configuring the Sonatype Flexmojos Proxy Repository”.

    1. Repository ID is "sonatype-flexmojos"
    2. Repository Name is "Sonatype Flexmojos Proxy"
    3. The Remote Storage Location is ${flexmojos.repository}[${flexmojos.repository}]
figs/web/flex-dev-nexus-sonatype-proxy.png

Figure 13.2. Configuring the Sonatype Flexmojos Proxy Repository

Once you have populated the fields shown in Figure 13.2, “Configuring the Sonatype Flexmojos Proxy Repository” click the Save button to save the proxy repository and start proxying the Sonatype Flexmojos repository.

Add the Flexmojos Proxy Repository to a Group

Nexus ships with a public repository group, which combines several repositories into a single URL for Maven clients. Add this new Flexmojos proxy repository to the Nexus public group. To do this:

  1. Return to the list of repositories which should now be visible in the upper half of the Repositories panel as shown in Figure 13.2, “Configuring the Sonatype Flexmojos Proxy Repository”.
  2. Click on the Public Repositories group, and then
  3. Click on the Configuration tab in the lower half of the Repository panel. Clicking the Configuration tab will expose the Group configuration form shown in Figure 13.3, “Adding the Sonatype Flexmojos Proxy to the Public Repositories Group”.
figs/web/flex-dev-nexus-sonatype-to-group.png

Figure 13.3. Adding the Sonatype Flexmojos Proxy to the Public Repositories Group

  1. To add the Sonatype Public Proxy to the Public Repositories group simply drag and drop the Sonatype Public Proxy repository from the Available Repositories list to the Ordered Group Repositories list.
  2. Click Save, and you have successfully added a proxy of the Sonatype Flexmojos repository to your Nexus installation.

Whenever a client requests an artifact from this repository group, if Nexus has not already cached a matching artifact, it will query the Sonatype Flexmojos repository at ${flexmojos.repository}[${flexmojos.repository}]. Your Nexus installation will maintain a local cache of all artifacts retrieved from the Sonatype Flexmojos repository. This local cache gives you more control and contributes to a more stable build environment. If you are setting up a group of developers to rely upon artifacts from the Sonatype public repository, you’ll have a completely self-contained build environment that won’t be subject to the availability of the Sonatype repository once the necessary artifacts have been cached by your Nexus instance.

Configure Your Development Environment for Nexus

The final step is connecting your Maven installation to the Nexus instance you just configured. You will need to update your Maven Settings to use your Nexus repository group as a mirror for all repositories. To do this, you need to put the following XML in your ~/.m2/settings.xml file.

Settings XML for Local Nexus Instance. 

<settings>
    <mirrors>
        <mirror>
            <!--This sends everything else to /public -->
            <id>nexus</id>
            <mirrorOf>*</mirrorOf>
            <url>http://localhost:8081/nexus/content/groups/public</url>
        </mirror>
    </mirrors>
    <profiles>
        <profile>
            <id>nexus</id>
            <!--all requests to nexus via the mirror -->
            <repositories>
                <repository>
                    <id>central</id>
                    <url>http://central</url>
                    <releases><enabled>true</enabled></releases>
                    <snapshots><enabled>true</enabled></snapshots>
                </repository>
            </repositories>
            <pluginRepositories>
                <pluginRepository>
                    <id>central</id>
                    <url>http://central</url>
                    <releases><enabled>true</enabled></releases>
                    <snapshots><enabled>true</enabled></snapshots>
                </pluginRepository>
            </pluginRepositories>
        </profile>
    </profiles>
    <activeProfiles>
        <activeProfile>nexus</activeProfile>
    </activeProfiles>
</settings>

This XML file configures Maven to consult a single public repository group for all configured repositories and plugin repositories. It is a simple way to guarantee that every request for an artifact is made through your Nexus installation.

13.2.3. Configuring Environment to Support Flex Unit Tests

Flexmojos expects to be able to launch the stand-alone Flash Player to execute unit tests. In order for this to work, you will need to add the stand-alone Flash Player to your PATH, or you will need to pass the location of the Flash Player executable to your build using the -DflashPlayer.command options. When executing a unit test, Flex Mojos expects to launch the following platform-specific executables for the stand-alone Flash Player:

Microsoft Windows

FlexMojos will attempt to launch the FlashPlayer.exe binary. To support execution of unit tests, add the directory containing FlashPlayer.exe to your PATH or pass in the location of the FlashPlayer.exe binary to Maven using the

Macintosh OSX

FlexMojos will attempt to launch the "Flash Player" application. To support the execution of unit tests, add the directory containing "Flash Player" to your PATH or pass the path to the executable to option.

Unix (Linux, Solaris, etc.)

FlexMojos will attempt to launch the flashplayer executable. To support the execution of unit tests, add the directory containing flashplayer to your PATH or pass the path to the executable to option.

Note

On a Linux machine, you will need to have X virtual framebuffer (Xvfb) installed to run unit tests in a headless build. For more information about Xvfb, click here.

If you have been developing Flash Applications with Adobe Flash CS4 or Adobe Flex Builder or if you have been viewing flash content in a browser, you probably have the Flash Player installed somewhere on your workstation. While it is possible to configure Maven to use one of these players for Flex unit tests, you’ll want to make sure that you are running the debug version of the Flash Player. To minimize the potential for incompatibility, you should download one of the Flash Player’s listed below and install it on your local workstation. To download the standalone Flash Player for you environment:

To install this player and add it to your PATH on an OSX machine, run the following commands:

$ wget http://download.macromedia.com/pub/flashplayer/updaters/10/\
       flashplayer_10_sa_debug.app.zip
$ unzip flashplayer_10_sa_debug.app.zip
$ sudo cp -r Flash\ Player.app /Applications/
$ export PATH=/Applications/Flash\ Player.app/Contents/MacOS:${PATH}

Instead of adding the path for the Flash Player to your PATH on the command-line, you should configure your environment to automatically configure these variables. If you are using bash, you would add the last export command to your ~/.bash_profile.

13.2.4. Adding FlexMojos to Your Maven Settings' Plugin Groups

If you need to run FlexMojos goals from the command-line, it will be more convenient if you add the Sonatype Plugin groups to your Maven Settings. To do this, open up ~/.m2/settings.xml and add the following plugin groups:

Adding Sonatype Plugins to Maven Settings. 

<pluginGroups>
    <pluginGroup>com.sonatype.maven.plugins</pluginGroup>
    <pluginGroup>org.sonatype.plugins</pluginGroup>
</pluginGroups>

Once you’ve added these plugin groups to your Maven Settings you can invoke a FlexMojos goal using the plugin prefix flexmojos. Without this configuration, calling the flexbuilder goal would involve the following command-line:

$ mvn org.sonatype.flexmojos:flexmojos-maven-plugin:${flexmojos.version}:flexbuilder

With the org.sonatype.plugins group in your Maven settings, the same goal can be invoked with:

$ mvn flexmojos:flexbuilder

13.3. Creating a Flex Mojos Project from an Archetype

Flexmojos has a set of archetypes which can be used to quickly create a new Flex project. The following archetypes are all in the org.sonatype.flexmojos group with a version of ${flexmojos.version}:

flexmojos-archetypes-library

Creates a simple Flex Library project which produces a SWC

flexmojos-archetypes-application

Creates a simple Flex Application with produces a SWF

flexmojos-archetypes-modular-webapp

Creates a Multimodule project which consists of a project that produces a SWC which is consumed by a project which produces a SWF that is ultimately presented in a project that generates a WAR

13.3.1. Creating a Flex Library

To create a Flex Library Project, execute the following command at the command-line:

$ mvn archetype:generate \
-DarchetypeRepository=http://repository.sonatype.org/content/groups/public\
-DarchetypeGroupId=org.sonatype.flexmojos \
-DarchetypeArtifactId=flexmojos-archetypes-library \
-DarchetypeVersion=${flexmojos.version}
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] com.sonatype.maven.plugins: checking for updates from central
...
[INFO] [archetype:generate]
[INFO] Generating project in Interactive mode
[INFO] Archetype defined by properties
...
Define value for groupId: : +org.sonatype.test+
Define value for artifactId: : +sample-library+
Define value for version:  1.0-SNAPSHOT: : +1.0-SNAPSHOT+
Define value for package:  org.sonatype.test: : +org.sonatype.test+
Confirm properties configuration:
groupId: org.sonatype.test
artifactId: sample-library
version: 1.0-SNAPSHOT
package: org.sonatype.test
Y: : +Y+[INFO] Parameter: groupId, Value: org.sonatype.test
[INFO] Parameter: packageName, Value: org.sonatype.test
[INFO] Parameter: basedir, Value: /Users/Tim
[INFO] Parameter: package, Value: org.sonatype.test
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: artifactId, Value: sample-library
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL

If you look in the directory sample-library/ you will see that the project consists of the directory structure shown in Figure 13.4, “Flexmojo Library Archetype File Structure”.

figs/web/flex-dev-arche-simple-lib-fs.png

Figure 13.4. Flexmojo Library Archetype File Structure


The product of the simple Flex library archetype only contains three files: a POM, one source, and a unit test. Let’s examine each of these files. First, the Project Object Model (POM).

Project Object Model for Flex Library Archetype. 

<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>org.sonatype.test</groupId>
    <artifactId>sample-library</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>swc</packaging>

    <name>sample-library Flex</name>

    <build>
        <sourceDirectory>src/main/flex</sourceDirectory>
        <testSourceDirectory>src/test/flex</testSourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.sonatype.flexmojos</groupId>
                <artifactId>flexmojos-maven-plugin</artifactId>
                <version>3.5.0</version>
                <extensions>true</extensions>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>com.adobe.flex.framework</groupId>
            <artifactId>flex-framework</artifactId>
            <version>3.2.0.3958</version>
            <type>pom</type>
        </dependency>

        <dependency>
            <groupId>com.adobe.flexunit</groupId>
            <artifactId>flexunit</artifactId>
            <version>0.85</version>
            <type>swc</type>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <profiles>
        <profile>
            <id>m2e</id>
            <activation>
                <property>
                    <name>m2e.version</name>
                </property>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.maven.ide.eclipse</groupId>
                        <artifactId>lifecycle-mapping</artifactId>
                        <version>0.9.9-SNAPSHOT</version>
                        <configuration>
                            <mappingId>customizable</mappingId>
                            <configurators>
                                <configurator
                                     id='org.maven.ide.eclipse.configuration.flex.configurator' />
                            </configurators>
                            <mojoExecutions>
                                <mojoExecution>
                                    org.apache.maven.plugins:maven-resources-plugin::
                                </mojoExecution>
                            </mojoExecutions>
                        </configuration>
                    </plugin>
                </plugins>
                <pluginManagement>
                    <plugins>
                        <plugin>
                            <groupId>org.apache.maven.plugins</groupId>
                            <artifactId>maven-resources-plugin</artifactId>
                            <version>2.4</version>
                        </plugin>
                    </plugins>
                </pluginManagement>
            </build>
        </profile>
    </profiles>
</project>

Project Object Model for Flex Library Archetype is very simple, the key to this POM is the flexmojos-maven-plugin configuration which sets extensions to true. This configuration customizes the lifecycle for the swc packaging which is defined in the flexmojos-maven-plugin. The archetype then includes the flex-framework dependency and the flexmojos-unittest-support test-scoped dependency. The flex-framework dependency is a POM which contains references to the SWC libraries and resources required to compile Flex applications.

In Project Object Model for Flex Library Archetype, the packaging is very critical. A POMs packaging type controls the lifecycle it uses to produce build output. The value swc in the packaging element is Maven’s cue to look for the Flex-specific lifecycle customizations which are provided by the flexmojos-maven-plugin. The other important part of this POM is the build element which specifies the location of the Flex source code and the Flex unit tests. Next, let’s take a quick look at Flex Library Archetype’s Sample App Class which contains the sample Actionscript which was created by this archetype.

Flex Library Archetype’s Sample App Class. 

package org.sonatype.test {
  public class App {
    public static function greeting(name:String):String {
      return "Hello, " + name;
    }
  }
}

While this code is underwhelming, it does provide you with a quick model and a quick pointer: "Place More Code Here". While it might seem silly to test code this simple, a sample test named TestApp.as is provides in the src/test/flex directory. This test is shown in Unit Test for Library Archetype’s App Class.

Unit Test for Library Archetype’s App Class. 

package org.sonatype.test {

    import flexunit.framework.TestCase;

    public class TestApp extends TestCase {

        /**
         * Tests our greeting() method
         */
        public function testGreeting():void {
            var name:String = "Buck Rogers";
            var expectedGreeting:String = "Hello, Buck Rogers";

            var result:String = App.greeting(name);
            assertEquals("Greeting is incorrect", expectedGreeting, result);
        }
    }
}

To run this build, go to the sample-library project directory and run mvn install.

$ mvn install
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building sample-library Flex
[INFO]task-segment: [install]
[INFO] ------------------------------------------------------------------------
[INFO] [resources:resources]
[INFO] [flexmojos:compile-swc]
[INFO] flexmojos ${flexmojos.version} - GNU GPL License (NO WARRANTY) - \
See COPYRIGHT file
[WARNING] Nothing expecified to include.  Assuming source and resources folders.
[INFO] Flex compiler configurations:
-compiler.headless-server=false
-compiler.keep-all-type-selectors=false
-compiler.keep-generated-actionscript=false
-compiler.library-path ~/.m2/repository/com/adobe/flex/framework/flex/\
3.2.0.3958...
-compiler.namespaces.namespace http://www.adobe.com/2006/mxml
target/classes/configs/mxml-manifest.xml
-compiler.optimize=true
-compiler.source-path src/main/flex
...
[INFO] [resources:testResources]
[WARNING] Using platform encoding (MacRoman actually) to copy filtered \
resources, i.e.  build is platform dependent!
[INFO] skip non existing resourceDirectory src/test/resources
[INFO] [flexmojos:test-compile]
[INFO] flexmojos ${flexmojos.version} - GNU GPL License (NO WARRANTY) - \
See COPYRIGHT file
[INFO] Flex compiler configurations:
-compiler.include-libraries ~/.m2/repository/org/sonatype/flexmojos/\
flexmojos-unittest-support...
-compiler.keep-generated-actionscript=false
-compiler.library-path ~/.m2/repository/com/adobe/flex/framework/flex
3.2.0.3958/flex-3.2.0....
-compiler.optimize=true
-compiler.source-path src/main/flex target/test-classes src/test/flex
-compiler.strict=true
-target-player 9.0.0
-use-network=true
-verify-digests=true -load-config=
[INFO] Already trust on target/test-classes/TestRunner.swf
[INFO] [flexmojos:test-run]
[INFO] flexmojos ${flexmojos.version} - GNU GPL License (NO WARRANTY) - \
See COPYRIGHT file
[INFO] flexunit setup args: null
[INFO] ------------------------------------------------------------------------
[INFO] Tests run: 1, Failures: 0, Errors: 0, Time Elpased: 0 sec
[INFO] [install:install]
Note

To execute Flex unit tests you will need to configure your PATH environment variable to include the Flash Player. For more information about configuring FlexMojos for unit tests, see Section 13.2.3, “Configuring Environment to Support Flex Unit Tests”.

When you ran mvn install on this project, you should notice in the output that Maven and Flexmojos plugin is take care of managing all of the libraries and the dependencies for the Flex compiler. Much like Maven excels at helping Java developers manage the contents of a Java classpath, Maven can help Flex developers manage the complex of compile paths. You also might have been shocked when the Flexmojos project started a web browser or the Flash Player and used it to execute the TestApp.as class against the project’s source code.

13.3.2. Creating a Flex Application

To create a Flex application from a Maven archetype, execute the following command:

$ mvn archetype:generate \
      -DarchetypeRepository=http://repository.sonatype.org/content/groups/public\
      -DarchetypeGroupId=org.sonatype.flexmojos \
      -DarchetypeArtifactId=flexmojos-archetypes-application \
      -DarchetypeVersion=${flexmojos.version}
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] com.sonatype.maven.plugins: checking for updates from central
...
[INFO] [archetype:generate]
[INFO] Generating project in Interactive mode
[INFO] Archetype defined by properties
...
Define value for groupId: : +org.sonatype.test+
Define value for artifactId: : +sample-application+
Define value for version:  1.0-SNAPSHOT: : +1.0-SNAPSHOT+
Define value for package:  org.sonatype.test: : +org.sonatype.test+
Confirm properties configuration:
groupId: org.sonatype.test
artifactId: sample-library
version: 1.0-SNAPSHOT
package: org.sonatype.test
Y: : +Y+
[INFO] Parameter: groupId, Value: org.sonatype.test
[INFO] Parameter: packageName, Value: org.sonatype.test
[INFO] Parameter: basedir, Value: /Users/Tim/flex-sample
[INFO] Parameter: package, Value: org.sonatype.test
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: artifactId, Value: sample-application
[INFO] BUILD SUCCESSFUL

If you look in the directory sample-application/ you will see the filesystem shown in Figure 13.5, “Directory Structure for Flex Application Archetype”.

figs/web/flex-dev-arche-simple-app-fs.png

Figure 13.5. Directory Structure for Flex Application Archetype

Building an application from the Application archetype produces the following POM.

POM for Flex Application Archetype. 

<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>org.sonatype.test</groupId>
    <artifactId>sample-application</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>swf</packaging>

    <name>sample-application Flex</name>

    <build>
        <sourceDirectory>src/main/flex</sourceDirectory>
        <testSourceDirectory>src/test/flex</testSourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.sonatype.flexmojos</groupId>
                <artifactId>flexmojos-maven-plugin</artifactId>
                <version>3.5.0</version>
                <extensions>true</extensions>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>com.adobe.flex.framework</groupId>
            <artifactId>flex-framework</artifactId>
            <version>3.2.0.3958</version>
            <type>pom</type>
        </dependency>

        <dependency>
            <groupId>com.adobe.flexunit</groupId>
            <artifactId>flexunit</artifactId>
            <version>0.85</version>
            <type>swc</type>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <profiles>
        <profile>
            <id>m2e</id>
            <activation>
                <property>
                    <name>m2e.version</name>
                </property>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.maven.ide.eclipse</groupId>
                        <artifactId>lifecycle-mapping</artifactId>
                        <version>0.9.9-SNAPSHOT</version>
                        <configuration>
                            <mappingId>customizable</mappingId>
                            <configurators>
                                <configurator
                                     id='org.maven.ide.eclipse.configuration.flex.configurator' />
                            </configurators>
                            <mojoExecutions>
                                <mojoExecution>
                                    org.apache.maven.plugins:maven-resources-plugin::
                                </mojoExecution>
                            </mojoExecutions>
                        </configuration>
                    </plugin>
                </plugins>
                <pluginManagement>
                    <plugins>
                        <plugin>
                            <groupId>org.apache.maven.plugins</groupId>
                            <artifactId>maven-resources-plugin</artifactId>
                            <version>2.4</version>
                        </plugin>
                    </plugins>
                </pluginManagement>
            </build>
        </profile>
    </profiles>

</project>

The difference between POM for Flex Application Archetype and Project Object Model for Flex Library Archetype is that the packaging element is swf instead of swc. By setting the packaging to swf, the project will produce a Flex application in target/sample-application-1.0-SNAPSHOT.swf. The sample application created by this archetype displays the Text "Hello World". Main.mxml can be found in src/main/flex.

Sample Application Main.mxml. 

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:Text text="Hello World!"/>
</mx:Application>

This application also creates a simple FlexUnit test that does nothing more than print out a trace message. The sample unit test is in src/test/flex/org/sonatype/test.

Unit Test for Main.mxml. 

package org.sonatype.test
{

    import flexunit.framework.TestCase;
    import Main;

    public class TestApp extends TestCase
    {

        public function testNothing():void
        {
            //TODO un implemented
            trace("Hello test");
        }
    }
}

13.3.3. Creating a Multi-module Project: Web Application with a Flex

To create a multi-module project consisting of a Flex Library project referenced by a Flex Application, referenced by a Web Application.

$ mvn archetype:generate \
      -DarchetypeRepository=http://repository.sonatype.org/content/groups/public\
      -DarchetypeGroupId=org.sonatype.flexmojos \
      -DarchetypeArtifactId=flexmojos-archetypes-modular-webapp \
      -DarchetypeVersion=${flexmojos.version}
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] com.sonatype.maven.plugins: checking for updates from central
...
[INFO] [archetype:generate]
[INFO] Generating project in Interactive mode
[INFO] Archetype defined by properties
...
Define value for groupId: : +org.sonatype.test+
Define value for artifactId: : +sample-multimodule+
Define value for version:  1.0-SNAPSHOT: : +1.0-SNAPSHOT+
Define value for package:  org.sonatype.test: : +org.sonatype.test+
Confirm properties configuration:
groupId: org.sonatype.test
artifactId: sample-library
version: 1.0-SNAPSHOT
package: org.sonatype.test
Y: : +Y+
[INFO] Parameter: groupId, Value: org.sonatype.test
[INFO] Parameter: packageName, Value: org.sonatype.test
[INFO] Parameter: basedir, Value: /Users/Tim
[INFO] Parameter: package, Value: org.sonatype.test
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: artifactId, Value: sample-multimodule
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL

If you look in the sample-multimodule/ directory, you will see a directory structure which contains three projects swc, swf, and war.

figs/web/flex-dev-arche-multimodule-fs.png

Figure 13.6. Directory Structure for Flex Multimodule Archetype


The simple top-level POM in this multimodule project is shown in . It consists of module references to the swc, swf, and war modules.

Top-level POM Created by Modular Web Application Archetype. 

<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>org.sonatype.test</groupId>
    <artifactId>sample-multimodule</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <module>swc</module>
        <module>swf</module>
        <module>war</module>
    </modules>
</project>

The swc project has a simple POM that resembles the POM shown in Project Object Model for Flex Library Archetype. Note that the artifactId in this POM differs from the name of the module directory and is swc-swc.

swc Module POM. 

<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>org.sonatype.test</groupId>
        <artifactId>sample-multimodule</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <groupId>org.sonatype.test</groupId>
    <artifactId>swc</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>swc</packaging>

    <name>swc Library</name>

    <build>
        <sourceDirectory>src/main/flex</sourceDirectory>
        <testSourceDirectory>src/test/flex</testSourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.sonatype.flexmojos</groupId>
                <artifactId>flexmojos-maven-plugin</artifactId>
                <version>3.5.0</version>
                <extensions>true</extensions>
                <configuration>
                    <locales>
                        <locale>en_US</locale>
                    </locales>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>com.adobe.flex.framework</groupId>
            <artifactId>flex-framework</artifactId>
            <version>3.2.0.3958</version>
            <type>pom</type>
        </dependency>

        <dependency>
            <groupId>com.adobe.flexunit</groupId>
            <artifactId>flexunit</artifactId>
            <version>0.85</version>
            <type>swc</type>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <profiles>
        <profile>
            <id>m2e</id>
            <activation>
                <property>
                    <name>m2e.version</name>
                </property>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.maven.ide.eclipse</groupId>
                        <artifactId>lifecycle-mapping</artifactId>
                        <version>0.9.9-SNAPSHOT</version>
                        <configuration>
                            <mappingId>customizable</mappingId>
                            <configurators>
                                <configurator
                                     id="org.maven.ide.eclipse.configuration.flex.configurator" />
                            </configurators>
                            <mojoExecutions>
                                <mojoExecution>
                                    org.apache.maven.plugins:maven-resources-plugin::
                                </mojoExecution>
                            </mojoExecutions>
                        </configuration>
                    </plugin>
                </plugins>
                <pluginManagement>
                    <plugins>
                        <plugin>
                            <groupId>org.apache.maven.plugins</groupId>
                            <artifactId>maven-resources-plugin</artifactId>
                            <version>2.4</version>
                        </plugin>
                    </plugins>
                </pluginManagement>
            </build>
        </profile>
    </profiles>

</project>

The swf module’s POM resembles the POM in POM for Flex Application Archetype adding a dependency on the swc-swc artifact. Note that the following POM defines an artifactId that differs from the directory that stores the module; the artifactId in the following POM is swf-swf.

swf module POM. 

<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>org.sonatype.test</groupId>
        <artifactId>sample-multimodule</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <groupId>org.sonatype.test</groupId>
    <artifactId>swf</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>swf</packaging>

    <name>swf Application</name>

    <build>
        <sourceDirectory>src/main/flex</sourceDirectory>
        <testSourceDirectory>src/test/flex</testSourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.sonatype.flexmojos</groupId>
                <artifactId>flexmojos-maven-plugin</artifactId>
                <version>3.5.0</version>
                <extensions>true</extensions>
                <configuration>
                    <locales>
                        <locale>en_US</locale>
                    </locales>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>com.adobe.flex.framework</groupId>
            <artifactId>flex-framework</artifactId>
            <version>3.2.0.3958</version>
            <type>pom</type>
        </dependency>

        <dependency>
            <groupId>com.adobe.flexunit</groupId>
            <artifactId>flexunit</artifactId>
            <version>0.85</version>
            <type>swc</type>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.sonatype.test</groupId>
            <artifactId>swc</artifactId>
            <version>1.0-SNAPSHOT</version>
            <type>swc</type>
        </dependency>
    </dependencies>

    <profiles>
        <profile>
            <id>m2e</id>
            <activation>
                <property>
                    <name>m2e.version</name>
                </property>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.maven.ide.eclipse</groupId>
                        <artifactId>lifecycle-mapping</artifactId>
                        <version>0.9.9-SNAPSHOT</version>
                        <configuration>
                            <mappingId>customizable</mappingId>
                            <configurators>
                                <configurator
                                     id="org.maven.ide.eclipse.configuration.flex.configurator" />
                            </configurators>
                            <mojoExecutions>
                                <mojoExecution>
                                    org.apache.maven.plugins:maven-resources-plugin::
                                </mojoExecution>
                            </mojoExecutions>
                        </configuration>
                    </plugin>
                </plugins>
                <pluginManagement>
                    <plugins>
                        <plugin>
                            <groupId>org.apache.maven.plugins</groupId>
                            <artifactId>maven-resources-plugin</artifactId>
                            <version>2.4</version>
                        </plugin>
                    </plugins>
                </pluginManagement>
            </build>
        </profile>
    </profiles>

</project>

When you declare a dependency on a SWC, you’ll need to specify the type of the dependency so that Maven can locate the appropriate artifact in the remote or local repository. In this case, the swf-swf project depends upon the SWC that is generated by the swc-swc project. When you add the dependency to the swf-swf project, the FlexMojos plugin will add the appropriate SWC file to the Flex Compiler’s library path.

Next, take a look at the simple POM in the war module.

war module POM. 

<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>
        <artifactId>sample-multimodule</artifactId>
        <groupId>org.sonatype.test</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <groupId>org.sonatype.test</groupId>
    <artifactId>war</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>war</packaging>
    <build>
        <plugins>
            <plugin>
                <groupId>org.sonatype.flexmojos</groupId>
                <artifactId>flexmojos-maven-plugin</artifactId>
                <version>3.5.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>copy-flex-resources</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>maven-jetty-plugin</artifactId>
                <version>6.1.17</version>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>org.sonatype.test</groupId>
            <artifactId>swf</artifactId>
            <version>1.0-SNAPSHOT</version>
            <type>swf</type>
        </dependency>
    </dependencies>

</project>

The POM shown in war module POM configures the FlexMojos plugin to execute the copy-flex-resources goal for this project. The copy-flex-resources goal will copy SWF application into the web application’s document root. In this project, running a build and creating a WAR will copy the swf-swf-1.0-SNAPSHOT.swf file to the web application’s root directory in target/war-war-1.0-SNAPSHOT.

To build the multimodule web application project, run mvn install from the top-level directory. This should build the swc-swc, swf-swf, and war-war artifacts and product a WAR file in war'/target/war-war-1.0-SNAPSHOT.war' which contains the swf-swf-1.0-SNAPSHOT.swf in the document root of the web application.

Note

To execute Flex unit tests you will need to configure your PATH environment variable to include the Flash Player. For more information about configuring FlexMojos for unit tests, see Section 13.2.3, “Configuring Environment to Support Flex Unit Tests”.

13.4. The FlexMojos Lifecycle

The FlexMojos Maven plugin customizes the lifecycle based on the packaging. If your project has a packaging of type swc or swf, the FlexMojos plugin with execute a customized lifecycle if your plugin configuration sets the extensions to true. Setting Plugin Extensions to True for Custom Flex Lifecycle shows the plugin configuration for the flexmojos-maven-plugin with the extensions set to true.

Setting Plugin Extensions to True for Custom Flex Lifecycle. 

<build>
    <sourceDirectory>src/main/flex</sourceDirectory>
    <testSourceDirectory>src/test/flex</testSourceDirectory>
    <plugins>
        <plugin>
            <groupId>org.sonatype.flexmojos</groupId>
            <artifactId>flexmojos-maven-plugin</artifactId>
            <version>${flexmojos.version}</version>
            *<extensions>true</extensions>*
            <configuration>
                <locales>
                    <locale>en_US</locale>
                </locales>
            </configuration>
        </plugin>
    </plugins>
</build>

13.4.1. The SWC Lifecycle

When the packaging is swc, FlexMojos will execute the lifecycle shown in Figure 13.7, “The FlexMojos SWC Lifecycle”. The highlighted goals are goals from the FlexMojos plugin, the goals which are not highlights are standard goals from the Core Maven plugins.

figs/web/flex-dev_swc-lifecycle.png

Figure 13.7. The FlexMojos SWC Lifecycle

The FlexMojos contributed goals are:

flexmojos:compile-swc

This goal compiles all of the Actionscript and MXML files in the sourceDirectory into a SWC. A SWC is an Adobe library or class file which contains components and resources used in Flex applications.

flexmojos:test-compile

This goal compiles all of the Actionscript and MXML files in the testSourceDirectory.

flexmojos:test-run

This goal executes unit tests using the Flash Player. This goal can only run if the Flash Player has been configured as described in Section 13.2.3, “Configuring Environment to Support Flex Unit Tests”.

13.4.2. The SWF Lifecycle

When the packaging is swf, FlexMojos will execute the lifecycle shown in Figure 13.8, “The FlexMojos SWF Lifecycle”. The highlighted goals are goals from the FlexMojos plugin, the goals which are not highlights are standard goals from the Core Maven plugins.

figs/web/flex-dev_swf-lifecycle.png

Figure 13.8. The FlexMojos SWF Lifecycle

The FlexMojos contributed goals are:

flexmojos:compile-swf

This goal compiles all of the Actionscript and MXML files in the sourceDirectory into a SWF. A SWF is a file which contains an application that can be render by the Adobe Flash Player or Adobe AIR software.

flexmojos:test-compile

This goal compiles all of the Actionscript and MXML files in the testSourceDirectory.

flexmojos:test-run

This goal executes unit tests using the Flash Player. This goal can only run if the Flash Player has been configured as described in Section 13.2.3, “Configuring Environment to Support Flex Unit Tests”.

13.5. FlexMojos Plugin Goals

The FlexMojos Maven Plugin contains the following goals:

flexmojos:asdoc

Generates documentation for Actionscript source files

flexmojos:asdoc-report

Generates documentation for Actionscript sources as a report that can be included in a Maven site

flexmojos:compile-swc

Compiles Flex source (Actionscript and MXML) into a SWC library for use in a Flex or AIR application

flexmojos:compile-swf

Compiles Flex source (Actionscript and MXML) into a SWF for use in the Adobe Flash Player or Adobe AIR Runtime

flexmojos:copy-flex-resources

Copies Flex resources into a web application project

flexmojos:flexbuilder

Generates project files for use in Adobe Flex Builder

flexmojos:generate

Generates Actionscript 3 based on Java classes using Granite GAS3

flexmojos:optimize

Goal which run post-link SWF optimization on swc files. This goal is used to produce RSL files.

flexmojos:sources

Create a JAR which contains all the sources for a Flex project

flexmojos:test-compile

Compile all test classes in a Flex project

flexmojos:test-run

Run the tests using the Adobe Flash Player

flexmojos:test-swc

Build a SWC containing the test classes for a specific project

flexmojos:wrapper

Generate an HTML wrapper for a SWF application

13.5.1. Generating Actionscript Documentation

You can run the asdoc or asdoc-report goals to generate documentation for Actionscript. Once the goals has completed, the documentation will be saved to ${basedir}/target/asdoc as HTML. Figure 13.9, “Actionscript Documentation Generated by the FlexMojos Plugin” shows the result of running the asdoc goal against the Flexmojos application archetype project.

figs/web/flex-dev_asdoc-browser.png

Figure 13.9. Actionscript Documentation Generated by the FlexMojos Plugin

13.5.2. Compiling Flex Source

FlexMojos contains a number of goals which compile Actionscript and MXML into SWCs and SWFs. The compile-swc and compile-swf goals are used to generate output from a project’s source, and test-compile is used to compile unit tests. In the simple projects created by the FlexMojos archetypes, the compile-swc and compile-swf goals are called because the project customizes the lifecycle and binds either compile-swc or compile-swf to the compile phase and test-compile to the test-compile phase. If you need to configure the options for the FlexMojos compiler, you would configure the FlexMojos plugin configuration. For example, if you wanted the application with the POM shown in POM for Flex Application Archetype to ignore certain code-level warnings on compile and use some customized font settings, you might use the plugin configuration shown in Customizing the Compiler Plugin.

Customizing the Compiler Plugin. 

<build>
    <sourceDirectory>src/main/flex</sourceDirectory>
    <testSourceDirectory>src/test/flex</testSourceDirectory>
    <plugins>
        <plugin>
            <groupId>org.sonatype.flexmojos</groupId>
            <artifactId>flexmojos-maven-plugin</artifactId>
            <version>${flexmojos.version}</version>
            <extensions>true</extensions>
            <configuration>
                <configurationReport>true</configurationReport>
                <warnings>
                    <arrayTostringChanges>true</arrayTostringChanges>
                    <duplicateArgumentNames>false</duplicateArgumentNames>
                </warnings>
                <fonts>
                    <advancedAntiAliasing>true</advancedAntiAliasing>
                    <flashType>true</flashType>
                    <languages>
                        <englishRange>U+0020-U+007E</englishRange>
                    </languages>
                    <localFontsSnapshot>
                        ${basedir}/src/main/resources/fonts.ser
                    </localFontsSnapshot>
                    <managers>
                        <manager>flash.fonts.BatikFontManager</manager>
                    </managers>
                    <maxCachedFonts>20</maxCachedFonts>
                    <maxGlyphsPerFace>1000</maxGlyphsPerFace>
                </fonts>
            </configuration>
        </plugin>
    </plugins>
</build>

13.5.3. Generating Flex Builder Project Files

To generate Flex Builder project files for a FlexMojos project, configure the plugin groups as described in Section 13.2.4, “Adding FlexMojos to Your Maven Settings' Plugin Groups”, and run the flexbuilder goal:

$ mvn flexmojos:flexbuilder

Running this goal will create a .project, .settings/org.eclipse.core.resources.prefs, .actionScriptProperties, and .flexLibProperties.

13.6. FlexMojos Plugin Reports

The FlexMojos Maven Plugin contains the following report:

flexmojos:asdoc-report

Generates documentation for Actionscript sources as a report that can be included in a Maven site

13.6.1. Generating Actionscript Documentation Report

To generate the asdoc-report as part of your Maven site build, add the following XML to your POM:

Configuring the Actionscript Documentation Report. 

<reporting>
    <plugins>
        <plugin>
            <groupId>org.sonatype.flexmojos</groupId>
            <artifactId>flexmojos-maven-plugin</artifactId>
            <version>${flexmojos.version}</version>
            <reportSets>
                <reportSet>
                    <id>flex-reports</id>
                    <reports>
                        <report>asdoc-report</report>
                    </reports>
                </reportSet>
            </reportSets>
        </plugin>
    </plugins>
</reporting>

When you run mvn site, Maven will generate this report and place the results under the "Project Reports" menu as shown in Figure 13.10, “Actionscript Documentation Report on Maven Site”.

figs/web/flex-dev_asdocs-report.png

Figure 13.10. Actionscript Documentation Report on Maven Site


If you need to pass in any configuration options to the asdoc-report, you will need add a configuration element to the reportSets element as shown in Configuring the asdoc-report.

Configuring the asdoc-report. 

<reporting>
    <plugins>
        <plugin>
            <groupId>org.sonatype.flexmojos</groupId>
            <artifactId>flexmojos-maven-plugin</artifactId>
            <version>${flexmojos.version}</version>
            <reportSets>
                <reportSet>
                    <id>flex-reports</id>
                    <reports>
                        <report>asdoc-report</report>
                    </reports>
                    <configuration>
                        <windowTitle>My TEST API Doc</windowTitle>
                        <footer>Copyright 2010 Sonatype</footer>
                    </configuration>
                </reportSet>
            </reportSets>
        </plugin>
    </plugins>
</reporting>

13.7. Developing and Customizing Flexmojos

The following sections guide you through some of first steps toward customizing or contributing to the Flexmojos project. Flexmojos is more than just a tool for people who are interested in compiling Actionscript into SWF and SWC artifacts, it is a community of developers. This section isn’t for everyone, but, if you have an itch to scratch and you wish to participate, come on in.

13.7.1. Get the Flexmojos Source Code

Flexmojos is an open source project hosted on the Sonatype Forge, and the source code for Flexmojos is stored in the Sonatype Forge Subversion repository. You can browse the contents of the Flexmojos Subversion repository by opening https://github.com/velo/flexmojos in a web browser.

figs/web/flex-dev-subversion.png

Figure 13.11. Flexmojos Subversion Repository


If you are interested in participating in the Flexmojos project, you will likely want to checkout the current Flexmojos source code to your local machine. To checkout the Flexmojos source using Subversion, execute the following command at the command line:

$ svn co http://svn.sonatype.org/flexmojos/trunk flexmojos
A flexmojos
...
$ ls
COPYRIGHT   flexmojos-sandbox pom.xml
flexmojos-archetypesflexmojos-super-poms  src
flexmojos-maven-plugin  flexmojos-testing
flexmojos-parentflexmojos-touchstone