Wednesday, March 07, 2012

Moving from Ant to Maven

I have to admit that I have not used Maven a lot until perhaps mid last year, when I realised how difficult it is becoming to maintain dependencies and builds for J2EE projects using Ant. Many of my colleagues were faced with same problems but most of them still choose to stay with Ant.

Ant was here, it seems, forever. It is well established and mature product and almost all developers understand it and know how to finish the job with it. On the other hand, when Maven came on the first look it seems that developers could not define explicitly what needs to happen when building the project (or at least this was my experience). Everything was implicit with an option to override the default settings. This was a confusing part opposing to the Ant where you needed to define everything explicitly. Not all understood what a project lifecycle was and why it was important. What Maven is today is described here, "What is Maven".  In simple words, these are few benefits that Maven provided to me:
  • Default setting out of the box with need to change build and deployment setting where needed
  • Dependency management, where if I need one dependency, Maven will automatically include all other needed dependency files and will exclude conflicted dependencies
  • Ability to define which dependencies are used for deployment and which are used for test (for example, you need to start in memory database for unit tests and do not want to deploy those jar files to production)
  • If we want to change version of the main dependency, all other relative dependencies will be updated automatically
  • Standardizes project builds through build lifecycle
  • Allows easy separation of code and unit tests

Maven does a lot more, but if we take only items listed, it will be clear how much more your life will become easier. One of the major problems in switching to Maven is how we are thinking about referenced projects (for example if we have dependencies on other projects in the workspace). Maven will not support this (there are workarounds but the only proper way is to create local repository). Maven needs to work with artifacts (basically versions of jar files). To achieve this, all you need to do is to setup in-house Maven repository (for example Sonatype Nexus or Artifactory from JFrog Artifactory) for local files and proxy repositories that are on the Internet. This will enable you to have you own repository with your artifacts (libraries). Many developers will usually avoid this (versioning) as when including them with it would mean that every time they change library project updates with dependencies will need to happen (for every library). On the other hand, working with same version would help avoid updating references. Developers would usually track libraries in the version control systems (or similar) where files are always given the same version under a different release. This, of course, has to change if we want to use Maven, and we need to start versioning the libraries and then uploading them to a local Maven repository. Then we can start including those dependencies in our project, but not as a referenced projects, but as a Maven dependencies. In the case that we need a quick build of the library, we can always install it in our local repository (in Win 7 \Users\User\.m2). This way, it will become available to be included in a project that needs this dependency and later on, it can be published in centralized repository for the rest of the team. This, of course, requires change of culture in the organization. In the end, it pays off big time.

One of the other problems developers are faced with is setting up local environment when starting a new development and making it easy to start being productive (business-wise) and not spending time resolving technical issues with environments and dependencies. Maven does this in an easy way. It not only saves you trouble of uploading you jar files to CVS or SVN, it has different plugins (like Eclipse plugin) that can start projects very easily and where it will setup dependencies from repository based on what is in the pom.xml file. Try it one, and you will never go back to Ant.

So basically, for Maven to work correctly, we need correct directory structure and correctly setup pom.xml file. For directory structure, you can reference this Maven directory layout and for POM setup, this Maven POM. Please note that POM can be simple as just as adding a few lines to describe your artifact and group. (This is like the project name and the package). If you have, for example, m2e plugin for Eclipse, you can see an example of Effective POM that will have a lot of information that you can use to customize your POM. It is up to you how much customization you want or need.

In my experience, even though Maven has an Ant plugin, mixing two of them is not a good idea as it might interfere with Maven build lifecycle (Maven build lifecycle).

And for the end, just to mention that Maven helps with one of the biggest problems that developers have when debugging the code. What happens when the source code from the 3rd party libraries is missing? Maven gets this for you automatically. That means that you can now see what you are debugging when going in depth to figure out you problems.

Please note that this text was written in very simple terms and if you would like to fully understand how Maven works, please refer to Maven site for further documentation. This article is not comparison of Ant vs Maven, but rather it reflects on benefits of having Maven builds in your environment. All projects can be built with both Maven and Ant.