Archive

Posts Tagged ‘maven’

Managing POM versions

July 26th, 2010 Nicolas Frankel No comments

This article won’t be long but can be a lifesaver. If you use Maven, how many times did you need to manually update POM versions in an entire modules hierarchy? For me, the answer is: “too many”.

When you project grows to include many Maven modules, releasing a new version can be a nightmare. Sure, you have the maven-release-plugin. It does many things under the cover but in some cases, I saw it fail. What do you do then? You manually change your POM version in your modules hierarchy:

  • the version of the module’s POM
  • the version of the parent’s POM

It’s not only a boring taks, it’s also an error-prone one. Imagine my surprise when I found the maven-version-plugin and its little jewel of a command line:

mvn versions:set -DnewVersion=1.0.1-SNAPSHOT

And presto, the plugin does it all for you, entering each module and changing the previous informations:

[INFO] [versions:set]
[INFO] Searching for local aggregator root...
[INFO] Local aggregation root: D:\workspace\Champion Utilities
[INFO] Processing ch.frankel.champions.license:license
[INFO]     Updating project ch.frankel.champions.license:license
[INFO]         from version 1.0.0 to 1.0.1-SNAPSHOT
[INFO]
[INFO] Processing ch.frankel.champions.license:license-check
[INFO]     Updating parent ch.frankel.champions.license:license
[INFO]         from version 1.0.0 to 1.0.1-SNAPSHOT
[INFO]     Updating project ch.frankel.champions.license:license-check
[INFO]         from version 1.0.0 to 1.0.1-SNAPSHOT
[INFO]
[INFO] Processing ch.frankel.champions.license:license-common
[INFO]     Updating parent ch.frankel.champions.license:license
[INFO]         from version 1.0.0 to 1.0.1-SNAPSHOT
[INFO]     Updating project ch.frankel.champions.license:license-common
[INFO]         from version 1.0.0 to 1.0.1-SNAPSHOT
[INFO]
[INFO] Processing ch.frankel.champions.license:license-generation
[INFO]     Updating parent ch.frankel.champions.license:license
[INFO]         from version 1.0.0 to 1.0.1-SNAPSHOT
[INFO]     Updating project ch.frankel.champions.license:license-generation
[INFO]         from version 1.0.0 to 1.0.1-SNAPSHOT

Give it a try, it’s a real powerful yet easy!

Categories: Java Tags:

DRY and skinny war

April 21st, 2010 Nicolas Frankel 1 comment

In this article, I will show you how the DRY principle can be applied when using the skinny war configuration of the maven-war-plugin.

While packaging an EAR, it is sometimes suitable that all libraries of the different WARs be contained not in their respective WEB-INF/lib folders but at the EAR level so they are usable by all WARs. Some organizations even enforce this rule so that this is not merely desiarable but mandatory.

Using Maven, nothing could be simpler. The maven-war-plugin documents such a use case and calls it skinny war. Briefly, you have two actions to take:

  • you have to configure every WAR POM so that the artifact will not include any library like so:
    <project>
      ...
      <build>
        <plugins>
          <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <configuration>
              <packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
              <archive>
                <manifest>
                  <addClasspath>true</addClasspath>
                  <classpathPrefix>lib/</classpathPrefix>
                </manifest>
              </archive>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </project>
  • you have to add every dependency of all you WARs in the EAR

The last action is the real nuisance since you have to do it manually. In the course of the project, a desynchronization is sure to happen as you add/remove dependencies from the WAR(s) and forget to repeat the action on the EAR. The DRY principle should be applied here, the problem lies in how to realize it.

There’s an easy solution to this problem: if a POM could regroup all my WAR dependencies, I would only have to draw a dependency from the WAR to it, and another from the EAR to it and it would fulfill my DRY requirement. Let’s do it!

The pomlib itself

Like I said before, the pomlib is just a project whose packaging is POM and that happens to have dependencies. To be simple, our only dependency will be Log4J 1.2.12 (so as not have transitive dependency, let’s keep it simple).

The POM will be:

<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>
  <parent>
    <groupId>ch.frankel.blog.pomlib</groupId>
    <artifactId>pomlib-parent</artifactId>
    <version>1.0.0</version>
  </parent>
  <artifactId>pomlib-lib</artifactId>
  <packaging>pom</packaging>
  <dependencies>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
    </dependency>
  </dependencies>
</project>

Like for any other project module, I put the versions in the parent POM.

The EAR and the WAR

Both should now add a dependency to the pomlib. For brevity, only the EAR POM is displayed, the WAR POM can be found in the sources if the need be.

<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>
  <parent>
    <groupId>ch.frankel.blog.pomlib</groupId>
    <artifactId>pomlib-parent</artifactId>
    <version>1.0.0</version>
  </parent>
  <artifactId>pomlib-ear</artifactId>
  <packaging>ear</packaging>
  <dependencies>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>pomlib-lib</artifactId>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>pomlib-war</artifactId>
      <type>war</type>
    </dependency>
  </dependencies>
</project>

Likewise, versions are put in the parent POM. Notice the import scope on the pomlib dependency, it’s the only magic.

Using mvn install from this point on will put the log4j dependency at the root of the generated EAR artifact and not in the WEB-INF/lib folder of the WAR.

Conclusion

Now that all dependencies are described in the pomlib, should you need to add/remove a dependency, it’s the only place you’ll need to modify. With just a little configuration, you’ve streamlined you delivery process and saved yourself from a huge amount of stress in the future.

By the way, if you use a simple Servlet container (like Tomcat or Jetty) as your development application server, you could even put the skinny war configuration in a profile. Maven will produce “fat” WARs by default, at development time. At delivery time, just activate the profile and here’s your EAR product, bundling skinny WARs.

You can find the source of this article in Maven/Eclipse format here.

Categories: Java Tags: ,

Maven The complete reference

February 3rd, 2010 Nicolas Frankel 2 comments

This review is about Sonatype’s Maven: The complete reference by Tim O’Brien, John Casey, Brian Fox, Jason Van Zyl, Eric Redmond and Larry Shatzer.

Disclaimer: I learned Maven from Sonatype’s site 3 years ago. I found it was a great tool to learn Maven. Now that I have a little more experience in the tool, I tried to write this review in an objective manner.

Facts

  1. 13 chapters, 267 pages, free (see below)
  2. This book is intended for both readers who wants to learn Maven from scratch and for readers who need to look for a quick help on an obscure feature
  3. A whole chapter is dedicated to the Maven assembly plugin
  4. Another chapter is dedicated to Flexmojos, a Sonatype plugin to manage Flex projects

Pros

  1. First of all, this book is 100% free to view and to download. This is rare enough to be state!
  2. Complete reference books are sometimes a mere paraphrase of a product’s documentation. This one is not. I do not claim I’m a Maven expert but I did learn things in here
  3. This book is up-to-date with Maven 2.2. For example, it explains password encryption (available since Maven 2.1.0) or how to configure plugins called from the command line differently using default-cli (since Maven 2.2.0)
  4. A very interesting point is a list of some (all?) JEE API released by the Geronimo project and referenced by groupId and artifactId. If you frown because the point is lost on you, just try using classes from activation.jar (javax.activation:activation): you’ll never be able to let Maven download it for you since it is not available in the first place for licensing reasons. Having an alternative from Geronimo is good, knowing what is available thanks to the book is better

Cons

To be frank, I only found a problem with Maven: The complete reference. Although a whole chapter is written on the Maven Assembly plugin, I understood nothing from it… The rest of the book is crystal clear, this chapter only obfuscated the few things I thought I knew about the plugin.

Conclusion

This book is top quality and free: what can I say? If you’re a beginner in Maven, you’ll find a real stable base to learn from. If you need to update your knowledge, you will find a wealth of information. If you’re a Maven guru, please contribute to the Assembly plugin’s chapter. I can only give a warm thank you for Sonatype’s effort for giving this quality book to the community.

Categories: Book review Tags: ,

Apache Maven 2 Effective implementation

December 5th, 2009 Nicolas Frankel 1 comment

Apache Maven 2 Effective implementation
This review is about Packt’s Apache Maven 2 Effective Implementation by Maria Odea Ching and Brett Porter.

Facts

  1. 12 chapters, 436 pages, 39.99$
  2. This book is intended for people that already have a good experience of Maven. The ‘About Maven’ part is as small as it can get, it is the opposite of what could be ‘Maven for Dummies’, where you learn to type mvn something.
  3. A good portion of the book is about tools that are part of the Maven ecosystem: Continuum for the CI part and Archiva for the repository part.
  4. A chapter is dedicated to testing, which test to pass automatically, what frameworks to use and how to configure the whole lot.

Pros

  1. People that wrote the book really know Maven intimately and it shows. I’m not a newbie myself and I learned some things that I have put to good use since then (or intend to in the near future).
  2. There’s an interesting multi-module structure described that is designed for big projects. It shows Maven structure can be quite adaptable and module design should be custom tailored to each project’s needs. A module for each layer / artifact is only the first step.
  3. The part about Maven plugins is very interesting. Since Maven adopts a plugin architecture, knowing what plugins can do what, why and how to use it is invaluable.
  4. So is the part about testing: a good idea is that some tests should not be passed everytime, but instead launched manually or attached to a specific module.

Cons

  1. The tools used are Continuum and Archiva but there’s no justification for this choice. One could think that’s because they’re both Apache but that’s just not enough. Java.net’s Hudson seems the most used CI server and Sonatype’s Nexus is the reference for Maven repositories (although I have a soft spot for JFrog’s Artifactory).
  2. What I regret most is the part taken by reporting. My personal stance on this is that only very few organizations use these features, mainly Open Source organizations. Since you now have products such as Sonar, describing in detail how to configure Maven reporting is a waste of time. Since the book is already oriented toward tools, why doesn’t it just teach how to use Sonar (since it cites Sonar anyway)?

Conclusion

All in all, Apache Maven 2 Effective implementation is not a great book but rather a good book to have when you already worked with Maven so as to stand back a little and build your projects more effectively with Maven in the future.

Categories: Book review Tags: ,

Top Eclipse plugins I wouldn’t go without

August 8th, 2009 Nicolas Frankel 4 comments

Using an IDE to develop today is necessary but any IDE worth his salt can be enhanced with additional features. NetBeans, IntelliJ IDEA and Eclipse have this kind of mechanism. In this article, I will mention the plugins I couldn’t develop without in Eclipse and for each one advocate for it.

m2eclipse

Maven is my build tool of choice since about 2 years. It adds some very nice features comparing to Ant, mainly the dependencies management, inheritance and variable filtering. Configuring the POM is kind of hard once you’ve reached a fairly high number of lines. The Sonatype m2eclipse plugin (formerly hosted by Codehaus) gives you a tabs-oriented view of every aspect of the POM:

  • An Overview tab neatly grouped into : Artifact, Parent, Properties, Modules, Project, Organization, SCM, Issue Management and Continuous Integration,
  • m2eclipse Overview tab Read more…