Maven, Flex/Air and Android - Trinity or Bermuda Triangle

2010-12-19 Software-Engineering Mobile

Partially for professional reasons, partially out of plain, naked, old-fashioned curiosity (and also triggered by the Adobe announcement that Adobe Air now runs on Android) I am currently looking to find out how to use Maven to build a Flex/Air application for the Android phone.

And ... it is not this easy. I am now working on this for a couple of weeks (elapse time that is - CPU time probably more 16 hours).

There is documentation available how to develop Flex/Air apps for Android using Flash Builder 4 (and other Adobe tools like Adobe Flash Professional CS5), but as soon as you want to use your own IDE (in my case AquaEmacs and Maven), things get difficult.

The components that you need to make work together and that have dependencies are ...
  • The Maven release - I started with 2.2.1, but found out that I need to use flex-mojo 4.0-SNAPSHOT and this requires 3.0.1
  • The flex-mojo release - I started with 3.7.1, but need to use Air 2.5, which is only packaged with Flex SDK 4.5, which requires flex-mojo 4.0-SNAPSHOT (have not tried, if it also works with 4.0-beta-3)
  • The Flex SDK release - I started with 4.1, but found out that this release is not packaged to support Air 2.5, means I need to use Flex SDK 4.5
  • The Air SDK release - I started with 1.5, but need to use 2.5, because this is the one that runs on Android
... means the winning configuration is ...
  • Maven 3.0.1
  • Flex-mojo 4.0-SNAPSHOT
  • Flex SDK 4.5.0 (build 17689) (this includes Air SDK 2.5)
The only thing you need to install is Maven 3.0.1 (the rest will be downloaded as part of the build process).

Now the hard work starts and it is mainly hard work, because if you do something wrong the build process will just display a stack trace that points to a NullPointer exception, but that is maybe the price for doing leading (bleeding) edge stuff.

The next step is to get a project that works. You can get this by checking out the Maven/Flex 4.1/Air 1.5 sample from ...

svn co http://svn.sonatype.org/flexmojos/trunk/flexmojos-testing/flexmojos-test-harness/projects/concept/simple-air SimpleAir

... and edit the pom.xml to look like this ...


<?xml version="1.0" encoding="UTF-8"?>
<!--

Copyright 2008 Marvin Herman Froeder Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
-->

<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>

<properties>
<flexmojos.version>4.0-SNAPSHOT</flexmojos.version>
<flex.version>4.5.0.17689</flex.version>
</properties>

<groupId>info.rvin.itest</groupId>
<artifactId>simple-air</artifactId>
<version>1.0-SNAPSHOT</version>

<packaging>pom</packaging>

<modules>
<module>air</module>
<module>swf</module>
<module>swc</module>
</modules>

<build>
<sourceDirectory>src/main/flex</sourceDirectory>
<plugins>
<plugin>
<groupId>org.sonatype.flexmojos</groupId>
<artifactId>flexmojos-maven-plugin</artifactId>
<version>${flexmojos.version}</version>
<extensions>true</extensions>
<dependencies>
<dependency>
<groupId>com.adobe.flex</groupId>
<artifactId>compiler</artifactId>
<version>${flex.version}</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.adobe.flex.compiler</groupId>
<artifactId>adt</artifactId>
<version>${flex.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

<dependencies>
<!-- Air SDK dependencies -->
<dependency>
<groupId>com.adobe.flex.framework</groupId>
<artifactId>air-framework</artifactId>
<version>${flex.version}</version>
<type>pom</type>
</dependency>
</dependencies>
</project>

Please also edit .../air/pom.xml and replace %{flexmojos.version} with ${flexmojos.version}.

Now comes the big trick ... please edit .../air/src/main/resources/descriptor.xml and to look like this ...


<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!--

Copyright 2008 Marvin Herman Froeder
-->
<!--
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-->

<!--
http://www.apache.org/licenses/LICENSE-2.0
-->

<!--
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

-->
<application xmlns="http://ns.adobe.com/air/application/2.5">

<!-- Adobe AIR Application Descriptor File Template.

Specifies parameters for identifying, installing, and launching AIR applications.
See http://www.adobe.com/go/air_1.0_application_descriptor for complete documentation.

xmlns - The Adobe AIR namespace: http://ns.adobe.com/air/application/1.0
The last segment of the namespace specifies the version
of the AIR runtime required for this application to run.

minimumPatchLevel - The minimum patch level of the AIR runtime required to run
the application. Optional.
-->

<!-- The application identifier string, unique to this application. Required. -->
<id>main</id>

<!-- Used as the filename for the application. Required. -->
<filename>main</filename>

<!-- The name that is displayed in the AIR application installer. Optional. -->
<name>main</name>

<!-- An application version designator (such as "v1", "2.5", or "Alpha 1"). Required. -->
<!-- <version>v1</version> -->
<versionNumber>1</versionNumber>

<!-- Description, displayed in the AIR application installer. Optional. -->
<!-- <description></description> -->

<!-- Copyright information. Optional -->
<!-- <copyright></copyright> -->

<!-- Settings for the application's initial window. Required. -->
<initialWindow>
<!-- The main SWF or HTML file of the application. Required. -->
<!-- Note: In Flex Builder, the SWF reference is set automatically. -->
<content>${output}</content>

<!-- The title of the main window. Optional. -->
<!-- <title></title> -->

<!-- The type of system chrome to use (either "standard" or "none"). Optional. Default standard. -->
<!-- <systemChrome></systemChrome> -->

<!-- Whether the window is transparent. Only applicable when systemChrome is false. Optional. Default false. -->
<!-- <transparent></transparent> -->

<!-- Whether the window is initially visible. Optional. Default false. -->
<!-- <visible></visible> -->

<!-- Whether the user can minimize the window. Optional. Default true. -->
<!-- <minimizable></minimizable> -->

<!-- Whether the user can maximize the window. Optional. Default true. -->
<!-- <maximizable></maximizable> -->

<!-- Whether the user can resize the window. Optional. Default true. -->
<!-- <resizable></resizable> -->

<!-- The window's initial width. Optional. -->
<!-- <width></width> -->

<!-- The window's initial height. Optional. -->
<!-- <height></height> -->

<!-- The window's initial x position. Optional. -->
<!-- <x></x> -->

<!-- The window's initial y position. Optional. -->
<!-- <y></y> -->

<!-- The window's minimum size, specified as a width/height pair, such as "400 200". Optional. -->
<!-- <minSize></minSize> -->

<!-- The window's initial maximum size, specified as a width/height pair, such as "1600 1200". Optional. -->
<!-- <maxSize></maxSize> -->
</initialWindow>

<!-- The subpath of the standard default installation location to use. Optional. -->
<!-- <installFolder></installFolder> -->

<!-- The subpath of the Windows Start/Programs menu to use. Optional. -->
<!-- <programMenuFolder></programMenuFolder> -->

<!-- The icon the system uses for the application. For at least one resolution,
specify the path to a PNG file included in the AIR package. Optional. -->
<!-- <icon>
<image16x16></image16x16>
<image32x32></image32x32>
<image48x48></image48x48>
<image128x128></image128x128>
</icon> -->

<!-- Whether the application handles the update when a user double-clicks an update version
of the AIR file (true), or the default AIR application installer handles the update (false).
Optional. Default false. -->
<!-- <customUpdateUI></customUpdateUI> -->

<!-- Whether the application can be launched when the user clicks a link in a web browser.
Optional. Default false. -->
<!-- <allowBrowserInvocation></allowBrowserInvocation> -->

<!-- Listing of file types for which the application can register. Optional. -->
<!-- <fileTypes> -->

<!-- Defines one file type. Optional. -->
<!-- <fileType> -->

<!-- The name that the system displays for the registered file type. Required. -->
<!-- <name></name> -->

<!-- The extension to register. Required. -->
<!-- <extension></extension> -->

<!-- The description of the file type. Optional. -->
<!-- <description></description> -->

<!-- The MIME type. Optional. -->
<!-- <contentType></contentType> -->

<!-- The icon to display for the file type. Optional. -->
<!-- <icon>
<image16x16></image16x16>
<image32x32></image32x32>
<image48x48></image48x48>
<image128x128></image128x128>
</icon> -->

<!-- </fileType> -->
<!-- </fileTypes> -->
</application>

... and you are (almost) done.

Last put not least, you need to make sure Maven is correctly configured to find the right components and the right plugins. My ${HOME}/.m2/settings.xml looks like this ...


<?xml version="1.0" encoding="UTF-8"?>
<settings
xmlns="http://maven.apache.org/settings/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd
"
>
<localRepository>/Downloads/maven/repository</localRepository>
<profiles>
<profile>
<id>roland</id>
<repositories>
<repository>
<id>mvndefault</id>
<name>Maven Default Repo</name>
<url>http://repo1.maven.org/maven2</url>
<layout>default</layout>
</repository>
<repository>
<id>mvnsearch</id>
<name>Maven Search Repo</name>
<url>http://www.mvnsearch.org/maven2</url>
<layout>default</layout>
</repository>
<repository>
<id>flexmojos</id>
<url>http://repository.sonatype.org/content/groups/flexgroup</url>
<layout>default</layout>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>flexmojos</id>
<url>http://repository.sonatype.org/content/groups/flexgroup</url>
<layout>default</layout>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>

<activeProfiles>
<activeProfile>roland</activeProfile>
</activeProfiles>
</settings>

Finally change directory to the base directory of the checkout and run ...

> mvn clean install

After 5 mins of downloads you should be done building your first Maven, Flex 4.5, Air 2.5 app.

The next step is to build and install an Android apk package, but I am still working to make this work. Stay tuned.