The Blog

Sep 25, 2007

Build Tools: Maven Flex Plugins 

by Maxim Porges @ 10:23 PM | Link | Feedback (7)

UPDATE 2007.09.28: as Christian Gruber (the maven-flex2-plugin's author) graciously pointed out, the net.israfil Flex 2 Maven plugin **is** available on the public Maven repo. You can get to it here: http://repo1.maven.org/maven2/net/israfil/mojo/maven-flex2-plugin/. I've left my original post as is for posterity's sake, but you can check the Google Group for the plugin to see why the integration build was failing (pending a reply from Christian after I posted my build file).

So, we have a build tool shoot-out coming up next week, which means I need to get my crap together and get a CF/Flex build working in Maven.

Naturally, the easiest thing to do would be to get a Maven 2 Flex Plugin and let that build my code for me. However, I had a few small issues getting it going, so I though I would share my experiences in case anybody else has the same problems.

Turns out there are two Maven plugins for building Flex apps: the maven-flex2-plugin option from israfil.net and another one I found today by accident on ServeBox.com (the flex2-plugin). Besides this, the ServeBox guys seem to have all sorts of Flex goodness (including a Java/Flex framework, apparently - who knew?). Anyway, I had been planning on using the one from israfil.net, so I started there.

Installing the Plugin
First off, I needed to install the plugin in my local Maven repository. Usually, installing Maven plugins is a snap, since they are hosted on global repositories that your local Maven installation knows how to talk to, and Maven installs them automatically just be you declaring them in your build. However, since israfil.net is not a hugely popular plugin, it's necessary to download it and install it from source.

First step, check the code out from SVN. We can find the SVN repo on the Project Information page (the Maven site plugin generates this for your automatically if you tell it where your repo's located in your POM).
svn checkout \
http://israfil-mojo.googlecode.com/svn/tags/israfil-mojo-all-9 \
israfil-mojo-all-9

If you look at what you checked out, you'll see that you have a tiered Maven project. There is a top level project for the israfil-mojo family of projects, and beneath that is each of the sub-projects for compiling flex2 (maven-flex2-plugin), generating ASDocs (maven-asdoc-plugin), etc.

Once you have the project code, you need to install it in to your local repository. Usually, you just invoke mvn install, but I had some issues with the build process.

First, due to the way that the maven-invoker-plugin was declared in the build file, Maven could not locate the plugin in the global repository to download it. So, I found the plugin on the appropriate Project Information page again, and checked it out from SVN.
svn checkout \
https://svn.apache.org/repos/asf/maven/plugins/tags/maven-invoker-plugin-1.0 \
maven-invoker-plugin

Next, I ran mvn install from the root of the downloaded maven-invoker-plugin directory, and Maven performed its usual magic of downloading all the dependencies and installing the plugin for me.

Once that was resolved, I went back to the Israfil Flex plugin. I ran mvn install from the root of the israfil-mojo-all-9 directory. Everything ran fine (compilation, tests, etc.) until Maven hit this point:
...
[INFO] Installing /Users/.../israfil-mojo-all-9/maven-flex2-plugin/pom.xml to /Users/.../it-1.2-SNAPSHOT/maven-flex2-plugin-it-1.2-SNAPSHOT.pom
[INFO] [invoker:run {execution: default}]
[INFO] Building: maven-flex2-actionscript1-test/pom.xml
[INFO] ...FAILED[code=1]. See /Users/.../build.log for details.

...

What was happening was, while running the invoker plugin, something was failing. It looked like some sort of ActionScript test was failing. I went in to the directory referenced in the error (/Users/porgesm/Desktop/israfil-mojo-all-9/maven-flex2-plugin/src/it/maven-flex2-actionscript1-test/) and found a pom.xml. Looking in the pom.xml, there was an integration test of some kind being run. Rather than trying to figure out why this was failing, I took the brute force approach and simply commented out the invoker plugin's invocation in the pom.xml under the maven-flex2-plugin directory (under the downloaded israfil-mojo-all-9 directory) as follows:
<!--
<plugin>
<artifactId>maven-invoker-plugin</artifactId>
<configuration>
<debug>true</debug>
<projectsDirectory>src/it</projectsDirectory>
<pomIncludes>
<pomInclude>*/pom.xml</pomInclude>
</pomIncludes>
</configuration>
<executions>
<execution>
<phase>integration-test</phase>
<goals><goal>run</goal></goals>
</execution>
</executions>
</plugin>
-->

Running mvn install again now produced the following output:
[INFO] ----------------------------------------------
[INFO] Reactor Summary:
[INFO] ----------------------------------------------
[INFO] Israfil Mojo: All ............................... SUCCESS [1.852s]
[INFO] Flex 2.0 maven plugin support classes ........... SUCCESS [2.834s]
[INFO] Flex 2.0 maven plugin ........................... SUCCESS [0.913s]
[INFO] ASDoc API documentation generator plugin ........ SUCCESS [0.604s]
[INFO] ----------------------------------------------
[INFO] ----------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ----------------------------------------------
[INFO] Total time: 6 seconds
[INFO] Finished at: Tue Sep 25 22:13:27 EDT 2007
[INFO] Final Memory: 11M/21M
[INFO] ----------------------------------------------

Nice - we're in business.

Creating A Sample Flex Project
Next, I configured a simple Maven project in Eclipse with a Main.mxml containing a button that said "Hello" when clicked. This .mxml file goes in to src/main/flex under the project, the default location the plugin expects code to be located.

The pom.xml file for this project was really simple. I took the sample from the israfil.net web site and modified it slightly for my needs:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>net.israfil.examples</groupId>
<artifactId>israfil-swf-example</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>swf</packaging>
<properties>
<flex.home>/opt/flex_sdk_2</flex.home>
</properties>

<build>
<!-- if you want this vs. artifactId.swf use finalName -->
<finalName>exampleApp</finalName>
<plugins>
<plugin>
<groupId>net.israfil.mojo</groupId>
<artifactId>maven-flex2-plugin</artifactId>
<version>1.2-SNAPSHOT</version>
<extensions>true</extensions>
<configuration>
<flexHome>${flex.home}</flexHome>
<useNetwork>true</useNetwork>
<strict>true</strict>
<!-- ... other options ... -->
<warning>true</warning>
<!-- if you use dataservices, make sure you overri... -->
<!--
<dataServicesConfig>
src/main/resources/services-config.xml
</dataServicesConfig>
-->

<main>Main.mxml</main>
</configuration>
</plugin>
</plugins>
</build>
</project>

Basically, I commented out the <dataServicesConfig/> element since I'm not using dataservices, and added a <properties/> element at the top of the file with the path to my Flex 2 SDK directory (containing the frameworks, player, bin directories etc. that come with the Flex 2 SDK).

I ran mvn compile, but had another issue, this time with Flex compilation.
...
[INFO] defaults: Error: unable to open './macFonts.ser'
...

Duh. Checking the Usage page in the plugin's project site, I see that I have to uncomment the <local-fonts-snapshot>localFonts.ser</local-fonts-snapshot> element in my flex-config.xml file. RTFM, fo' sho'.

I ran mvn compile again, and this time (after a brief compilation pause) a file called exampleApp.swf appeared in my target directory. Sure enough, double clicking the SWF opened the Flash projector and produced a running Flex app.

Thoughts
This was certainly a bit more of a pain than I had expected, but the issues with the build were not unresolvable. In a controlled development environment, you would build and deploy a lesser-known plugin like this to your corporate Maven repository to save your developers the hassle of doing so manually.

The plugin seems to work nicely once configured, although I've only put it through simple paces so far. The other plugin I mentioned from ServeBox supposedly has FlexUnit integration, so I'll definitely need to check that out - otherwise, I'll need to invoke the FlexUnit Ant tasks from Maven in order to run the unit tests for the sample application we're building for next week's user group meeting. ServeBox also has their own public Maven repo from which Maven can retrieve the plugin, so the install process should be simpler once I add this repo location to my Maven settings file.

Stay tuned and I'll post more info on my ongoing experiences with the israfil.net plugin, as well as the one from ServeBox.