Table of Contents

One of the things we have been meaning to do is convert our build framework over from ANT to Maven2. The time has come, and the work is in-progress (jira:fcrepo-394).

The basic strategy was laid out in our last face-to-face committers' meeting in Ithaca. As you can see, there are a few things that need to be done. If you are interested in helping, I would be very happy to coordinate efforts. Send an email to the group: "fedora-ant-to-maven@googlegroups.com"

Approach

Since moving to Maven2 requires significant restructuring of the baseline directories, we want to make small, incremental changes back to svn/trunk so that the on-going Fedora development does not become too far separated. This means that the ANT builds must continue to work as the baseline becomes incrementally transformed.

Progress/Status

(warning) Not yet
(info) Partial
(tick) Complete

* (tick) 1a - Source conformant to m2 standards (files and packages) + tweak build.xml

    1. This was checked-into svn:fedora/trunk.rev.8076
    2. The basic structure of maven has been created (src/main/java, src/test/java, etc)
    3. The renaming of packages based on Maven-central's requirements will happen at the very end of this whole effort
  • (tick) 1b - Get poms for all dependencies
    1. Based on the jars in the /lib dir, a simple install script pushes them into the local repository
    2. Need to create proper *.pom and <dependency> for each artifact
  • (tick) 2a - Ant-maven integration (eight subprojects) generating source and building
    • This initial integration requires a minimum break-out of the following subprojects
    • This is just building, unit tests turned off
    • This was checked-into svn:fedora/trunk.rev.8083
      1. (tick) generate
        • This is a small project that creates the executable stubwrapper generator
      2. (tick) common
        • This contains 'fedora.common' package
        • includes wsdl2java generation and stubwrappers
        • has dependencies on '/generate'
      3. (tick) server
        • This is the 'fedora.server' package
        • has dependencies on '/common'
      4. (tick) client
        • This is the 'fedora.client' package
        • has dependencies on both '/common' and '/server'
      5. (tick) integrationtest
        • This is the 'fedora.test' package
        • has dependencies on both '/client' and '/server'
      6. (tick) localservices
        • This contains three sub-projects
          • fop
          • imagemanip
          • saxon
        • War files are created for all contained sub-projects when running mvn clean install
      7. (tick) democontent
        • This creates a war file (fedora-demo.war) containing only demo content (no application code)
      8. (tick) installer
        • This project has no source java files of its own
        • It uses the 'assembly' plugin to aggregate other artifacts into fedora-installer.jar
        • To create fedora-installer.jar, run: mvn clean install -P fedora-installer
  • (tick) 2b - All maven unit tests (test inventory)
    • This was checked-into svn:fedora/trunk.rev.8086
      1. (tick) generate
      2. (tick) common
      3. (tick) server
      4. (tick) client
      5. (tick) integrationtest
      • No unit tests here by definition
  • (tick) 2c - All maven integration tests (test inventory)
    • Like the system tests previously provided in the ANT tests (ConfigA/B/Q), for now, the Maven2 integration tests will require a pre-started application server.
    • Because integration tests are run during the default build lifecycle of Maven2, you must pass the following flag at build-time to disable the running of integration tests ('integration.test.skip')
      • mvn clean install -Dintegration.test.skip=true
  • *# (tick) generate
    1. (tick) common
    2. (tick) server
    3. (tick) client
    4. (tick) integrationtest
  • (tick) 2d - All maven system tests (test inventory)
    • These tests run within the 'integrationtest' project as separate profiles.
    • This was checked-into svn:fedora/trunk.rev.8088
  • *# (tick) ConfigA
      • mvn clean install -P configA
    1. (tick) ConfigB
      • mvn clean install -P configB
    2. (tick) ConfigQ
      • mvn clean install -P configQ
  • (info) 2e - installer.jar (and other artifacts verified)
    1. (tick) client.jar
      • This is being created with the default build target: (mvn package)
      • Its artifact name contains the 'fedora' classifier (see note below for todo)
    2. (tick) installer.jar
    3. (tick) rmi-journal-receiver.jar
      • This was checked-into svn:fedora/trunk.rev.8114
    4. (tick) fedora-demo.war (democontent)
    5. (tick) local-services
      • This was checked-into svn:fedora/trunk.rev.8092
  • *# *## (tick) fop.war
      1. (tick) imagemanip.war
      2. (tick) saxon.war
    1. (warning) api.jar
      • Is this still used?
    2. (tick) messaging-client.jar
    3. (tick) messaging-client.zip
      • This was checked-into svn:fedora/trunk.rev.8113
    4. (tick) fedorahome.zip
      • created by running: mvn clean install -P fedora-installer
    5. (tick) fedora.war
  • (warning) 3 - m2-only (full split-out)
    • Admin Client (Swing)
    • Java Client API (FedoraClient.jar)
    • Messaging Client
    • WebAdmin Client (Flex)
    • (tick) Server Webapp
    • (tick) Installer
  • (warning) 4 - Split out server modules as projects
  • (warning) 5 - Rename packages based on Maven-central's requirements

Commands

The following are some useful commands in working with the Fedora Maven2 builds

  1. mvn clean install
    • builds all source code
    • runs all unit & integration tests
  2. mvn install -Dintegration.test.skip=true
    • runs all unit tests
    • skips all integration tests
  3. mvn install -Dmaven.test.skip=true
    • skips all unit tests
  4. mvn integration-test -P config[A|B|Q]
    • runs system tests per given configuration
  5. mvn install -P fedora-installer
    • generates fedora-installer.jar
    • found in /installer/target

Unresolved

If you would like to help, these nuggets need a friend.

# (info) Currently, all of the maven dependencies are in the top-level pom.xml

    1. (tick) They need to be surgically pushed down to their appropriate subproject pom.xml
      1. An initial push down is complete though
    2. (tick) Their dependency declarations need to point to the proper version on maven-central, not the locally created artifact
      1. All of the artifacts that can be resolved to maven-central without selected new versions is complete
      2. Additional validation is needed especially to ensure that conflicts do not cause problems
    3. (tick) Libraries which cannot be resolved to maven-central need to added to the Duraspace Mave repository (under thirdparty)
    4. (tick) Libraries which are supplied by Duraspace projects need to be added to the Duraspace Maven repository (under releases)
    5. (info) The Duraspace Maven repository public groups need to be revised to NOT mirror maven-central or other public repositories
  1. The continued need for each junit suite aggregator class needs to be re-evaluated
  2. Unit test naming conventions need to be standardized (since maven invokes them based on a regex at different build phases)
    1. unit-test: '**/*Test.class'
    2. integration-test: '**/Test*.class'
  3. (tick) Unit/system/integration tests used to fall under 'fedora.test'
    1. now that they have been split across subprojects ('server', 'client', 'integrationtest'), they are not aggregated with a single call (i.e. fedora.test.AllUnitTests)
    2. a fix to this issue would only be needed as long as we continue to use ANT, Maven2 has its own test aggregation
  4. (tick) Build number & timestamp needed for artifact names and manifest files
    • client.jar
      • needs 'fedora.version' in filename and manifest
      • needs 'build.tstamp' in manifest
    • The following is a plugin that should do the trick
    • It should be configured in the top-level /pom.xml and /client/pom.xml
    • http://mojo.codehaus.org/buildnumber-maven-plugin/index.html
    • The build number plug-in fails if the SCM is unavailable or is not installed on the host platform. A <revisionOnScmFailure> parameter has been added to set a default build number. A warning is still shown during build but the build runs properly to completion. The default build number has been set to the "version" of the fedora-repository pom assuming that pom's version will eventually match a current or planned release.
  5. Refactor fedora.test.FedoraTestCase.java into two classes (one dependent on '/server' and one on '/client') so tests the inherit from it can be pushed back down from '/integrationtest' to their respective projects.
  6. fedora.test.integration.cma.SimpleDeploymentTests has a bug. See source file for details.
  7. In creating fedorahome.zip, deploy and undeploy *.wsdd files are token-swapped (e.g. 'Fedora-API-M-Port-SOAPHTTP' to 'management').
    • This mangles token instances such as 'Fedora-API-M-Port-SOAPHTTP S'. This is a pre-existing bug.
  8. (tick) Script needs to be written to support Maven Bamboo CI build
  9. (tick) The file server/src/main/resources/properties/lib.properties may be a candidate for removal as it was tied to the Ant build
  10. Libraries listed in server/src/resource/properties/install.properties do not automatically update with library updates and duplicate information in the pom which does not benefit from pom dependency checking
    1. (info) Updated to be consistent with Maven dependencies but still requires manual editing
  11. Split client into four modules in a branch (See Item 3 Above). Keep them under a client subdirectory.
    1. Swing Client
    2. FedoraClient Jar
    3. Messaging Client
    4. WebAdmin Client
  12. Experiment with saxon, fop and imagemanip stored under a localservices directory but being dependencies of fedora-repository. This may help Eclipse since each local service is a standalone, deployable war.

Rationale

Subproject break-out
generate

Finding the appropriate lines on which to draw subproject (maven module) boundaries is not an exact science.

During this initial conversion to Maven2, we want to minimize the degree of baseline upheaval while splitting out subprojects enough to allow maven to properly function.

A logical starting point is:

  • client
  • server
  • common

Where 'client' has a dependency on 'server', and they both depend on 'common'.
This becomes a little problematic with the introduction of wsdl stubs/skeletons and in the case of Fedora, second-level generated source code wrapping the generated wsdl stubs.

The generated artifacts are as follows:

  • wsdl-stubs
  • wsdl-skeletons
  • wsdl-stub wrappers

The sequence of events to produce these artifacts is as follows:

  1. compile fedora class (BuildAxisStubWrapper.java)
  2. run axis-wsdl2java on fedora wsdl's
  3. run executable BuildAxisStubWrapper on wsdl2java outputs (wsdl-stubs)

The binary output of step-2 above is needed by 'server' during compilation.
The source output of step-2 above is needed as input to step-3.
The source output of step-3 above is needed by 'client' during compilation.

  • Note: the source output is needed here instead of the binary because the generated source contains import statements with dependencies on packages within 'client'.
    Therefore, the source output of step-2 is needed by 'client' before the compilation phase.

This being the case, the three-step sequence above can all be pushed down to 'common'.
The only problem here is that an executable BuildAxisStubWrapper is needed before the source-generation phase of running axis-wsdl2java.
Therefore, a fourth subproject is needed to create the BuildAxisStubWrapper executable: 'generate'.

integrationtest

There is a combination of unit, integration, and system tests within the baseline.
The 'integrationtest' subproject grew out of the need to have tests with dependencies on all of the other functional subprojects.

As it so happens, their is a test base class (FedoraTestCase.java) that is extended by several other tests from both 'server' and 'client'.
FedoraTestCase itself depends on both 'server' and 'client'.
Therefore, all tests that extend from FedoraTestCase are implicitly integration tests and have been migrated to the 'integrationtest' subproject.

#trackbackRdf ($trackbackUtils.getContentIdentifier($page) $page.title $trackbackUtils.getPingUrl($page))
  • No labels

4 Comments

  1. Once the compile and test targets have been worked out and are functioning smoothly, I'd like to see the assembly plugin added, to build packages suitable for distribution (including specifying executable jars):  http://maven.apache.org/plugins/maven-assembly-plugin/

    1. Certainly it is no problem to throw the assembly-plugin into the top-level pom.xml. For it to be useful, however, we need to configure it as well as create the accompanying descriptor (i.e. dep.xml). The structure of the 5 maven-modules is pretty well set for the time being. If you would be interested in jumping in to do this 'assembly setup', I would be happy work with you.

      1. This can be "tricky", we use an assembly descriptor/plugin in DSpace and had to make sure that the project it is configured within was not a parent of the other projects.  This is because of two reasons (1) we wanted to bind the assmbly to the package phase in Maven and not have to have users type mvn package assembly:assembly to package up the dspace release.  (2) adding the assembly to the parent may cause it to be executed on any child modules as well.
        Given this I highly recommend separating what is considered your "parent" pom from the project used to assemble your distribution.

        1. For the issue of the assembly plugin, what we ended up doing was attaching it to the package phase (so assembly:assembly is not required) solely within a single child project ('installer'). It so happens that within that project, the plugin is also wrapped within a profile ('fedora-installer'). Since there is considerable packaging overhead in creating the installer, it is only created on demand:
          mvn package -P fedora-installer