Saturday, May 22, 2010

Projects in Java with Maven 2

 

For those of you who don’t know Maven is a build tool/dependency manager/project model. Those in the Microsoft space can probably imagine MSBuild + the ability to download all dll’s for you.

What I liked

  1. Dependency Resolution. Automatic downloading of dependencies rocks in concept. Just specify library name and version and when you compile again it’s there.  No need to check in jar’s into your source tree.
  2. IDE Independence. In practical terms lets you use whatever IDE you want with no import/export.  Intellij, Eclipse and Netbeans all understand maven as a full project format. So your team can all have different IDE’s and not create havoc with one another.
  3. Good Default Project Structure. Tests are in the same location by default, resources for tests and your prod code are in expected places.

What I hated

  1. Inefficient with already downloaded dependencies. It will check remote repositories every time you build even when you specified version number. Now I can see why they did that but not as a default. I mean sure version 1.12 may have had a bad bug and the project hotfixed in a new one with the same version number, but I’d say that’s really unlikely.  In a larger project with several repositories the difference in time to build between this and an alternate dependency manager Apache Ivy is stark.
  2. Very opinionated view of the build process. Those of you used to (N)Ant or Rake will miss the lack of control. The AntRun plugin will help mitigate some of the lose of control.
  3. HOME/.m2/settings.xml . Specific system wide settings do not belong in a build language. The bad heavy friction ideas that it enabled were legion. Just one example was I had to connect to my work VPN even when working on my home OSS projects hosted on github.
  4. Way too XML for for sometimes simple things. To specify the version of java target language version see the figure below, this specifies Java 1.6.

 


<build>

  <plugins>

    

    <plugin>

      <artifactId>maven-compiler-plugin</artifactId>

      <configuration>

        <source>1.6</source>

        <target>1.6</target>

      </configuration>

    </plugin>

    

  </plugins>

</build>


Summary

If you have a cross IDE team or are running an OSS java project I find it very hard to ignore Maven. If you are looking for easier dependency management, less verbose build files, and do not care about IDE independence I suggest any number of alternatives such as Apache Buildr, Apache Ivy, Gradle or many others I’m sure I’m forgetting.

3 comments:

duality72 said...

Some comments on your problems:

1. This shouldn't be happening. Any explicit version like 1.12, once it's found locally, is not checked again against the remote repos. Even SNAPSHOT versions like 1.12-SNAPSHOT are only checked against the repo once every 24 hours. Those are the defaults, anyway; you can override them locally. You should take a closer look here to see what the problem is.

2. It is opinionated, but arguably that's a good thing. Developers tend to hate it because it's harder to add whatever crazy build step you want for a short-term fix, but that's good for the build engineers and putting thought into the process and doing it right for the long-term.

3 & 4. You probably could have avoided some of this with project-specific settings and having a good base project pom.xml with settings can help minimize some of the heavy XML.

Anyway, sounds like you're off to a good start, so hopefully this helps. If you haven't checked out the free e-books at Sonatype and Maestrodev, I encourage you to do so.

http://www.sonatype.com/products/maven/documentation/book-defguide

http://www.maestrodev.com/better-build-maven

Ryan Svihla said...

First thanks for the feedback and the helpful links. The rest is my response to your specifics.

1. I'll need to checkup why I was seeing this. It struck me as slow and painful.

2. Respectfully, this still smacks of barriers for barriers sake. I've been the "build engineer" on enough projects to know the stuff I want to do in maven takes little time in something like Rake, Bake or Phantom, AND more importantly with a lower learning curve. Preference is obviously a key here, but I struggle to find the specifics of what entails "right for the long term" and where a maven plugin makes that happen.

3. I agree. I think we had a bad implementation. Still I could use some of that opinionated thinking here that was mentioned in problem 2.

4. I disagree. Source target is something I do put in my parent pom and it's still entirely too much extra ceremony for a very simple thing. Compare that build plugin fragment in my post to gradle's equivalent:

sourceCompatibility = 1.6

Why should maven have so many more elements to have the equivalent. Even for a XML dialect it is still way to wordy at times.

duality72 said...

I'm not saying you don't have some valid points, but that you put build engineer in quotes is telling.