Showing posts with label maven. Show all posts
Showing posts with label maven. Show all posts

Thursday, April 12, 2012

Maven Does Not Suck . . . but the Maven Docs Do

I'm not going to go into the whole Maven debate, but suffice it to say that I'm a strong proponent of everything best practice, and, to me, Maven is an embodiment of best practice. By this I mean that Maven is built around a specific best practice build methodology. Note, I said a specific best practice build methodology. In the real world, there are more than a handful of build methodologies that could qualify for the best practice accolade, but Maven assumes a single one of them. This does not mean that the others are not good, it just means that if you use Maven, you going to need to buy-in to the conventions it assumes . . . or suffer. This is true for any Convention Over Configuration ( CoC ) tool, and Maven is pretty darn  CoC.

Maven, like all design patterns, is a reuseable solution to the process of building software

I think the occasionally discussed notion of Maven as a design pattern for builds is a powerful metaphor.  It's useful because it emphasises that Maven, like all design patterns, is a reuseable solution to the process of building software.  It's a best practice solution that has been refined by a community of smart people over years of heavy use.  The most obvious benefits of leveraging a design pattern for building software are the same as those for writing software.  Namely:

  • You get a bunch of functionality with out having to write it yourself
  • An engineer that understands the pattern as applied to one project, can instantly understand the pattern as applied to another project.

Nominally, the first bullet is about productivity and and the second is about simplicity. Obviously, everybody wants to be more productive, i.e. accomplishing more with less lines of code. But, I actually think the second point -- simplicity -- is far more important. In my opinion, the entire field of engineering boils down, most elegantly, to the concept of "managing complexity". By complexity, I refer directly to that headache you get when bombarded with piles of spaghetti code.  Design patterns help eliminate this intellectual discord by sealing off a big chunk of complexity in a higher level notation.  In case you've forgotten, this is what frees our minds up for the bigger and cooler tasks that inevitably reside on the next level.

It is this point of view that makes me rank learning a new project's ad hoc build to be one of the most annoying aspects of my profession. Even if an ant or make build is very cleanly implemented, follows a localized best practice, and automates a broad scope of the software lifecycle, it still punishes  new developers with a mountain of raw data, i.e. lines of scriptcode. Note, it's only the ad hoc-ness that is a problem here. This is certainly not a knock on these tools. ant in particular is very good at automating your tasks and providing a reusable set of build widgets. But it does nothing to provide a reusable solution to the entire process of building software, and, accordingly, it does nothing to ease a new developers on their road to comprehending the build.

it's the conventions that matter most with a CoC tool like Maven

So, as I see it, it's the conventions that matter most with a CoC tool like Maven.  You have to know and follow the assumed conventions in order to be successful with Maven. Projects that don't follow the conventions quickly run afoul of Maven. First, they struggle to implement their own build process with a tool that assumes a build process of it's own. It's easy to fall into being upset that you can't easily do what you've been doing, but the preceding paragraphs are meant to suggest that it's actually you who needs to change, at least if you plan to continue on with Maven. When you choose Maven, you need to accept the conventions. I you can't, I suggest you stick with Ant, which is flexible enough to meet you on your terms. Just remember that you are losing the ability to leverage the design pattern aspect of Maven to manage the complexity of your build. And if you think your build doesn't have complexity issues, ask your self these questions:

  • Can every engineer on our team easily build all the components of our software system?
  • Do our engineers have the confidence to modify build scripts without angst?
  • Do our engineers flee the room when someone is needed to address a build problem?

So, if you're with me so far, you'd probably agree that following the conventions assumed by Maven is a critical prerequisite for entering Maven nirvana. And this is what leads me to the conclude that the Maven docs suck.  They are not only inadequate, but perhaps detrimental; they mostly document the configuration while utterly failing on the critical topic of conventions.  The emphasis on configuration, which I assume is largely by accident, leads newbies into thinking it's okay, and perhaps even  normal, to configure Maven.

The Maven documentation is not only inadequate, but perhaps detrimental; it mostly documents the configuration while utterly failing on the critical topic of conventions.

By documentation, I mostly mean all that stuff you find when you visit the Maven or Codehaus plugin pages. For instance, consider the extremely core maven-assembly-plugin.  Browse through the docs on the Maven site and you'll find that it's almost entirely about configuration. The problem, as I've stated and restated, is that you don't really want to configure Maven; you want to follow the conventions. Configuration should be only an option of last resort.

plugin puts things and then the next plugin can't find that stuff.  Use a profile to tell Maven where to find something, and then nothing else can find that thing without the profile.  Configuring Maven gets you into a bit of a configuration feedback loop, and geometric growth of configuration does not lend itself to pom readability.  Even if you can get Maven to do what you need by configuring it to death, you quickly get an incomprehensible build.  

Use the configuration to change where one plugin puts things and then the next plugin can't find that stuff.

So, avoid configuration!  Stick instead to the conventional path. Your engineers will know and love their build, and you will easily leverage the many benefits offered by the Maven ecosystem -- from the rich plugin libraries to the repository servers and build servers.  

But how does one go about learning the Maven conventions?  It's all about community. Luckily, it's a pretty friendly community.  Here are some of the most important resources that I use when trying to determine how things should be done in Maven.


Additionally, in an effort to be a friendly community member, I'm using this blog entry as an introduction to a series of Maven entries.  Each of these entries will outline important Maven conventions. I'll detail the convention as well as offer example poms.  So, keep in touch if you want to learn about Maven conventions.  

Thursday, March 12, 2009

Maven: The Definitive Guide -- Book Review

Maven: The Definitive Guide by O'Reilly provides a great introduction to this increasingly ubiquitous development tool. Admittedly, this ubiquity is still perhaps limited to the Java open source community, but it's spreading fast, and with good reason. Many have knocked Maven for being overly complex, or over engineered, and I kept my distance for a while. I recently became more involved with the one of the Apache projects, Struts 2, and since that project, like most Apache projects by now, uses Maven, I decided to give it a good examination. Luckily, this new book had just came out and my introduction was eased greatly.

Star Rating: 4 out of 5 Stars


Maven: The Definitive Guide gets 4 out of 5 stars from me. This could have easily been 5 out of 5, but the code examples in the book have many errors. I'll say more about the code errors, and how to deal with them, in a later paragraph, but I don't want to start off on the wrong foot because I really like this book a lot. Let's focus on what it has to offer for now.

Introduction to Maven Space

The first six chapters of the book walk the reader from newbie to fully functional Maven developer in easy to follow, to the point manner. It really doesn't take long to read through these chapters, even doing the examples as you go. These chapters will show you how to structure, manage dependencies, build and release your projects "the Maven way". Rather than reproducing the content of the book, I'll just note a couple of more interesting aspects of the Maven way. Dependency management is one of the most dazzling features of Maven, so I'll start with that.

As an example, let's consider a project that depends upon Struts 2, a Struts 2 project in other words. How do you manage that dependency the Maven way? First, we have to understand how Maven identifies dependencies. Every project/artifact in the Maven universe is uniquely identified by a groupId, artifactId and version. This ternary identifier will become very familiar to you be the time you complete the first six chapters.

How does Maven go about finding the depencies then? All dependencies are Maven artififacts that are stored in repositories. There is a "mother" repository where all of the common Jar files of the Java world exist as Maven artifacts. Maven comes configured to point to the mother repository, located at http://repo2.maven.org/maven2/. Note, officially, this "mother" repository is called the "central" repository.

Take a couple of seconds to check this mother repo out. Here you'll see a directory structure that mirror's organization namespaces. Let's look for Struts 2. Tunnel down into org/apache/struts. The groupId for all of the struts stuff is org.apache.struts, and this is mirrored by the repository directory structure. The directories you now see are all of the artifactId's. You should see struts2-core; this is the main Struts 2 project, which happens to be packaged as a Jar file, like many Java projects. Inside of that directory you'll see a bunch of version numbers representing the different releases of that project. Let's look in 2.1.6, the most recent general release.

Looking inside that directory you'll see what first appears to be quite few items. Most of them are checksums however. In the end, you simply have:
  • The Jar file itself
  • The JavaDocs
  • The Source Code
  • The POM: the Maven descriptor file

And that's that. By the end of the first six chapters, you'll be more than familiar with all of this and you'll know that, with Maven, if you are creating a Struts 2 application, the only thing you'll need to do is declare that your project depends upon the struts2-core artifact by adding a line like the following to your projects own POM.

<dependency>
<groupid>org.apache.struts</groupid>
<artifactid>struts2-core</artifactid>
<version>2.1.6</version>
</dependency>

With this is place, you don't have to handle Jar files yourself. In a corporate setting, you can even configure your own repositories, but the main idea remains the same; you declare dependencies and let Maven do the actual management of physical jar files. Very nice.

Archetypes

These chapters will also show you how to use Maven archetypes to help get new projects up and running with a few key strokes. Archetypes provide the skeletal structure for a given type of project. Something like 90 archetypes are available in the default repository as we speak. These range from the standard Jar file type project, to generic web applications to very specific things like a Struts 2 archetype.

Reading Road Map

If you're looking for the shortest path to enlightenment, I can recommend the following reading path for this book. First, read chapters 1-6 in succession. They are short and will get you up to speed in a tutorial fashion. I think you can safely skip chapter 7, which shows a complicated real world project; you'll know if you need to read it.

Next, the reference section of the book has very good information. On first read, however, I think you are very safe in reading chapters 9, 10, and 14. 9 and 10 are essential descriptions of the POM itself and the way Maven actually works. Chapter 14 is an introduction to the eclipse plugin for Maven, m2eclipse. This plugin is a very powerful plugin that is not to be missed. As a teaser, I'll toss out one nice feature of using the Maven Eclipse plugin. When a Maven project, in Eclipse, references various dependencies, you can have Eclipse auto-magically get source code for all of those dependencies and link that source code into the Eclipse debugger and code awareness features. This means that you automatically get tracing and debugging into all of the open source Java projects that you work with, think Hibernate, Struts 2, etc.

A Word on the Book's Example Code

As I mentioned earlier, the example code simply has a lot of typo's and errors. Most of this stuff is already documented on the Sonatype web site.


Conclusion

I definitely recommend this book for any Java developer. In addition to the hard copy, you can also read the book online at the sonatype site, and it actually can be installed with the m2eclipse plugin so that you can read it within the help facilities of Eclipse. Cutting edge book distribution, eh? Enjoy.