I was starting a new (personal) project, so I thought it may be a good idea to set it up using Maven2. Up until now, I have been a happy user of Ant. The first I heard about Maven was from Michael Neale, one of the core developers of the JBoss Rule (formerly Drools) project, who liked it because he did not have to manually write build.xml files anymore. More recently, my ex-colleague Debasish Ghosh and author of the blog "Ruminations of a Programmer", and someone whose opinions I hold in high regard, blogged about how Maven helps with Project Geometry.
Apart from this, Maven (and Maven2) has many cool features. Maven2 is also a very large, complex and poorly documented software which therefore has a very steep (almost vertical) learning curve. It also requires you to be connected to the Internet most of the time. I realize that given the abundance of articles about Maven in the Java press lately, I may sound like another Java dev who has seen the light or drank the Maven Kool-Aid (depending on your point of view), but till about day before yesterday, until I finally got everything working, I was cursing about these deficiencies myself.
In a nutshell, the advantages I see with Maven2 are as follows. Some of them can be addressed by other tools, which do not require you to completely restructure your build system as Maven does. But the nice thing about Maven2 is that these are all supplied by a single package, so if you spend the time to understand how Maven2 works, you should be able to leverage its built in support for third party build tools to produce better quality software.
- Standardized Directory Structure
- Simplified Build Process
- No bundling of third-party JAR files
- Transitive Dependency handling
- Built in reporting
- Support for creating project website
- Support for APT (Almost Plain Text) format for user documentation
- Automatic generation of IDE artefacts
Standardized Directory Structure
Maven2 comes with a set of built in project archetypes (or templates), which auto-generates different type of project directory structures for you. Because each of these directory structures are standard, Maven "knows" where to find the .java files when it has to run a "compile" goal (similar to Ant's targets). Unfortunately, the standard directory structure for web applications (with the Java sources embedded within the application itself) is not one of them. Maven2 has the concept of one artefact for one application, so the kind of web application I am used to would produce a JAR file for the Java stuff and a WAR file for the webapp itself. To set up this kind of application, we need to set up a multi-module project under Maven2, with one standalone Java project for the Java code, and a simple web application project for the JSP and HTML pages, with the standalone Java project as a dependency. This turned out to be a mixed blessing, since IDEs such as Eclipse are better at running Java compiles than parsing and validating XML pages, so having them in separate projects actually speeds up clean Java compiles.
Simplified build process
Once the standard directory structure is set up, you need to build a POM (Project Object Model) with a pom.xml file. The pom.xml file will tell Maven about the project, such as the type of project, the library dependencies, the compiler level, etc, based on which Maven2 will now "know" how to run various standard goals. The Maven2 team calls this style declarative, in contrast to Ant's imperative model, where you need to tell Ant how to do a compile, test and so on. To do non-standard things, there are ways to enhance Maven's build phases with enhanced goals, which seems fairly simple to do, but requires more understanding than I have of the Maven POM. The only benefit I see is that I dont have to create a build.xml file for each project, and that project targets are standardized across applications - not a major benefit, since I can always look up the available targets using "ant -projecthelp" and I usually copy and paste content from build.xml files from other projects when I create a new one anyway.
No bundling of third-party JARs
I do web application development with Spring and Hibernate, which come with a large number of JAR files in their standard distributions. Additionally, I may also use other miscellaneous JAR files, such as log4j and the jakarta-commons libraries, so each project contains quite a lot of libraries. Maven2 downloads these JAR files, based on the contents of your POM, to a central local repository (under $HOME/.m2/repository), so it can be shared across multiple projects. However, there are other solutions, such as Savant, which does the same thing, without requiring you to give up your Ant build files.
Transitive Dependency handling
This simply means that if I need the Spring JAR file in my webapp, I specify Spring as my dependency, not say, for example the AOP Alliance JAR file which spring depends on. Maven2 will consult the Spring POM in the remote repository, and figure out the dependencies that Spring needs and download them too. This was not supported in Maven 1.x, which was one of my motivations for starting with Maven with Maven2, even though Maven 1.x is better documented. In my opinion, this is a major benefit, and the old way of copying everything that I needed manually is like doing software installs on Linux using RPM rather than RedHat's Yum or Debian's APT. But this feature is not unique to Maven. I know that at least Savant supports this feature.
Built in reporting
Maven2 has an open plugin architecture, which allows different tool vendors to write plugins which Maven can download and use. Maven supports a large number of standard reports that get generated when you generate your project website. These reports can provide quite a lot of information about your project that can be useful to developers, such as the test coverage report. I have not run any of the reports myself yet, but I liked what I saw in the documentation.
Support for creating project website
Building a standard project website is just a matter of running the mvn site command. It creates a functional and standard site that can be used to store various project artifacts and providing information about the project to the end users. Beats having to build a project website manually.
Support for APT format for user documentation
This is another big thing that attracted me to use Maven2. It supports a Wiki-like formatting syntax called APT (Almost Plain Text) that can be formatted to HTML automatically. This can be very useful for creating user documentation. In the past, I have used MS-Word documents, HTML and Docbook XML documents (both coded by hand) for writing documentation. Lately, I have been using the corporate wiki to write system and user documentation, and the time savings are quite awesome. APT is similar, except that you will not need the corporate wiki infrastructure to host your documentation, it is part of your project website itself. Another feature I have not used yet, but one that I will definitely use.
Automatic generation of IDE artefacts
And of course, the nicest thing for Java IDE users, which is probably 90% of Java programmers today. Maven has goals for generating IDE artifacts for Eclipse, IDEA, NetBeans and even EMACS JDEE. This is pretty much a requirement if you are working with a Maven repository, since the JAR files are nested too deep in the repository directory structure, and selecting each of them to set up your IDE build path is going to be difficult and time consuming. However, with the IDE artefact generation goals, you can create the artefacts with a single command, and you will have a fully configured project when you step into your IDE to work. I have tried this with Eclipse, and it works great.
However, there are things that I did not like about Maven2. Here is a list.
- Need Continuous Internet Connection
- All or Nothing approach
- Steep Learning Curve and Scarce Documentation
- New features of Maven2 not available to Maven 1.x
Need Continuous Internet Connection
A colleague notes - "The Network is NOT the Computer, its the Network", but its amazing how so many modern software programs seem to assume that the user is going to be always on the Internet. Maven2 is one such. When you download Maven2, it downloads some small bootstrap component, which allows it to start itself and to download whatever plugin is required for the goal you requested. Once the plugin is downloaded, you can use it in when you are disconnected. But during the initial setup, it is mandatory for you to be always connected to the Internet. This was a problem for me, since this type of work (picking up new frameworks and build tools and learning them) usually occurs on my commute on my laptop when I do not have an internet connection. I suspect a large number of Maven2 users also are not always connected to the Internet. A separate download or Maven2 goal that allows all available or most commonly used plugins to be downloaded at one go would be very helpful.
All or Nothing Approach
Maven2 is a huge and very featureful piece of software, but it is not possible to phase it into an organization by only using specific modules. One popular module, in my opinion, would be the APT to HTML translator. Believe it or not, switching build tools which are used by all developers in a corporate environment, especially when you transition from something as intuitive as Ant to Maven, is no trivial task, and is unlikely to happen, except perhaps within small teams which are free to set their own standards, and open-source projects.
Steep Learning Curve and Scarce Documentation
Maven2 is a totally new way of doing your builds. It makes easy things trivial, and hard things easy, but only if you know how - and its quite a challenge to figure out how the first time. Some things are quite non-intuitive, for example to make Maven2 work with Java 1.5, I had to add the following snippet to my POM:
1 2 3 4 5 6 7 8
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin>
Dont know about you, but this is not something I would have thought up myself. There are other little things too, which are hard to figure out the first time, but you will totally get it once you know how.
Like other Apache projects, finding documentation for solutions to problems on the Maven2 website is difficult, but the articles are good and quite detailed. As far as books go, I did not find "Maven - A Developer's Notebook" by Vince Massol very useful, since it deals with Maven 1.x, and Maven2 is quite different. A better choice is Mergere's free e-book "Better Builds with Maven" by Vincent Massol and Jason Van Zyl which works great as a tutorial and a general background reference on Maven2. Download it, you will need it. You will still have to look up discussion forums on the Internet, but at least its a start.
No backporting of new features
This is probably just a temporary issue, but there is a general feeling among the Maven user community that Maven2 is unfinished. Yet, Maven2 offers many useful features, such as Transitive Dependency handling, which are never going to be backported to Maven 1.x. Which means that users who want to use these features have to stay on the bleeding edge and face the possibility of builds being broken due to bugs in Maven2 code. At the moment this is annoying, but is likely to go away as Maven2 gets more mature.
So, to set up Maven, get yourself hooked up to the Internet and stay on it until you are done with all the goals you are likely to execute. Resist the temptation to do local installs from JARs on your hard disk if you cannot find them on ibiblio or other mirrors. Maven2 needs both the JAR files and the POM file for that third-party project to resolve dependencies. And enjoy yourself coding while Maven2 takes care of your build once you are past the learning curve.