Wednesday, April 28, 2010

Building Flex 4 AIR application with flex-mojos (Maven)

After spending a number of hours trying to get my Flex 4 AIR application to successfully build with the maven flex-mojos plugin, I was finally able to create a pom.xml file that worked. There are a few gotchas to deal with which are detailed below. First of all here is the working pom.xml

<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.mcgraphix.xd</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<name>my-app Flex</name>
<properties>
<flex.framework.version>4.0.0.14159</flex.framework.version>
<sourceDir>src/main/flex</sourceDir>
</properties>
<packaging>swf</packaging>
<build>
<sourceDirectory>src/main/flex</sourceDirectory>
<plugins>
<plugin>
<groupId>org.sonatype.flexmojos</groupId>
<artifactId>flexmojos-maven-plugin</artifactId>
<version>3.7-SNAPSHOT</version>
<extensions>true</extensions>
<dependencies>
<dependency>
<groupId>com.adobe.flex</groupId>
<artifactId>compiler</artifactId>
<version>${flex.framework.version}</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.adobe.flex.compiler</groupId>
<artifactId>adt</artifactId>
<version>${flex.framework.version}</version>
</dependency>
</dependencies>
<configuration>
<sourceFile>AirTest.mxml</sourceFile>
<flexbuilderCompatibility>true</flexbuilderCompatibility>
<descriptorTemplate>${basedir}/src/main/flex/AirTest-app.xml</descriptorTemplate>
<keystore>${basedir}/cert.p12</keystore>
<storepass>secret</storepass>
<includeFileSets>
<fileSet>
<directory>src/main/resources/embedded</directory>
<includes>
<include>*.*</include>
</includes>
</fileSet>
</includeFileSets>
</configuration>
<executions>
<execution>
<goals>
<goal>sign-air</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.adobe.flex.framework</groupId>
<artifactId>air-framework</artifactId>
<version>${flex.framework.version}</version>
<type>pom</type>
</dependency>
</dependencies>
</project>


Also notice that includeFiles and includeFileSets configuration parameters are both set. Although the documentation says they are not required, leaving them out causes an exception to be thrown from the sign-air goal. This has been fixed in the latest snapshot.

Also note that it seems to only be possible to include files that are located within the src/main/resources directory.

Also, one other thing to note is that the flex-mojos plugin uses the application descriptor xml file as configured in the descriptorTemplate node. However, there is one change that I had to make in order for the plugin to work. Normally, FlashBuilder updates the descriptor template to specify the name of the SWF in the <content/> node:

<content>[This value will be overwritten by Flex Builder in the output
app.xml]</content>

In order for the sign-air goal to work, I had to manually update that node with the correct value. In my case it needed to be:

<content>my-app-1.0-SNAPSHOT.swf</content>
This change breaks FlashBuilder but there are two solutions. One would be to just make a duplicate version of the descriptor that you use with flex-mojos and one with FlashBuilder. However, you would need to manually keep them up to date if you change the version number. The other option would be to dynamically make a copy and then update that node as needed. This would theoretically allow you to automatically sync the version number with the version specified in the pom. I haven't figured this part out yet, but I will update this post with my progress. This has been fixed. You can specify the flexBuilderCompatibility parameter to let the plugin manage this automatically


<flexBuilderCompatibility>true</flexBuilderCompatibility>

UPDATE: You can also use the special ${output} token in the application descriptor as the value of the content tag which will allow the plugin to set the name of the swf into the descriptor automatically. With this approach, you don't need to set the flexCompatibility paremeter. However, that still breaks Flash Builder's Export Release Build function.

The last step if desired is to let the plugin manage the version number in the application descriptor. This can be done by setting the version node with ${version}.

<version>${version}</version>

This doesn't break Flash Builder, however if you use the Export Release Build the version number will be "${version}".

I will bundle everything up and post here shortly.


Also, I have posted some of my findings to the Flex-mojos Google Group.

11 comments:

Unknown said...

air-framework and flex-framework are basically the same dependency. But the first includes airglobal+airframework and the second playerglobal.

So there is no point on adding flex-framework then exclude player global.....


VELO

Rob McKeown said...

I will fix that. Thanks for the info... and your answers on the google group too.

Unknown said...

Nice, if you like, you can add that as air usage instructions on wiki (it is public editable, so you can add that)

So other users will more likely find it, you get the credit and flexmojos more documentation. =D


VELO

Rob McKeown said...

Sure, I will post it to the wiki tomorrow. Thanks again.

Anonymous said...

There is an other interresting article about air and maven on piaction blog with code exemple:

You can find it here (but in french) :
http://blog.piaction.com/2010/04/automatiser-la-production-de-vos-applications-air-avec-maven/

Strangepork said...

> I will bundle everything up and post here shortly.

Hey I would love to download this bundle! ;-)

Rob McKeown said...

@strangepork - You should be able to find everything you need from the flex-mojos wiki at https://docs.sonatype.org/display/FLEXMOJOS/Building+an+AIR+Application

I posted all the example files there.

Nabeel Ahmad said...

I am trying to migrate my maven project from flex 3 to flex 4. I have tried a lot of configurations and SDK versions. If for example I spceify...

com.adobe.flex.framework
flex-framework
4.0.0.13555
pom


My IDE recognizes this version but somehow I cannot download the required version. After compiling my pom.xml I get this message

Missing:
----------
1) com.adobe.flex:compiler:pom:4.0.0.13555
Path to dependency:
1) org.sonatype.flexmojos:flexmojos-maven-plugin:maven-plugin:3.6.1
2) com.adobe.flex:compiler:pom:4.0.0.13555

Rob McKeown said...

It sounds like the repositories you are downloading from don't have the new versions deployed. Are you using your own hosted repository?

Anonymous said...

Your example doesn't work anymore can you please update it

Blog said...

Thanks for the article. Based on this I have created an example porject which uses the newest flexmojo and flex versions. The source is managed on /bitbucket.org.