Wednesday, March 04, 2009

Maven vs Ant+Ivy

Choosing a right build management tool is important for any software development process.

The most important thing a build management tool should provide is improved productivity of the development team. Developers have to deal with the build management tool on day to day basis. If the build management tool is not right for the team, it will create frustration in the team members which may result in not so good position for the project.

One tool can not fit every team and every project. The right tool must be chosen based on its audience and the project requirements.

I think most developers from Open Source and Java community prefer command line based tools such as ANT or Maven. These tools are flexible (easy to enhance), scriptable (and hence can be automated). These avoid dependency on any IDE and can be used from a remote terminal.

In some cases, however, depending on the type of project and team, IDE can be a better build tool. It offers click and build features. Debugging is, I think one of the biggest feature of using an IDE. This will be a natural choice for people from Microsoft background. If the team has most of such developers, don't try to push command line based tools on them. The migration should be gradual.

I prefer to use non-ui based build tools.

I had been using ANT for past many years and simply loved it. ANT scripts are very simple to develop and use, and develop. It is also very simple to understand and follow its execution. It has very good documentation and consistent way of doing things. Despite its simplicity ANT is very flexible.

However, everytime I start a new project, I had to create a new script (not fun). I had to download all the libraries that I will need in the project, put them in some folder. I also need to understand the dependencies between these different libraries. Now I need to modify ANT script to manually manage the dependencies and blah blah blah....too much pain.

Doing the above was fun for first few times but when I had to do it again and again, I started to dislike it.

Moreover, all IDEs, despite their claims, don't have good integration with ANT. People will say, hey Eclipse, NetBeans, IntelliJ etc. can import ant based projects and can build using ANT script. But none of these IDE can understand the library dependency defined in the ANT script. As a result, I can't trust IDE to resolve classes and code completion. What a shame.

Last year, I was introduced to the wonderland of Maven. After some initial learning curve, I became comfortable with it and I really started to like it.

Maven gives you library dependency management (the biggest pain in ANT). It can automatically create default project directory structure and initial pom.xml based on the type of project you create. It has concept of project build life-cycle and even without modifying the default script, you can build and release the project.

You can have multi-module project and create dependencies between them. When doing a build on multi-module project, it can automatically identify the correct sequence of building module.

Wow Maven is a wonderful tool. It does so much for you. I don't need to download libraries that I use (at least most of them). I can simply define dependency in the maven script and all the required libraries (including transitive dependencies) are downloaded during Maven build.

Eclipse and Netbeans also support Maven and understand library dependencies defined in the Maven script.

And then...

As I worked more with Maven, I realized that Maven is not flexible at all. Although, it offers so many features but does not allow me to anything unconventionally.

For example everything part of the script has to fit within the Maven project lifecycle. Let's say if I want to start http tunnel for monitoring the traffic. How do I do that? Starting an http tunnel is not part of project life cycle. May be it is...some people will argument...but some things don't have to be perfect....they have to be simpler and flexible...At the end of the day getting things done and done faster is all that matters.

I can not use any library outside of Maven repository. If some library is not available in any Maven repository, Maven guide tells me to put that library in local Maven repository manually. That is not cool. In this case I can not distribute my code among my team members. Assuming that there is no local central repository, everybody in my team will have to add the library manually. I don't like that.

As far as writing a script is concerned, I complained about ANT before. However, I should have also mentioned that the ANT script notations and structure are so simple and consistent that I can almost always write the initial ANT script (compile, run, clean javadoc deploy etc) without referring to any documentation.

I can not say the same thing for Maven. Even if all I need to do is enable Java 5 compatibility in my Project, I have to refer to it's documentation (who remembers name of all the plugins, group id, version numbers blah blah blah).

(I should also say....what the hack....Java 7 is due pretty soon and Maven assumes that the new projects are going to use Java 1.3 ???????..very annoying)

As other people described about Maven, it is like a black magic. It magically does too much stuff for you...How....you don't know....You have no idea what it did underneath but it was done. May be it is good thing for some people but I found it very annoying. When it does not work, it is very difficult to follow through its execution and discover problems.

Maven tries to force you to do things like the Maven way, while ANT allows you to do things your way.

With Maven, you are like a lion in a cage. You are enjoying tasty food everyday but are not free to go anywhere. With ANT you are like a lion in a jungle. You are free; you can do anything but you have to hunt for your own food and sometimes you may not even find one.

Each project is different. The environment and the constraints are always different in each project and there is no single solution to all of them.

Each project may have different needs and may not fit into perfect life cycle and the project structure of Maven.

Ant provides the flexibility. With Ant you really need are plugins that provide Maven features without Maven restrictions.

One of the biggest feature of Maven IMHO is dependency management. Apache Ivy adds this feature to ANT.

Apache Ivy is very similar to Maven in dependency management. You define project's library dependencies in ivy configuration file, add its reference in the ANT script and that's pretty much it.

Apache Ivy can also understand Maven repository.

The ANT + Ivy allows you to mix repository based libraries and non-repository based libraries. I can put non-repository based libraries in a special folder in the project and reference it in ANT.

The good thing about this solution is that it provides you dependencies management while enjoying the freedom of ANT as opposed to caze of Maven.

It gives you controlled, predictable, transparent solution with no surprises. And that is exactly what I want.

However you should also remember that there are still certain nice features about Maven that are not provided by ANT +Ivy solution (such as project life cycle management, integration with central repository+version control system, ability to publish/release projects just to name a few).

These features are, though easily implementable, have to be developed in-house.

One more thing, Eclipse has good integration with Ivy. Netbeans lacks such integration. Well..I think we will see this soon.

Because of the flexibility ANT ( + Ivy) will be my first choice for the time being.

I would also like to see a plugins/features can auto-create IDE independent ANT script and project directory structure for well known projects (should be pluggable so that people can contribute more project types)...similar to artifact-type in Maven.