jueves, diciembre 01, 2011

All my scientists are working on a deadline, So my psychologist is working day and nighttime, They say they know what's best for me, But they don't know what they're doing (Atomic Garden - Bad Religion)

Maven archetypes are project templates that allow users create project structure with a simple Maven command. In my company we are using archetypes because provide a way to standardize projects structure. All our projects are built using the same directory structure, all of us use the same version of common libraries like JUnit, Hamcrest, Spring Framework, Mockito, or in case of web applications bundling them with company's approved CSS and Javascript libraries. Also PMD, checkstyle or findbugs coding rules can be stored in distributed archetype.

If each time you start a new project you are of those who copy files from existing projects to the new one, apply DRY principle and create a Maven archetype from existing project.

First thing to do is create your template project with all files to be bundled into archetype. In this example, simple Spring MVC project will be transformed  to be a Maven archetype.

After template project is created and all desired files are added, you should have a directory layout like:

My personal advice is that if you are thinking about distributing this archetype with community (not only for your company), remove all IDE specific files.

Now you have your project created and ready to be packaged as archetype. Execute next command on root of your project.
mvn archetype:create-from-project
And Maven console output should be:

And now your archetype is created in target/generated-sources/archetype directory with next hierarchy:

Now project is inside archetype-resources directory. This directory contains all files that will be added in generated project.

At first sight, not much differences between original project and "template" project, it seems that only three files has been added archetype-metadata.xml, archetype.properties and goal.txt, but shortly you will see that original project content has been modified too.

Before continuing see that in project exists two poms, one pom that is in root directory, that will be called archetype pom, because it contains all archetype configuration, and another one into archetype-resources, called template pom, because it will be the pom used in generated project.

Next step is isolate archetype project into separate folder, so can be dealt as alone project.
mv target/generated-sources/archetype ../spring-mvc-archetype

Following step is adding a name to generated archetype, so open archetype pom and change  <name> tag value to your archetype name, for example spring-mvc-archetype, and if you want  artifactId and groupId too.

After this modification, open archetype-resources' pom, and see how <artifactId> or <groupId> values are surrounded with ${artifactId} or ${groupId}. When you are creating a new archetype, by default Maven will ask you to enter four parameters, groupId, artifactId, version and package. Entered values will be used to fill placeholders.

With default four parameters should be enough, but imagine you want that user provides more information, for example, war name. To get this, open archetype-metadata.xml file (src/main/resources/META-INF/maven) and add one required property, using <requiredProperties> tag.

In previous file we are adding a new required property named warName. And last thing to do is update
archetype.properties located on test/resources/projects/basic with default value of new property.

And that's all, if you open any Java class or any Xml file, you will see that has been modified with ${package} variable. This information is filled when you generate the project.

Now you can install archetype into your local catalog and start generating standardized  projects.
mvn clean install
And your artifact is ready to be used. Try next command or if you have installed m2Eclipse plugin open Eclipse and try your new archetype:
mvn archetype:generate -DarchetypeCatalog=local
A list of all installed archetypes is shown. Choose previously created and fill up all required properties, and your new project is built and configured. You can start coding with same libraries that your workmates use and same style rules.

In this post a simple example has been provided, but think about all kind of elements that you copy and paste from one project to another like SCM connection, surefire plugin configuration, release plugin tag name, to cite a few, and how you can integrate them into your archetype.

I wish you have found this post interesting.

Music: http://www.youtube.com/watch?v=AhzhiQA6-Aw&ob=av3e

6 comentarios:

Anónimo dijo...

Nice article, thanks! Some of the common functionality you mentioned could be moved into a parent .pom that all of your projects inherit from; dependency versions can be declared in dependencyManagement for example.

Alex dijo...

Thank you very much for reading my blog, I agree with you that some functionality should be moved to parent pom. In fact I wrote about this http://alexsotob.blogspot.com/2011/03/que-rabia-que-ternura-ser-el-sol-y-la.html

Also you can modify an archetype so parent pom structure is also created by during project generation.

Again, thank you very much for reading my blog.

byteslash dijo...

Very good article. Perhaps you could make it even more interesting by adding more how to create maven templates for the top 5 most used java frameworks! how about that?

best regards

Alex dijo...

Thank you very much for your comments, in fact exists many archetypes http://docs.codehaus.org/display/MAVENUSER/Archetypes+List

Moreover I have created one to work with Thymeleaf template engine, but before deliver it, Thymeleaf creator and me, are checking that all features work perfectly.

Thanks for reading my blog.


Javier dijo...

Great article, this is what we need in my company.

We're trying Spring Roo, but not everybody likes it.

However, a common structure is required, for instance, to migrate old projects to a new structure.


P.S.: I liked a lot the reference to Bad Religion lyrics.

Alex dijo...

Javier, thank you so much for your comment, I agree with you that Spring Roo is a really nice tool but of course not everybody can be feel comfortable with it.

A basic structure is required across all company and Maven archetypes could help you of course.


Donate If You Can and Find Post Useful