I'm an author and a developer focused on build tools. I'm currently focusing on Gradle, but I have an interest in all build tools and most development infrastructure. I focus on Enterprise Java, Ruby, and the interface between Systems Administration and Software Development. The focus of my work is to make it easier for individuals to adopt open source software. Tim is a DZone MVB and is not an employee of DZone and has posted 41 posts at DZone. You can read more from them at their website. View Full User Profile

How to Migrate from Ant to Maven: Project Structure

08.25.2010
| 13401 views |
  • submit to reddit

I’ve seen my fair share of projects migrating from Ant to Maven, and, for a complex project, this migration path can take some time. You have to worry about dependency management, project structure, and retraining an existing team to use Maven and understand the core concepts behind the tool. When you make the shift, you are often affecting development infrastructure for an existing project, and you need to take into account development environments as well as developer’s ideas about how code should be organized and stored in source control. In this post, I’m going to discuss a common pattern I’ve seen in Ant to Maven migrations: how to migrate the monolithic project.

A Common Pattern: The Monolithic Project

Ant projects which have evolved over many years often lack modular structure. While it is certainly possible to create the equivalent of a multi-module Maven project in Ant, the usual progression in an Ant project is to store all of your source in a single tree and use extra targets to selectively compile different packages. This approach is shown in the following figure.

In the most extreme cases, there is a single project which contains an array of modules. Maybe you have an entire enterprise system all stored in a single project alongside a complex Ant build.xml file which contains a collection of tasks for each component. A monolithic Ant project usually produces a series of artifacts: a JAR containing some API for clients, a server-side web application, a utility library, etc. Developers have usually grown so accustomed to this approach that the idea of splitting up a complex system into a series of related submodules can see daunting.

Moving to Maven: Do we need all these projects?

One of the first questions I get in a Maven migration from Ant is whether it is really necessary to modularize a project. “Do we really need to create all these projects for Maven?” (Short answer: Yes, there is no avoiding this.) This is usually accompanied by a concern that Maven limits each project to producing a single artifact. These are two core assumptions of Maven: your projects will be modularized and each project should produce a single build artifact.

Now, while these are core assumptions, there are ways around them, and I’ve even seen people go to extreme lengths in an attempt to preserve this single, monolithic project. You can create an elaborate set of profiles to modify the build depending on the context in which it is run, and you can attach extra build artifacts to a project using assemblies. Even though Maven makes assumptions about code layout and project structure, it can do just about anything, and in this case, it can be used to approximate the monolithic, combined Ant project.

If you do this, if you try to trick Maven the first thing you’ll notice is that your monolithic project’s POM is going to be somewhat unwieldy: it is going to be massive. Instead of a simple, declarative picture of a project, you are going to have a POM that contains multiple assembly definitions. Each assembly definition is going to have to explicitly define the structure of your build artifacts and you are going to find yourself venturing into includes and excludes patterns for things like the Maven Compiler plugin. In other words, you are going to have to expend a huge amount of effort to bend Maven to your assumptions.

If you do this, you really won’t be using “Maven”. You’ll be using your own interpretation of Maven, and once you go down this road, you are going to start having problems using standard tools designed for Maven. In short, don’t do this. Don’t try to bypass Maven’s approach to modularity with assemblies and profiles. If you do, you are going to find yourself “swimming upstream”, and your first hint is going to be the size and complexity of your POM files. I’ve certainly created some complex POMs in my time, but I only need to do this for projects that really require customization because they are doing something unique (see the POMs for the Maven book builds, they are large and extremely customized).

If you are creating web applications, EARs, and simple Java applications you shouldn’t have large POMs. If you do, it is probably a sign that you have ventured too far “off the map”. While you might be building your project with “Maven”, there is likely something wrong with your approach. If you find yourself constantly challenging an assumption as basic as project modularity, then you need to either rethink using Maven entirely or rethink your project structure.

Adopting Maven Means Adopting Modular Structure

If you are going to adopt Maven, you must adopt a modular project structure. If you don’t you will be fighting an uphill battle with Maven and the tools that have been designed to work with it. You will be fighting not only with Maven, but you’ll be doing constant battle with your IDE and your repository manager.

If you are moving from Ant to Maven, do you yourself a favor. Adopt a modular project structure. Don’t approach Maven as a “toolbox” like Ant with tasks and targets. Approach Maven as a framework with expectations and assumptions. If you do this, you’ll have a much easier time adopting the tool.

 

From http://www.sonatype.com/people/2010/08/how-to-migrate-from-ant-to-maven-project-structure/

Published at DZone with permission of Tim O'brien, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Tomi Tuomainen replied on Wed, 2010/08/25 - 3:27pm

About lack of modular structure... Among others, Eric Evans has written (Domain Driven Design) that we should follow LOGICAL packaging as deep as possible. This means creating packages fi.mycompany.customer.account.client, fi.mycompany.customer.account.server instead of fi.mycompany.client.customer.account and fi.mycompany.server.customer.account.

Logical packaging keeps domain logic in one place. It is easier to follow the code and avoid jumping between modules and directories.

Dividing client and server (and other possible other distributions) into separate modules gets even worse. This is where Maven goes wrong and why I still prefer Ant+Ivy.

Michael Remijan replied on Thu, 2010/08/26 - 8:17am

I have done a lot of work migrating ANT projects to Maven.  The patterns and perceptions of this article are right on.  Most believe replacing a build.xml with a pom.xml is all that is needed.  When challenges arise trying to shoehorn the old ANT build.xml "functionality" into the new Maven pom.xml, frustration and abondonment are the results.  In addition to the patterns of modularization discussed in this article, another aspect to keep in mind is non build processes may also have to change.  In many ANT projects, I have seen targets created "for convenience" which (s)ftp files all over the place into different environments or copy files to different file system locations for "deployment".  The question to ask, is the necessary?  Do these processes need to be reproduced when migrating to Maven?  In many cases the answer is no, though making these process changes are often more difficult than making build changes. 

King Sam replied on Fri, 2012/02/24 - 10:07am

I've seen this over and over both in the maven user mailing list and in the real world. Someone reads some nice things about maven and plunges a development organization headfirst into maven. What they wind up with is a massively monolith build process that's generating artifacts when in fact, there are no changes in the dependency stream.

Ricardo Gladwell replied on Sun, 2012/03/25 - 3:21pm

Adopting Maven does not mean you must adopt a "modular" structure. I've been using Maven for years without using modules, while leveraging the other advantages.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.