Apache – Complex Maven2 with Flex4 Setup

apache-flexflex-mojosgumbomaven-2sonatype

I have been struggling to get Maven2 to cooperate with me, and was wondering if anyone out there had any ideas on how to get this working…. I am working on a Flash project, and we are considering switching from our hybrid Flex4/FlashCS4 to a pure Flex4 solution. We would like to use the Maven2 build system, so that our developers do not have to manually download, install, and configure Flex4 on their machines.

I have managed to create a single-module project using Maven2 with Flex4 (I am using the Sonatype FlexMojos Plugin and their Maven2 repository located at http://repository.sonatype.org/content/groups/flexgroup/). I really start running into trouble when it comes to making this multimodule….

Our project is organized as follows:

 |- bin
 |  |- moduleX.swf
 |  |- moduleY.swf
 |  |- ...
 |- lib
 |  |- moduleA.swc
 |  |- moduleB.swc
 |  |- ...
 |- src
 |  |- moduleA
 |  |- moduleB
 |  |- ...
 |- test
 |  |- moduleA
 |  |- moduleB
 |  |- ...
 |- share
 |  |- asset1
 |  |- asset2
 |  |- ...
 |- ...

Basically, each of our modules has its sources located under "src/<modulename>/" and its test sources located under "test/<modulename>/", with generated SWF files being placed in "bin" and generated SWC files being placed in "lib". Our assets (things that we would like to be able to reference using the "@Embed" or "[Embed]" tags) live under "share". I have looked at the references on project inheritance and aggregation, but can't seem to find anything that would allow us to keep our existing project directory structure. We would like this migration to be as quick, painless, and non-disruptive as possible. I would really appreciate it if anyone can figure out how to create a "pom.xml" file that allows us to keep our current infrastructure.

Best Answer

If you are certain about moving to Maven 2, it will save you a lot of pain to modify the project structure so each module contains its own sources and tests and follows the Maven conventions.

If you really can't do that, you can create a parallel module hierarchy, and configure each module with relative paths pointing back to your existing structure. The structure could end up looking something like this:

|- Maven Root
|   |- pom.xml
|   |- ModuleA 
|   |  |- pom.xml
|   |- ModuleB
|   |  |- pom.xml
|   |- ModuleX
|   |  |- pom.xml
|   |- ModuleY
|   |  |- pom.xml
|   |- asset1
|   |  |- pom.xml
|   |-...
|
|- Existing-Root
    |- bin
    |  |- moduleX.swf
    |  |- moduleY.swf
    |  |- ...
    |- lib
    |  |- moduleA.swc
    |  |- moduleB.swc
    |  |- ...
    |- src
    |  |- moduleA
    |  |- moduleB
    |-...

You may also want to add interim poms so you can build related sets (e.g. a share pom containing all the share modules).

You could then:

  • configure each pom with the appropriate relative paths so it can build its sources.
  • configure the maven-dependency-plugin to unpack Embed resources into target/flex/resources
  • use the build-helper-maven-plugin to set target/flex/resources as a resource location (note this may not actually work, as the plugin expects Embed resources to be in src/main/resources)
  • define the appropriate dependencies between modules.
  • use the maven-antrun-plugin to copy the final artifacts to the existing bin directory (if you attempt to use the same output directory by setting project.build.outputDirectory, but then a clean of one module will clobber other builds).

Here is an example configuration to achieve those steps for one of the poms:

<build>
  <!--configure the source and test sources to point to the existing structure-->
  <sourceDirectory>
    ${baseDir}/../../Existing-Root/test/${project.artifactId}
  </sourceDirectory>
  <testSourceDirectory>
    ${baseDir}/../../Existing-Root/src/${project.artifactId}
  </testSourceDirectory>
  <plugins>
    <plugin>
     <groupId>org.sonatype.flexmojos</groupId>
     <artifactId>flexmojos-maven-plugin</artifactId>
     <version>3.2.0</version>
     <extensions>true</extensions>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-dependency-plugin</artifactId>
      <executions>
        <execution>
          <id>unpack</id>
          <phase>generate-resources</phase>
          <goals>
            <goal>unpack</goal>
          </goals>
          <configuration>
            <artifactItems>
              <!--unpack asset1 to target/flex/resources, 
                define any additional artifacts for other shares-->
              <artifactItem>
                <groupId>my.group.id</groupId>
                <artifactId>asset1</artifactId>
                <version>1.0.0</version>
                <type>swf</type>
              </artifactItem>
            </artifactItems>
            <outputDirectory>
              ${project.build.directory}/flex/resources
            </outputDirectory>
            <overWriteReleases>false</overWriteReleases>
            <overWriteSnapshots>true</overWriteSnapshots>
          </configuration>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <!--add target/flex/resources as a resource location-->
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>build-helper-maven-plugin</artifactId>
      <version>1.3</version>
      <executions>
        <execution>
          <id>add-resource</id>
          <phase>generate-resources</phase>
          <goals>
            <goal>add-resources</goal>
          </goals>
          <configuration>
            <resources>
              <resource>
                <directory>
                  ${project.build.directory}/flex/resources
                </directory>
              </resource>
            </resources>
          </configuration>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <artifactId>maven-antrun-plugin</artifactId>
      <executions>
        <execution>
          <phase>pre-integration-test</phase>
          <configuration>
            <tasks>
              <!--copy the final artifact to the module's bin directory-->
              <copy 
                file="${project.artifactId}-${project.version}.${project.packaging}"
                todir="${baseDir}/../../Existing-Root/bin/${project.artifactId}"/>
            </tasks>
          </configuration>
          <goals>
            <goal>run</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
  ...
 </build>