Continuous Integration for Agile Project Managers (Part 1)

March 30, 2010 by

Any Agile Project Manager worth his salt should be aware of the term ‘Continuous Integration’ (often shortened to ‘CI’). But what is it, and how is it done?

This series of short blog articles aims to answer these two questions, so you can start your next project, or re-configure an existing project, armed with the necessary understanding about this key practice within agile software delivery.

Background

The basic premise of CI is pretty straightforward. An agile team needs a repeatable and reliable method to create a build of the software under development. Why so? Well, if its not already obvious, you may want to revisit the principles behind the Agile Manifesto. Within them you will notice a number of references to ‘working software’, and the foundation of any working software is a stable, tested build.

Recipe for CI

So how does CI help to create this build? Lets list the essential ingredients that we need :

  1. Source Code Control – in a typical agile project, developers turn User Stories into source code, in whatever programming language(s) the project is using. Once their work is at an appropriate level of completeness, they check-in or commit their work to the source code (a.k.a version) control system; for example, Subversion
  2. Build Tool – if the source code needs to be compiled (e.g. Java or C++) then we will need tooling to support that. Modern Integrated Developer Environments (IDE), such as Eclipse or Visual Studio are able to perform this task as developers save source code files. But if we want to build the software independently of an IDE in an automated fashion, say on a server environment, we need an additional tool to do this. Examples of this type of tool are Ant, Maven and Rake and Make. These tools can also package a binary output from the build. For example, with Java projects this might be a JAR or WAR file – the deployable unit that represents the application being developed.
  3. Test Tools – as part of the build process, in addition to compilation and the creation of binary outputs, we should also verify that (at minimum) the unit tests pass. For example, in Java these are often written using the JUnit automated unit testing framework. The tools in (2) often natively support the running of such tests, so they should always be executed during a build. In addition to unit testing, there are numerous other quality checks we can perform and status reports CI can produce. I’ll cover these in detail in a subsequent part to this series.
  4. Schedule or Trigger – we might want to create our build according to a schedule (e.g ‘every afternoon’) or when there is a change in the state of the project source code. In the latter case we can set up a simple rule that triggers a build whenever a developer changes the state of the source code by committing his/her changes, as outlined in (1). This has the effect of ensuring that your teams work is continuously integrated to produce a stable build, and, as you may have guessed, is where this practice gets its name from.
  5. Notifications – the team needs to know when a build fails, so it can respond and fix the issue. There are lots of ways to notify a team these days – instant messaging, Twitter etc, but the most common by far is still email.
  6. Continuous Integration Recipe

    Continuous Integration Recipe


    The tool that wires these five elements together is a Continuous Integration Server. It interacts with the source control system to obtain the latest revision of the code, launches the build tool (which also runs the unit tests) and notifies us of any failures. And it does this according to a schedule or state change based trigger. A CI server often also provides a web-based interface that allows a team to review the status, metrics and data associated with each build.

    CI Server options

    There is a pretty overwhelming choice of available tools in this space. Some are open source, some proprietary. I don’t have time to go into all the available options here unfortunately. However, there is a handy feature comparison matrix available here. Of course, it would be remiss of me not to mention our own hosted service, which allows you to get started with CI in no time at all, without having to be an ‘expert’ user.

    Mike Test Reports

    Test Reports generated by Mike

    In the next part of this series, I’ll delve deeper into how you can use CI to enforce software quality within your team during the various stages of the development process.

Bootstrap your Agile Java Startup Infrastructure in < 30 minutes

March 25, 2010 by

So, you have a great idea for the next web-based killer application. You have assembled a small but geographically dispersed team with the requisite amount of Agile Java development-fu to get the job done. What you need now is some hosted infrastructure so you can all get to work effectively.

In less than 30 minutes.

Step 1 – Get some IDE

Get Eclipse Galileo (JEE version). Hopefully your pipe is fat enough (~190 MB download). Fire it up and use update sites to obtain m2eclipse and subclipse (we’re assuming SVN for a repository, but you could use Git). Install Tomcat and configure as a server.

Step 2 – Get some Scaffolding

Within Eclipse go to File>New>Other, to open the Select a wizard dialog. From the scrollbox, select Maven Project and then click Next. Move through the wizard to select an archetype of an appropriate type (e.g. Appfuse). Click Finish. Validate you can build and deploy your app.

Step 3 – Get some Version Control

While you are waiting for your build to complete, pick a hosted version control provider. There are a number who provide low-cost or even free hosted Subversion for private projects, typically with a trial period. Here is a list. Once signed-up with a clean repository, use subclipse to share the scaffolding app created in (2).

Step 4 – Get some Project Tracking and Wiki

The majority of providers listed in (3) also offer something in the area of hosted task/issue tracking apps that often have sufficient wiki capabilities. Alternatively you can try those who specialise
in this area such as FogBugz or Agilo. We use Agilo on Mike. And you might want to get Basecamp. We use that too.

Step 5 – Get some CI

You could roll your own on Amazon EC2, but that isn’t happening in 30 minutes or 30 hours, probably! Hmmm…Oh I almost forgot – you could use our excellent hosted service ;).

Step 6 – Get some BRM

Whats a BRM? Its Binary Repository Manager. If you’re using Maven, I’d recommend you use one. The only hosted one I’m aware of is provided by Artifactory Online.

Right. We are good to go. What are you waiting for?

New Mike Release with GitHub integration and Functional Testing support

March 18, 2010 by

We are very pleased to be able announce a new release of our hosted CI platform. The release includes some major enhancements to allow our users to do much more with their builds while at the same time ensuring that they happen within a highly secure, controlled environment.

Here is summary of the new features:

CI support for projects hosted within public or private GitHub repositories that use Ant, Maven or Eclipse.

Each build is now executed in an entirely separated environment, which allows our users to:

  • Start, stop and deploy to embedded containers as part of their build process (e.g. Jetty or Glassfish).
  • Start, stop and deploy to provided (by Mike) instances of Apache Tomcat (v5 and 6) as part of their build process.
  • Run integration and functional tests, using frameworks such as HtmlUnit or JWebUnit against applications deployed to said containers or instances.
  • Fork additional processes as part of a build, such as bash scripts and other non-Java based tooling.
  • Use the full range of available Ant tasks and Maven plug-ins as part of a build.

Security hardening:

  • All network communication within Mike is encrypted using either key or token-based authentication.
  • All outbound network access from a build is transparently proxied and validated.
  • IP protection: all builds run in a clean, repeatable sand-boxed environment and all source code processed by a build is accessed using token-based authentication over encrypted channels. See the security section of our website for further details

Also:

  • Support for Maven Ant Tasks (v2.1.0) – Ant-based projects can now use Maven dependency management for their binary artefacts.
  • Gravatar integration for developer email addresses.

Be sure to check out our no-obligation, 14-day trial. You simply need to provide us with your company/project name and an email address. You can also use our sample applications to rapidly get started and experience our platform features. Our prices start from only $10 per month.

Mike Sample Projects

March 2, 2010 by

To make it easier for potential users to trial our service, we have created some sample projects on Google Code.

All the projects are flavours of the classic Java Petstore web application. Eclipse, Ant and Maven variants are provided. The samples also include versions that will fail the build with errors and also fail testing so that the full range of reporting can be experienced.

You can also view our video that walks through the steps of adding, and building a sample project.

Working with Custom Maven Archetypes (Part 3)

February 25, 2010 by

In part 1 and part 2 of this series I was able to demonstrate how you can create a custom archetype and release it to a Maven repository. In this final part we’ll look at what you need to do to integrate it into your development process. This will involve the following steps:

  • Uploading the archetype and its associated metadata to a Maven Repository Manager.
  • Configuring an IDE to use the archetype.
  • Generating a skeleton project from the archetype.

Step 1 – Upload your archetype

In part 2 we covered releasing and deploying the archetype. For reasons of brevity I simply demonstrated deploying a release to the local file system, but if we wish to share our archetype we must deploy it to a remote repository that can be accessed by other developers. A remote Maven repository, in its simplest form, can be served up using a Http server such as Apache or Nginx. However, these days I would recommend that you use a Maven Repository Manager (MRM) instead, as these tools are purpose-built for serving (and deploying) Maven artefacts. There are basically three options for your MRM – Nexus, Artifactory or Archiva. A features matrix comparision is available here. All are available in open source flavours and both Nexus and Artifactory in particular are great tools. However, currently Artifactory is the only one that supports a Cloud-based service option which, as you might expect, integrates very well with our hosted Continuous Integration service. This allows you to provision yourself a fully-fledged MRM in very short order.

So, how do we add our archetype to the repository? This is a simple process using the built in Artifact Deployer of Artifactory which allows you to upload a file and supply its Maven GAV co-ordinates.

Artifactory Deployer

Artifactory Web-based Deployer

Next, we need to add some additional metadata about our archetype in the form of a ‘catalog’:


<?xml version="1.0" encoding="UTF-8"?>
<archetype-catalog>
  <archetypes>
    <archetype>
    <groupId>com.mikeci</groupId>
    <artifactId>mikeci-archetype-springmvc-webapp</artifactId>
    <version>0.1.4</version>
    <repository>http://mikeci.artifactoryonline.com/mikeci/libs-releases</repository>
    <description>Mike CI archetype for creating a Spring-Mvc web application.</description>
    </archetype>
  </archetypes>
</archetype-catalog>

This file should ideally be placed into an appropriate folder of a Maven repository and it contains information about all of the archetypes that live within the repository. We can simply add this file to our ‘libs-releases’ repository using Artifactory’s REST API:


curl -u username:password -f -d @archetype-catalog.xml -X PUT "http://mikeci.artifactoryonline.com/mikeci/libs-releases/archetype-catalog.xml"

Step 2 – Configure your IDE

Now that our archetype is deployed remotely, we can start to use it from within our IDE – in my case – Eclipse. To get good Maven integration inside Eclipse, you really should be using the latest release (0.10.0) of m2eclipse. Once m2eclipse is installed, it provides a handy feature that allows you to add and remove archetype catalogs. You will need to add your deployed archetypes catalog to the list of catalogs accessible from within m2eclipse. This ensures that you can access your custom archetypes when you run the Create a Maven Project wizard in Eclipse as we will see shortly.

Choose the menu item, Windows>Preferences, to open the Preferences dialog and drill down to the Maven>Archetypes preferences, as shown.


m2eclipse Archetype Prefs

Setting archetype preferences


Click Add Remote Catalog to bring up the Remote Archetype Catalog dialog. In the Catalog File text box, enter the path to your remote catalog file and in the Description text box, enter a name for your catalog:

m2eclipse Remote Catalog

Adding the catalog

Step 3 – Generate your project

You should now be ready to generate a skeleton Maven project inside Eclipse. Choose the menu item, File>New>Other, to open the Select a wizard dialog. From the scrollbox, select Maven Project and then click Next. Follow the wizard to configure your project location. Eventually, the wizard allows you to select the archetype to generate your Maven project. From the Catalog drop-down list, select your custom catalog. Then locate and select your archetype :

m2eclipse Select Archetype

Select the archetype

Click Next and enter the GAV values for your new project. Et voila – you should have just created a skeleton project based upon your custom archetype using a slick IDE wizard.

Pretty impressive, don’t you think?

Announcing our Pricing Plans

February 12, 2010 by

We are pleased to announce that our commercial plans are now available! There are three options:

  • Solo plan, which costs $19 per month. This is, at it sounds, targeted at teams (of up to 5) working on a single project.
  • Multi, $49 per month, includes support for Maven builds and up to 5 projects/10 users
  • Plus, $99 per month, with the same build tool support as Multi but up to 20 projects/30 users

We provide a no-obligation, 30-day trial.You simply need to provide us with your company/project name and an email address. All payments will be securely handled via PayPal should you subsequently wish to sign-up with us.

Please take a look at our pricing page for full details.

All The Young (Ex) Dudes

February 9, 2010 by

As we near the end of beta here at Mike HQ, I’d just like to publicly say a big thank you to all our participants who have helped to shape and improve our platform over the past few months – your feedback has been invaluable.

We are currently in the final phases of testing the version of our platform that will form the basis of our commercial offering. Our acceptance testing work flow involves consuming services provided by other organisations to best simulate a real-world usage scenario for our platform. The primary third party service we use is hosted version control. In fact, it is only reasonable to state that Mike has a strong dependency on the existence of such services. It is the first link in the chain of what we here at Mike HQ refer to as the ‘hosted ALM continuum’ – the suite of co-operating and complementary hosted services that provide agile teams with a full outsourced, web-enabled, development ‘stack’. Disclaimer: it is most definitely in our interest to promote hosted version control solutions, as they are an enabler for the use of our own platform.

So, what do we use for testing?

Well, at present we support Subversion repositories that are accessible over Http(s). To simulate repositories that do not require authentication for read access we use Google Code. For those who are unfamiliar with Google Code (there can’t be that many of you surely?) it provides a free collaborative development environment for open source projects, and provides each project with its own Subversion repository. Thanks, Google.

However, our main scenario is retrieving (or updating) source code from repositories that do require authentication and also provide a secure transport using Https. After surveying the landscape, we decided to trial a service offered by Codesion. At the point we signed up (last year) they were known as CVSDude and they have recently re-branded themselves under a new name. We did like the old name – it has allowed us to indulge in some office banter during our acceptance testing phases, which, lets face it, are often not one of the more exciting aspects of software engineering. I won’t bore you with our banter though as it probably falls into the camp of ‘you had to be there’ to seem even remotely funny.

Codesion web site

Codesion

Setting up a free 30-day trial on Codesion was a cinch:

  1. We swiftly signed up via their website, http://codesion.com/
  2. We created a new project, and added the Subversion service
  3. We created our users, groups, roles (they have a bunch of defaults), and assigned them to our project.
  4. We cut-n-paste’d the SVN URL from the project page, into our SVN import statement and we were done.

At this point we now had data we needed to test our platform – our test fixtures are a range of Java projects of different flavours. A side-effect was that it definitely gave us a view of what a slick SaaS sign-up process and after sales care looks like – something for us to aim for with our own offering. Since we started using them we’ve had zero problems. In some of our test cases we hit the repository repeatedly and it gives us the same reliable service every time.

We’d have no hesitation in recommending Codesion if you are looking for a low-cost, industrial-grade hosted solution for Subversion. But, if you are reading guys, we did slightly prefer the old name….sorry ;-).

Working with Custom Maven Archetypes (Part 2)

January 26, 2010 by

In part 1 of this series of blog entries I demonstrated how you can quickly create a custom Maven archetype. This nice feature of Maven allows you to produce template or skeleton projects, which are great for bootstrapping your development efforts. In this second part of the series, I’ll show you how to ‘production-ize’ your archetype, which involves the following steps:

  • Add your archetype to version control
  • Update the appropriate metadata elements in your archetype’s POM
  • Release your archetype using the maven-release-plugin

Step 1 – Add your archetype to version control

I decided to use Git as the VCS (version control system) for my archetype. This is in part due to the fact that we will soon be releasing a new version of Mike that supports projects hosted on the popular ‘Social coding’ site GitHub. GitHub offers free project hosting for ‘public’ (AKA open source) projects.

So, lets get down to business. First off, you must have the Git client installed of course. If you are on a flavour of *nix this is a cinch, but there is tooling support for other OS’ including TortoiseGit, from the creators of the popular TortoiseSVN client. As there are already plenty of tutorials about using Git, i’m not going to replicate all steps here. Try Git for the lazy if you are time poor, for a good intro.

First up, I navigate to a directory, initialise my Git repository and add my fledgling archetype:


~/foo$ cd mikeci-archetype-springmvc-webapp
~/foo/mikeci-archetype-springmvc-webapp$ git init
Initialized empty Git repository in /home/leggetta/foo/mikeci-archetype-springmvc-webapp/.git/
~/foo/mikeci-archetype-springmvc-webapp$ git add .
~/foo/mikeci-archetype-springmvc-webapp$ git commit -m "Initial commit"
Created initial commit fad815f: Initial commit
 13 files changed, 513 insertions(+), 0 deletions(-)
 create mode 100644 pom.xml
 create mode 100644 src/main/resources/META-INF/maven/archetype-metadata.xml
 create mode 100644 src/main/resources/META-INF/maven/archetype.xml
[...]

Now that i have my archetype added to a local Git repo, I want to share this via GitHub. This obviously requires a GitHub account and you also need to ensure you have added a public key to provide you with the requisite privileges to ‘push’ your changes. Once you’ve set up a bare repository on GitHub, you can execute the following commands:


~/foo/mikeci-archetype-springmvc-webapp$ git remote add origin git@github.com:amleggett/mikeci-archetype-springmvc-webapp.git
~/foo/mikeci-archetype-springmvc-webapp$ git push origin master
Counting objects: 34, done.
Compressing objects: 100% (22/22), done.
Writing objects: 100% (34/34), 21.23 KiB, done.
Total 34 (delta 1), reused 0 (delta 0)
To git@github.com:amleggett/mikeci-archetype-springmvc-webapp.git
 * [new branch]      master -> master

What did I just do? The command remote add origin [url] adds the location of the remote GitHub repository to my local repository configuration and calls it ‘origin’. When I type push origin master this sends or ‘pushes’ my local changes on the ‘master’ branch to the ‘origin’ server. The ‘master’ branch is one that is created by default for me when I initialized the repository above.

Step 2 – Updating the POM

For Maven to function effectively, you should always ensure that you include project VCS information in your POM file. Now that we’ve added the archetype to a Git repository we can include the appropriate <scm> configuration:


  <scm>
   <connection>
   scm:git:ssh://github.com/amleggett/${artifactId}.git
   </connection>
   <developerConnection>
   scm:git:ssh://git@github.com/amleggett/${artifactId}.git
   </developerConnection>
   <url>
   http://github.com/amleggett/${artifactId}
   </url>
  </scm>

It’s important to understand the meaning of each of the child elements of <scm>. The <connection> element defines a read-only url and the <developerConnection> element a read+write url. For both of these elements the url must adhere to the following convention:


 scm:<scm implementation>:<scm implementation-specific path>

Finally, the <url> element content should point to a browsable location and for me this is the GitHub repository home page. Note that in all cases, I’m using an interpolated value which is my project artifactId.

One handy tip is that you can verify this configuration by using the maven-scm-plugin. This plugin offers ‘vendor’ independent access to common VCS commands by offering a set of command mappings for the configured VCS. The validate goal should confirm all is well:


~/foo/mikeci-archetype-springmvc-webapp$ mvn scm:validate
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'scm'.
[INFO] --------------------------------------------------------------
[INFO] Building MikeCI Spring-Mvc web application archetype
[INFO]    task-segment: [scm:validate] (aggregator-style)
[INFO] --------------------------------------------------------------
[INFO] Preparing scm:validate
[INFO] No goals needed for project - skipping
[INFO] [scm:validate {execution: default-cli}]
[INFO] connectionUrl scm connection string is valid.
[INFO] project.scm.connection scm connection string is valid.
[INFO] project.scm.developerConnection scm connection string is valid.
[INFO] --------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] --------------------------------------------------------------

We also have to update the POM to tell Maven (or rather, the maven-deploy-plugin) where to deploy snapshot and released versions of our archetype. For the time being, i’m just going to specify my local filesystem as this destination, but in a real world example this would most likely point to a location appropriate for a Maven repository manager, such as Nexus or Artifactory:


 <distributionManagement>
  <repository>
   <id>release-repo</id>
   <url>file:///home/leggetta/foo/release-repository</url>
  </repository>
  <snapshotRepository>
   <id>snapshot-repo</id>
   <url>file:///home/leggetta/foo/snapshot-repository</url>
  </snapshotRepository>
 </distributionManagement>

Once satisfied with the POM modifications, I commit to my local Git repo and then push the changes to GitHub.

Step 3 – Releasing the archetype

So, i’m now almost ready to create my first early release of the archetype. I can accomplish this using the maven-release-plugin. This plugin exposes two major goals – prepare and perform.
The prepare goal does some pre-flight checking by running a build and verifying all is well before promoting the version in the pom and creating a tag of the release. The perform goal then checks out this tag, builds the project and deploys the resulting artefact to the Maven <repository> specified in your <distributionManagement> section.

Its always a good idea to use the most recent version of the maven-release-plugin, which is currently 2.0-beta-9. This will require a further POM modification and Git commit+push:


 <plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-release-plugin</artifactId>
  <version>2.0-beta-9</version>
 </plugin> 

Next, run the release:prepare goal. By default this runs interactively, prompting you in your shell to provide info about the release version and subsequent development version:


:~/foo/mikeci-archetype-springmvc-webapp$ mvn release:prepare
[INFO] Scanning for projects...
[INFO] --------------------------------------------------------------
[INFO] Building MikeCI Spring-Mvc web application archetype
[INFO]    task-segment: [release:prepare] (aggregator-style)
[INFO] --------------------------------------------------------------
[INFO] [release:prepare {execution: default-cli}]
[INFO] Verifying that there are no local modifications...
[...]
[INFO] Checking dependencies and plugins for snapshots ...
What is the release version for "MikeCI Spring-Mvc web application archetype"? (com.mikeci:mikeci-archetype-springmvc-webapp) 0.1.2: : 
[...]
[INFO] Release preparation complete.
[INFO] --------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] --------------------------------------------------------------

Then run release:perform. If it all goes smoothly, you should have something akin to the following in your remote repository:


~/foo$ ls -1 release-repository/com/mikeci/mikeci-archetype-springmvc-webapp/0.1.2/
mikeci-archetype-springmvc-webapp-0.1.2.jar
mikeci-archetype-springmvc-webapp-0.1.2.jar.md5
mikeci-archetype-springmvc-webapp-0.1.2.jar.sha1
mikeci-archetype-springmvc-webapp-0.1.2.pom
mikeci-archetype-springmvc-webapp-0.1.2.pom.md5
mikeci-archetype-springmvc-webapp-0.1.2.pom.sha1
mikeci-archetype-springmvc-webapp-0.1.2-sources.jar
mikeci-archetype-springmvc-webapp-0.1.2-sources.jar.md5
mikeci-archetype-springmvc-webapp-0.1.2-sources.jar.sha1

So, to summarise, I now have the appropriate configuration management in place to make changes to my archetype and release it to a Maven repository.
In the next part of this series, I’ll look into the different ways you can integrate your archetype into the development process.

Why DVCS won’t kill Subversion in 2010

January 21, 2010 by

At Mike HQ we are currently implementing support for GitHub as this has been requested by a number of our private beta participants. We like Git and are currently undergoing an internal debate/argument as to whether we should switch (no pun intended) to a DVCS from Subversion for our own source code management.

I was going to write something that discussed why, although we might decide to use Git ourselves, it isn’t suitable for everyone – I firmly believe that Subversion usage will continue to thrive in 2010.

However, after searching some, I discovered a comment from this blog entry which more or less summed up my own thoughts. I’m simply going to reproduce it here verbatim (courtesy of clr_lite whoever you are):

  • distributed version control is not for everyone
  • too many people are enamored of a tool or something because it’s new
  • every organization has it’s own situation and needs
  • getting a full repository and allowing people to work in silos without collaboration is not necessarily a good thing
  • git addresses the needs of linux kernel development, with many contibutors funnelling to a gatekeeper
  • some development shops benefit from a locking checkout model which forces developers to communicate and plan
  • subversion has a lot of users and knowledge pool; this can be important for some situations
  • distributed model has it’s plusses; getting all the history, changes, diffs, etc, while offline can be real helpful, but it all depends on the nature of the development and the developers
  • no one tool or process is ‘right’ for everyone

Well put, I thought.

Working with Custom Maven Archetypes (Part 1)

January 14, 2010 by

Late last year we announced support for Maven on our hosted CI platform. This was something we introduced earlier than anticipated as we discovered that the majority of our private beta participants wanted to use this increasingly popular tool for their builds. We also provide support for Apache Ant and Eclipse IDE based projects that don’t include a build.xml or POM file. The rationale behind the latter is to allow developers to get up and running with CI in no time at all. We also released an (open source) Eclipse plugin – mikeclipse – that in its current incarnation allows you to generate a ‘Mike-friendly’ web application project so you can quickstart your development effort. You can create a web app with Struts2 or Spring-Mvc based project flavours. No ‘Mike-specific’ hooks are written in to the generated apps, so you can just use it as a simple wizard to generate a skeleton project. We intend to expand the features of this plugin over the course of the coming months.

Those of you who are familiar with Maven will probably be aware that this generation of skeleton projects is already available via the maven-archetype-plugin. This plugin generates a project based upon a template – called an archetype of course – that you package as discreet Maven (jar) component. Once you have installed or deployed your archetype into a Maven repository it can then be processed by the maven-archetype-plugin. At execution time, if used interactively, the plugin will prompt you with a series of questions about which archetype you wish to use and what, using Maven-ese, the ‘GAV’ (GroupId/ArtifactId/Version) coordinates are for your skeleton project.

I’ve been a user of the plugin for some years now, buts its been a little while since i’ve created a custom archetype, so I thought it might be worth sharing the process I went through to create it. Along the way I discovered some nice features that, at time of writing, did not appear to be fully documented on the plugin site, so I’ve captured them here. I’ll look into creating a issue and/or submitting a patch to the Maven project for these omissions if required later.

Step 1 – Generate Your Archetype

This was a new one for me. Previously I had always hand crafted my custom archetypes, but the plugin supports a goal that allows you to create the basis of your archetype from an existing project – very handy. So I used mikeclipse to create myself a Spring-Mvc skeleton project, did some refactorings to mavenize it – create a POM basically – and executed the following command in my shell


~/foo/example$ mvn archetype:create-from-project
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] ---------------------------------------------------------
[INFO] Building example
[INFO]    task-segment: [archetype:create-from-project] (aggregator-style)
[INFO] ---------------------------------------------------------
[INFO] Preparing archetype:create-from-project
[INFO] ---------------------------------------------------------
[...]
[INFO] Archetype created in target/generated-sources/archetype
[INFO] ---------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ---------------------------------------------------------

This created a first-cut archetype for me in target/generated-sources/archetype that i could now tweak.

Step 2 – Removing redundant files

First thing i needed to was make some small changes to remove some superfluous Eclipse metadata files. This is probably an oversight on my part as i could have generated the archetype after removing these, but since i wanted to view the results of the archetype generation in Eclipse, the plugin had hoovered them up. So I removed them from the archetype-resources sub-directory (under target/generated-sources/archetype) and also edited the two archetype descriptor files under archetype-resources/META-INF/maven. I believe that two files are created to ensure backward-compatability with earlier versions of the archetype plugin – i was using the 2.0-alpha-4 release which supports the new archetype-metadata.xml format descriptor. For example, I removed the following entry from archetype-metadata.xml after deleting the files:


  <fileSet filtered="true" encoding="UTF-8">
     <directory></directory>
     <includes>
        <include>.project</include>
        <include>.classpath</include>
     </includes>
  </fileSet>

Step 3 – Fixing Velocity warnings

Under the hood, the archetype plugin uses Apache Velocity to do its file filtering – for example, the substitution of the GAV values I discussed above. Those who have used Velocity will be aware that it can be quite verbose in its output, especially when it encounters syntax that resembles a filterable value. This manifests itself in warnings like the following when you generate a project using your archetype (I’ll cover that process shortly):


   [WARNING] ... : ${mvnVersion} is not a valid reference.

While this warning does not materially affect what gets generated it doesn’t build confidence in your archetype as it will be one of the first things your users will see. So lets see how we can fix this. In my case, its due to the fact that my template POM contains a number of properties that I don’t want to be filtered and should be left intact as part of the generation. This is not an uncommon problem with POM’s – they often contain properties that allow a runtime interpolated value to be changed in one place. We can use some simple Velocity syntactical sugar as follows. Declare the following directive at the top of your template pom.xml file under archetype-resources


  #set( $symbol_dollar = '$' )

Then, wherever you declared a property that you want to be ‘ignored’ by Velocity do something akin to the following


  <requireMavenVersion>
    <version>${symbol_dollar}{mvnVersion}</version>
  </requireMavenVersion>

Step 4 – Filtering a filename

One of the nice features in the latest version of the archetype plug-in is the ability to re-name files during the generation process. In my scenario, I want to use this feature to ensure that my Spring servlet descriptor matches up with the associated declaration in my web.xml file. However, I did have to do a little digging to find out how to do this via the plugin JIRA as when I looked it did’nt jump out from the plugin web site examples or usage pages. Anyways, its pretty simple to do. Just create the template file using the filterable property as part of its name, using double underscores as token separators. In my case:


  $ mv src/main/webapp/WEB-INF/example-servlet.xml \
  src/main/webapp/WEB-INF/__artifactId__-servlet.xml

Step 5 – Install and invoke the archetype

A quick local installation is simply accomplished by running an mvn install inside the target/generated-sources/archetype directory.

The install creates a metadata file under ~/.m2/ called archetype-catalog.xml.


~/.m2$ cat archetype-catalog.xml
  <?xml version="1.0" encoding="UTF-8"?>
  <archetype-catalog>
   <archetypes>
    <archetype>
     <groupId>com.mikeci</groupId>
     <artifactId>example-archetype</artifactId>
     <version>1.0-SNAPSHOT</version>
     <description>example-archetype</description>
    </archetype>
   </archetypes>
  </archetype-catalog>


Once installed I can invoke it using the archetype:generate goal. By default this will search the public archetype catalog from the Maven central repositories and display all the available ones plus my local one. To tell the plugin to only search my local Maven repository I can use a simple mojo parameter as follows:


~/foo$ mvn archetype:generate -DarchetypeCatalog=local
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] --------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO]    task-segment: [archetype:generate] (aggregator-style)
[INFO] --------------------------------------------------------------
[INFO] Preparing archetype:generate
[...]
Choose archetype:
1: local -> example-archetype (example-archetype)
Choose a number:  (1): 1
Define value for groupId: : com.acme
Define value for artifactId: : mywebapp
Define value for version:  1.0-SNAPSHOT: :
Define value for package:  com.acme: :
Confirm properties configuration:
groupId: com.acme
artifactId: mywebapp
version: 1.0-SNAPSHOT
package: com.acme
Y: :
[INFO] --------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] --------------------------------------------------------------

Then finally:


~/foo/mywebapp$ mvn package jetty:run -P mikeci,itest
[INFO] Scanning for projects...
[INFO] --------------------------------------------------------------
[INFO] Building example
[INFO]    task-segment: [package, jetty:run]
[INFO] --------------------------------------------------------------
[INFO] [enforcer:enforce {execution: enforce-versions}]
[...]
[INFO] Started Jetty Server

Et voila, my browser displays the simple landing page for the generated web app:

Obviously, I’ll need to subsequently take the generated archetype code and turn it into a proper project in its own right, add it to version control and ultimately deploy/release it to a Maven repository so it can be shared. I’m planning on using Github for the VCS (or SCM in maven-ese) as we are currently working on adding Git support to Mike. I also want to see how the maven-release-plugin handles Git. I’ll cover these topics in the next part of my blog.

Adam