Prerequisite knowledge
Intermediate to advanced Flex knowledge
Additional required other products 
Flexmojos 4.0-RC2 (listing of all goals and configuration settings)
User level
Required products
Flash Builder (Download trial)
Sample files
View examples
This is the final article in a three-part series on Flex, Maven, and Flexmojos. Building on the introduction to Maven and Flexmojos in Part 1, Part 2 covered setting up a project, finding dependencies, customizing Flexmojos, unit testing, and adding additional projects to your build. This article covers Flash compilation and linkages, dependency scope, RSL support, WAR packaging, build profiles and the ASDoc goal. By the end of this article you should have all the tools you need to manage your enterprise project with Maven and Flexmojos.
Note: I previously mentioned this article would also cover Nexus, the repository management software from Sonatype. In order to reduce the size of this tutorial, I've opted to put the Nexus material into its own article (to come).

A closer look at Flash Platform compilation

A proper discussion on producing fully fledged SWFs and SWCs cannot proceed without a quick refresher of the Flash Platform compilers and artifacts.
There are two primary command line compilers for the Flash Platform (Flex, AIR, and ActionScript 3 projects all use these).
  • mxmlc is the application (SWF) compiler
  • compc is the component (SWC) compiler
Note: The mxmlc compiler and the compc compiler generally take the same settings but there are a few that only work with one or the other; see the documentation for more details.
Compiler file types
The compilers can produce a variety of file types:
  • A SWF is a compiled Flash Platform artifact.
  • A SWC, like a JAR, is simply a compressed file. You can open it as a ZIP file and see that it has both a catalog.xml and a library.swf. In catalog.xml, you can see the version of the Flex SDK it was compiled against (yes, even if it is pure ActionScript 3 project), along with a listing of all the definitions within.
  • An RSL is a downloadable SWF version of a library (SWC) that is stored in the user's browser cache, preventing multiple downloads of the same definitions.
  • A SWZ is a signed RSL (a signed SWF), created solely by Adobe, used to ensure downloaded RSLs are trusted Adobe content.
Note: In Flash Builder, when you add a SWC as a dependency to an application and set the linkage to RSL, the IDE will automatically deploy the library.swf from the SWC into your bin-debug folder for runtime loading.
Library linkage
Flash Builder provides three types of linkages for building projects with dependencies (see Figure 1):
  • Merged Into Code. This bundles in all classes from the library that are used in the project. It corresponds to the library-path option of mxmlc and compc .
  • External. This compiles the SWF or SWC against the classes from the library for linkage but does not add them into the resulting file. It corresponds to the external-library-path compiler option.
  • Runtime Shared Library. Relevant only for Flex and AIR Applications (not SWCs or ActionScript 3 projects), this ensures that the library referenced by the SWF will be loaded once into the user's Flash Player cache at runtime. This is enabled by default on Flex projects for the framework dependencies (you can use static-link-runtime-shared-libraries on mxmlc to disable it).
Note: By default, Flash Builder configures Flex Library projects (SWCs) to use external linkage for its Flex framework dependencies and Flex Applications (SWFs) use RSLs. ActionScript projects use a smaller subset of the framework, and can use only merged linkage (as RSL support is part of the Flex SDK). All other libraries linked to a SWF are linked as merged by default.
Figure 1. Library linkage in Flash Builder.
Figure 1. Library linkage in Flash Builder.

For more information on RSLs, see Introduction to RSLs in the Flex 4.5 documentation.

Dependency scope

Dependencies you list in a Maven project may themselves have dependencies; such dependencies are called transitive. When you install a third-party dependency into your local repository, Maven creates a POM for the artifact, which simply states its groupId, artifactId , and version (GAV) parameters along with the packaging . If, however, your dependency is built via a Maven POM and contains dependencies, then your project will transitively depend on these also.
For example, the flex-framework POM (created by Marvin Froeder as a convenience), which you compile against when building a Flex project, is simply a POM itself. It depends on another POM that contains all the SWCs you expect for Flex projects. As such, each dependency you add to a project can potentially expand the dependency tree significantly.
You can show the dependency tree of any POM by executing the following goal at the project level:
mvn dependency:tree
To prevent unwanted dependencies at various stages in the build, you can limit the scope of the dependency. Here, scope refers to the context in which the dependency is relevant. An example is a unit testing dependency. Recall from Part 2, I created dependency on FlexUnit4, and I limited it to the unit testing compilation phase by setting its scope:
<dependency> <groupId>com.adobe.flexunit</groupId> <artifactId>flexunit</artifactId> <version>4.1.0-8</version> <type>swc</type> <scope>test</scope> </dependency>
Scope options in Flexmojos
For Flex projects there is only one scope option that really limits the dependency to a phase in the build: test . You can also specify theme , which allows you to explicitly state that the dependency should be fed to mxmlc as the theme option, but this is often unnecessary as Flexmojos infers your theme (typically Spark or Halo) from the project.
The remaining five scope options correspond to the various framework linkages that Flex allows between a SWF or SWC and its library dependencies. The five are:
  • merged: In POMs with SWF packaging, this is the default scope on dependencies. Just like the compiler library-path option, this technique only compiles in the classes that are used by the project. This corresponds to the Merged Into Code library linkage option within Flash Builder.
  • internal: This compiles in all dependencies into the target project, regardless of whether or not they are used. It corresponds to the include-libraries compiler option. It can be used to bundle dependencies together (in an altogether un-Maven like way).
  • external: In POMs with SWC packaging, this is the default scope on dependencies. It compiles against, but does not include any definitions from the dependency, assuming they will exist at runtime. It corresponds to the external-library-path compiler option. For example, playerglobal.swc is linked as external as it lives within each install of the Flash Player plug-in. This scope equates to the External linkage in Flash Builder. Typically used for SWCs, you may on occasion also require this in runtime modules (SWFs) to compile against definitions expected to already be bundled into the application SWF.
  • rsl: Relevant only to SWFs, the compiled artifact will have a reference to download the RSL dependency at runtime. This corresponds to the runtime-shared-library-path compiler option, and the RSL option in Flash Builder (more information below).
  • caching: This is similar to rsl, however the compiled project will be linked to the Adobe SWZ files. That is, the signed framework RSLs.
Just like the normal scope, these can be appended to a dependency as usual. For example, if you wanted to compile your library (a SWC) against a dependency and wanted the classes used to be bundled in (instead of the SWC default of external), then you could use the merged scope:
<packaging>swc</packaging> . . . <dependency> <groupId>org.robotlegs</groupId> <artifactId>robotlegs-framework</artifactId> <version>1.5.1</version> <type>swc</type> <scope>merged</scope> </dependency>
Note: When using merged, external, internal, rsl or caching scope be aware that Maven does not support custom scopes and as such often warns about using those provided by Flexmojos. These warnings can be ignored with direct dependencies as Flexmojos overrides them. Transitive dependencies on the other hand, render Flexmojos powerless as Maven provides these dependencies to it, ignoring custom scope. As such you may experience unexpected outcomes when one of your project's dependencies has a dependency with one of the custom scopes. The solution is to define these transitive dependencies in your project directly and specify the scope corresponding to the linkage you require.

RSL of the Flex framework

By default, both Flash Builder and mxmlc use RSL linkage for the Flex framework. In Flexmojos, you typically include the Flex framework in a SWF project as follows:
<dependency> <groupId>com.adobe.flex.framework</groupId> <artifactId>flex-framework</artifactId> <version></version> <type>pom</type> </dependency>
When you do, then you've effectively used merged scope (assuming the packaging is SWF) and you'll notice the generated artifact has bundled in the Flex framework definitions it requires. If you compile any of my first few example projects from GitHub, you may notice that the produced SWF is quite large. That is because all used Flex components and dependencies are bundled in.
If you want to download the Flex framework as a collection of RSLs, a little more work is required.
First, you need to list the individual Flex framework dependencies. Typically, you create a dependency on the Flex framework using the XML snippet above. The flex-framework POM depends on the common-framework POM, which individually lists all possible Flex dependencies you could need, along with the resource bundles (*.rb.swc).
From these, you can take a subset of the dependencies and set the scope to caching . However, due to the nature of the Flex compiler, the order of RSLs is of the utmost importance. As such, it makes sense to use the order of dependencies shown in Flash Builder (see Figure 2).
Figure 2. The order of Flex framework RSLs.
Figure 2. The order of Flex framework RSLs.

Start with that ordering, and ignore playerglobal.swc, authoringsupport.swc, flash-integration.swc and the locales (none of which have RSL definitions, as can be seen if you expand the details next to the dependency). Then cross reference to the common-framework POM, to get the XML you need.
To follow along, see the FrameworkRSLs project in GitHub. Here, in the correct order, is the entire list of framework SWZ dependencies:
<properties><flex.sdk.version></flex.sdk.version></properties> . . . <dependency> <groupId>com.adobe.flex.framework</groupId> <artifactId>framework</artifactId> <version>${flex.sdk.version}</version> <type>swc</type> <scope>caching</scope> </dependency> <dependency> <groupId>com.adobe.flex.framework</groupId> <artifactId>textLayout</artifactId> <version>${flex.sdk.version}</version> <type>swc</type> <scope>caching</scope> </dependency> <dependency> <groupId>com.adobe.flex.framework</groupId> <artifactId>spark</artifactId> <version>${flex.sdk.version}</version> <type>swc</type> <scope>caching</scope> </dependency> <dependency> <groupId>com.adobe.flex.framework</groupId> <artifactId>sparkskins</artifactId> <version>${flex.sdk.version}</version> <type>swc</type> <scope>caching</scope> </dependency> <dependency> <groupId>com.adobe.flex.framework</groupId> <artifactId>rpc</artifactId> <version>${flex.sdk.version}</version> <type>swc</type> <scope>caching</scope> </dependency> <dependency> <groupId>com.adobe.flex.framework</groupId> <artifactId>charts</artifactId> <version>${flex.sdk.version}</version> <type>swc</type> <scope>caching</scope> </dependency> <dependency> <groupId>com.adobe.flex.framework</groupId> <artifactId>spark_dmv</artifactId> <version>${flex.sdk.version}</version> <type>swc</type> <scope>caching</scope> </dependency> <dependency> <groupId>com.adobe.flex.framework</groupId> <artifactId>osmf</artifactId> <version>${flex.sdk.version}</version> <type>swc</type> <scope>caching</scope> </dependency> <dependency> <groupId>com.adobe.flex.framework</groupId> <artifactId>mx</artifactId> <version>${flex.sdk.version}</version> <type>swc</type> <scope>caching</scope> </dependency> <dependency> <groupId>com.adobe.flex.framework</groupId> <artifactId>advancedgrids</artifactId> <version>${flex.sdk.version}</version> <type>swc</type> <scope>caching</scope> </dependency> <dependency> <groupId>com.adobe.flex.framework</groupId> <artifactId>flex-framework</artifactId> <version>${flex.sdk.version}</version> <type>pom</type> </dependency>
Note: The final POM dependency must be defined after the RSLs. Maven uses dependency mediation based on the premise that the first declaration wins, so putting it at the end ensures that the caching scoped dependencies will take precedence.
Now when I build my project, Flexmojos will work out what RSLs are required by my application based on usage. For example, here are my GitHub project outputs:
[INFO] Required RSLs: [INFO] /rsl/framework- [INFO] /rsl/spark- [INFO] /rsl/textLayout-
Note: By default, Flexmojos uses the following RSL pattern: rsls/{artifactId}-{version}.{extension}. You can customize this via the <rslUrls> configuration parameter.
Now, if you try to execute a SWF with just those dependencies, you'll see Flash Player report something like:
Error #2032: Stream Error. URL: file:///rsl/framework-
Of course, this is because the RSLs themselves haven't been deployed alongside the SWFs.
So where do these dependencies come from? Well, I could use WAR packaging in Flexmojos and have them copied for me into the WAR's target (I cover that below). Alternatively, I can reference the live versions from Adobe. I can find the precise URLs of the RSLs and versions in Flash Builder via the Properties dialog box by choosing Project > Properties and selecting Flex Build Path on any Flex Application project (see Figure 3).
Figure 3. Expanded framework RSL details.
Figure 3. Expanded framework RSL details.

In Flash Builder, you can see that all the dependencies use the same policy file: . However, if you look closely, you'll notice two of the dependencies (osmf and the textLayout framework) use different versions and slightly different URLs.
Most of the Flex framework dependencies look like the following spark example:
This example is in the following format:{extension}/flex/${flex.sdk.version}/{artifactId}_{version}.{extension}
However, textLayout has a different URL and version, so it requires:
This is in the following format:{extension}/tlf/${flex.tlf.version}/{artifactId}_${flex.tlf.version}.{extension}
Finally, osmf is a kind of hybrid due to its versioning:
Its format is:{extension}/flex/${flex.sdk.version}/{artifactId}_${flex.osmf.version}.{extension}
If you add the following Flexmojos configuration (as in the GitHub project), then you can run the SWF directly from the target folder:
<properties> <flex.sdk.version></flex.sdk.version> <flex.tlf.version></flex.tlf.version> <flex.osmf.version></flex.osmf.version> </properties> . . . <configuration> <policyFileUrls> <!--- cross domain policy for each RSL entry --> <url></url> <url></url> <url></url> </policyFileUrls> <rslUrls> <url>{extension}/flex/${flex.sdk.version}/{artifactId}_{version}.{extension}</url> <url>{extension}/tlf/${flex.tlf.version}/{artifactId}_${flex.tlf.version}.{extension}</url> <url>{extension}/flex/${flex.sdk.version}/{artifactId}_${flex.osmf.version}.{extension}</url> </rslUrls> </configuration>
For general information about using the framework as RSLs, see Using the framework RSLs in the Flex 4.5 documentation.

Runtime Flex modules

Flexmojos offers two alternative ways to compile and deploy Flex modules. To follow along with examples of these mechanisms, see the FlexModules project in GitHub.
Option 1: Within the application POM
The first way is simple, and it involves using the modules parameter in the compile-swf goal.
Basically, it requires hosting all of my Flex modules within the same location as my main application SWF and listing them individually within one POM.
Within the configuration, I can add the following parameter:
<modules> <module> <sourceFile>MyModule.mxml</sourceFile> <optimize>true</optimize> <finalName>MyModule</finalName> </module> </modules>
Note: The optimization parameter, is just like its counterpart in Flash Builder. It ensures that definitions within the loading application are not repeated in the module.
Now when the application builds, the module will be built alongside it, and renamed to the easy-to-use MyModule.swf so I can simply load the module in my application via:
<s:ModuleLoader url=”MyModule.swf” />
To see this in action, check the application subproject within GitHub.
Option 2: One POM per module
The second option requires a little more effort. However, you gain the ability to customize the module more precisely. It is also a more Maven-friendly approach as it conforms to the one-artifact-per-POM mantra; the technique used in the previous option breaks that convention.
To use this second option, simply create a POM with SWF packaging and set the sourceFile parameter to the module file, as you would with a normal application; for example:
<configuration> <sourceFile>MyModule.mxml</sourceFile> </configuration>
To see this in action, explore the module subproject within GitHub. In my example, I also set the finalName parameter so I know how to find the module within my ModuleLoader class ( finalName is only the name of the artifact in the target folder, it doesn't affect the artifact name within your repository).
The advantage of having a POM for each Flex module is it lets you specify nuances between the module and each of its dependencies, which is a real factor in production. You may want a specific SWC dependency for one module alone; using this technique you can include it in just the module and prevent its inclusion in your parent application.
To build the module and prevent it from bundling in dependencies already present in the application (as though it is optimized), you can use the link report produced by the application as a dependency. This is similar to compiling the module via mxmlc with the load-externs compiler option.
There are two steps to this. First, you need to configure the application so that its link report is added to our repository. This can be done with the following setting:
Next, the module needs to have a dependency on that link report, which lets Flexmojos enable the load-externs mxmlc option. Because this project uses POM inheritance (covered in Part 2), I can use the convenient project variables; for example:
<dependency> <groupId>${project.groupId}</groupId> <artifactId>application</artifactId> <version>${project.version}</version> <type>xml</type> <classifier>link-report</classifier> </dependency>
Effectively, this module is now optimized for the application, just as it would if I had enabled that feature within Flash Builder.
Note: In practice, you will likely want to deploy modules into the same folder (or a subfolder) as the application itself. The WAR packaging can do this for you, for more information, see the section on Additional features below.

Maven profiles

Maven provides profile support to help you handle situations in which you want to customize different types of builds within one POM. A profile enables you to customize the execution based on environmental features, properties, or file existence.
To see this in action on a Flex project, see my Profiles project in GitHub.
What you can customize
The simplest profile will just alter properties in the POM. For example, toggling between Flex 4.1 and Flex 4.5 would entail the following:
<profiles> <profile> <id>flex4.1</id> <properties> <flex.sdk.version></flex.sdk.version> </properties> </profile> <profile> <id>flex4.5</id> <properties> <flex.sdk.version></flex.sdk.version> </properties> </profile> </profiles>
If I want to get a bit more intimate with the Flexmojos configuration, then I can do that too. Consider the following Flexmojos code coverage configuration:
. . . <configuration> <coverage>true</coverage> <coverageReportFormat> <param>html</param> </coverageReportFormat> </configuration> . . .
I could override this with a profile (for my build server for example) that would output XML reports instead; for example:
<profile> <id>xml-coverage</id> <build> <plugins> <plugin> <groupId>org.sonatype.flexmojos</groupId> <artifactId>flexmojos-maven-plugin</artifactId> <configuration> <coverageReportFormat> <param>xml</param> </coverageReportFormat> </configuration> </plugin> </plugins> </build> </profile>
In this case, I have to replicate the configuration as it appears in my POM, hence the build / plugins / plugin reference to Flexmojos.
Note: The coverageReportFormat parameter is of type List in the Flexmojos plug-in docs, so you need to use <param> for each list entry.
Profile activation
The following list describes the various methods of profile activation in decreasing order of precedence:
  1. First, you can enable (or disable with ! ) profiles via the command line using the –P option; for example: mvn clean install –P flex4.1,debug,!coverage
  2. Second, you can activate a collection of profiles via the <activeProfiles> parameter within a settings file.
  3. Third, you can enable the activation based on property settings or the environment.
For example, you can enable by the value of a property:
<profile> <activation> <property> <name>flex.sdk.version</name> <value></value> </property> </activation> . . . </profile>
Or you could enable by the presence (or absence via !) of the Windows OS using the following:
<activation> <os> <family>windows</family> </os> </activation>
You can also enable by the presence (or absence via <missing> ) of a file:
<activation> <file> <exists>/usr/local/bin/flashplayer</exists> </file> </activation>
Note: Maven currently (3.0.3 at time of writing) does not support multiple activations for one profile.
  1. Fourth, you can configure a profile to enable by default via <activeByDefault>true</activeByDefault>.
Keep in mind that any profiles enabled by default will automatically be disabled when any profile is activated by any of the other techniques listed above. For that reason, activeByDefault is best used sparingly.
Note: If you want to see which profiles were applied, you can append the help:active-profiles goal; for example: mvn clean install –P flex4.1 help:active-profiles
For more information on Maven profiles, see Introduction to Build Profiles in the Apache Maven documentation.

Additional features

Documentation, WAR packages, and custom RSLs call all be generated with Flexmojos.
Flexmojos can be configured to output ASDocs from your code. To activate this feature, simply run:
mvn flexmojos:asdoc
Alternatively, you can append the goal to the default lifecycle simply by adding it as an additional goal to the build. (See my ASDoc example in GitHub).
<build> <plugins> <plugin> <groupId>org.sonatype.flexmojos</groupId> <artifactId>flexmojos-maven-plugin</artifactId> <executions> <execution> <goals> <goal>asdoc</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
That way, every time you run mvn clean install , the ASDocs will also be generated. You could also create a profile that enables this feature for you.
For the full details on the goal, see flexmojos:asdoc in the Flexmojos plug-in documentation.
WAR packaging
Flexmojos is also compatible with WAR packaging. This means you can export your Flex artifacts into a WAR file for web deployment. A part of this is the copy-flex-resources goal which bundles SWFs, locales, and RSLs into the final WAR.
To execute this goal, you create another Maven module with packaging as war , append the copy-flex-resources goal to the plug-in, and add dependencies of each SWF you want included in the final WAR. To bind extra goals to the default lifecycle, I use the <execution> setting within the plugin itself; for example:
<packaging>war</packaging> . . . <build> <plugins> <plugin> <groupId>org.sonatype.flexmojos</groupId> <artifactId>flexmojos-maven-plugin</artifactId> <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>${project.groupId}</groupId> <artifactId>application</artifactId> <version>${project.version}</version> <type>swf</type> </dependency> <dependency> <groupId>${project.groupId}</groupId> <artifactId>module</artifactId> <version>${project.version}</version> <type>swf</type> </dependency> </dependencies>
To explore the entire project, see the WARPackaging example on GitHub and this POM in particular.
Note: There is also a goal to create an HTML wrapper, however I've personally had mixed results using it. For more information on the wrapper goal, see this note on Html Wrapper Mojo.
Custom RSLs
In addition, Flexmojos can generate RSLs for your project.
The first step is to generate a SWF from the SWC. To create RSLs from your SWC libraries, you can simply append the create-rsl goal to the execution; for example:
<packaging>swc</packaging> . . . <build> <plugins> <plugin> <groupId>org.sonatype.flexmojos</groupId> <artifactId>flexmojos-maven-plugin</artifactId> <executions> <execution> <goals> <goal>create-rsl</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
(See this POM for the complete example.)
This creates both the SWC and the SWF needed for the RSL, installing both in the local repository.
Alternatively, if the dependency is a third-party SWC you already downloaded, you can extract the library.swf from the SWC and install that in your local repository as a SWF.
Note: In production environments you should consider using optimized SWFs where possible. This may involve running Apparat or some similar tool on the SWF.
The next step is to add this RSL dependency to your project. For example, both an internal dependency and a third-party dependency may look like this:
<dependency> <groupId>${project.groupId}</groupId> <artifactId>library</artifactId> <version>${project.version}</version> <type>swc</type> <scope>rsl</scope> </dependency> <dependency> <groupId>org.robotlegs</groupId> <artifactId>robotlegs-framework</artifactId> <version>1.5.1</version> <type>swc</type> <scope>rsl</scope> </dependency>
(See this POM for the complete example.)
Note: You use the SWC type on the dependency even though in the final form, the application will look for a SWF. Flexmojos will work that out for you.
You specify the RSL deployment for these files as follows:
<configuration> <rslUrls> <rsl>rsl/{artifactId}-{version}.{extension}</rsl> </rslUrls> </configuration>
Flexmojos knows to build this SWF with RSL dependencies and as such lists them for you:
[INFO] Required RSLs: [INFO] rsl/library-1.0.0-SNAPSHOT.swf [INFO] rsl/robotlegs-framework-1.5.1.swf
Finally, if you want these deployed along with you application, you can simply use another Maven module with WAR packaging and employ the copy-flex-resources goal to place the RSLs (see Figure 4).
Figure 4. Custom RSL deployment.
Figure 4. Custom RSL deployment.

Where to go from here

There you have it—a thorough guide to Flex and Maven through the Flexmojos plug-in. You can use any of the resources below for extra help, including assistance with both AIR and ActionScript 3 projects.
Remember, with great power comes great responsibility, and Maven is certainly powerful. The conventions are in place to ensure that everything works with as little plumbing as possible. Disregard those conventions at your peril—you can't expect much help from Maven if things don't turn out as expected. Always remember to keep your configuration as trim as possible. Less is more when it comes to managing your scripts.
Once tamed, Maven is a tool you'll be glad to have in your toolbox. And, now that Adobe has announced that they are looking to support Maven in Flex and Flash Builder, it is only a matter of time before it is part-and-parcel of the Flash Platform world.
Here are some useful resources: