Why Maven doesn’t work for me.



I’ve been meaning to do a follow up post on Maven for quite a while. I received several emails regarding my previous post from people asking how we’re using it. I must admit, it looked promising initially, but as we got into the specifics, it looked less workable for building commercial software. Here I hope to outline some of the reasons I suggest that Maven may not be for you.

It’s strengths.

Firstly, by reading blogs, wikis and the Maven website itself, you would get the impression that Maven is well suited to building web applications. It is, as several are already in existence, and those developers seem to like using it. For the most part, these are open source projects, following best practices, typically producing jars, wars or zip build outputs.

This makes Maven suitable for web applications such as a stock trading applications a typical bank would use. Coders code it, Maven builds it, then deploys it to a test environment where QA test it. If it is deemed of acceptable quality, it may be further deployed to a live environment. Maven suits this process well.

This is fine for internal web based applications which an information systems department may maintain, or for web based open source applications. When it comes to commercial software, the needs are a little different. For the majority of projects I’ve worked on, we eventually need to build and test software, before creating an installer, and bundling it on CD or for download. This leads us to the first issue I have with Maven …

1. One build output.

Within the Maven project file, you can specify the packaging used for your build output. The default is jar, with war, rar, ear, and a few others also acceptable.

The point here, it that you only get one output file from a Maven project. For open-source, or web application development, this is generally sufficient. In my experience though, this is far from ideal for commercial software.

The software I’ve been dealing with is mostly Java, with some native bits, and associated data and configuration files. Bundling all this into a single jar, or war is not appropriate for several reasons. Some technical, some legal (with regard to licensing of third party libraries), etc.

The net result, is if you persist in using Maven, you’ll need one project file per output file, with the associated overhead of ensuring that those multiple build systems don’t diverge over time.

2. Linear build process.

The second issue I have, is that Maven defines a linear build process. Again, this reduces it applicability to general purpose project building.

A good example if how this hurts, is cross platform Java development with native code. Java provides an API for talking to serial ports, though the implementation must be provided separately. It’s relatively easy in Ant, to branch your build depending on the platform your building, and include the Linux serial implementation when you build on Linux, and a different Windows serial implementation when building on Windows.

No such luck with Maven. You get a linear build process which you can optionally hook in at various points, but you don’t get branching or looping constructs for your build system. You’re left to resort to multiple project files again.

3. Configuration Overhead

One of the major selling points of Maven is it’s jar management abilities. I admit, if done properly, this would be a killer feature. I await the day it’s done well.

This works well, again for open source only projects. For the rest of us, we’ll need to create our own Maven repositories, for internal commercial libraries, as well as commercial third party libraries and toolkits.

This adds to the amount of work required from a project team before the first successful build is created. I’ve already posted about the pain I experienced in installing and configuring an internal Maven repository. Ideally this cost could be borne once, and shared amongst all project teams, but then you’re running into legal and licensing issues when you could potentially be sharing libraries across project teams without the necessary per-seat fees. Also, as I’ve noted before, Maven isn’t ideal for all projects, so adopting (or forcing) it to other teams is problematic. In the majority of cases, you’ll be left alone to manage your own project infrastructure, adding to your workload.

4. Build failures.

Rather than check in libraries to your project, Maven allows you to specify what libraries you need in your project file. Maven then looks for these jars in your local Maven directory, a maven proxy (if configured) or finally in the central Maven repository. This is a useful feature, as all the dependencies are managed for you with this approach.

The downside, is the need to have a local maven proxy for your own commercial, or third party libraries. Another downside, is the need to be constantly connected to the internet to check the central repository while building. For example, if your project file specifies your project needs the latest version of JUnit, then Maven will check that it has it each time you build. If for some reason your internet connection is down, slow, or the central repository is busy (which is likely as Maven’s popularity grows), you get a build failure.

Call me old fashioned, but to me build failures are serious. They generally denote that something has gone wrong. You’ve forgot to check in a file, or a unit test has failed, etc. You need to fix it.

With intermittent build failures due to network connectivity, a developers faith that a failed build is actually something that needs fixing becomes eroded, and failed builds tend to be ignored for longer, as developers assume it another bogus failure that’ll fix itself eventually.

The net result here is either time spent diagnosing bogus failures, or developers getting lazy about build failures.

5. Repeatability.

Related to Maven’s library management, is the requirement of repeatability. To me a build should be constantly repeatable. That is, if I check out revision 2345 of a project and build it today, I get the same build outputs as if I build the same revision next week, month, or year.

This is not necessarily the case with Maven’s library management. Unless your are fastidious in specifying the version of libraries you need, Maven will download updated libraries behind your back. So building revision 2345 today gets you a build. Building the same revision next week gets you a different output, because the libraries you depend on were updated on the central repository.

If you can’t reproduce consistent builds, what’s the point in having source control infrastructure? Source Control Management is already difficult enough, without playing fast and loose like this. What happens in 3 years when that big customer requests some changes to the software you sold them?

Call me paranoid, but I’d rather take the hit and manage my own libraries. Sure checking them into Subversion or CVS uses disk space, but disk space is cheap compared to not being able to repeat a build when that big customer comes calling.

6. Internal Processes

How your company builds software also has a baring on this discussion.  Our software development process specifies that the Configuration Manager must build all release candidates.  This step is introduced so that a person independent from the project team can validate that the software, tools  and methods needed to build an application are in place, and that a specific build version could be reproduced in the future if necessary.

We generally meet this requirement by checking in all libraries needed into source control, and writing a build instructions document which outlines what tools and configuration is needed to set up a build environment, as well as how to produce a build from that environment.

As already noted, Maven is unsuited to this metaphor for various reasons:

  1.  You are depending on resources outside of your control when depending on libraries from Maven’s central repository.  Can you guarantee that in X years time, the repository will still be there, with the versions of libraries you need? (No you can’t, so repeatability of builds is compromised).
  2. Can you guarantee that your project’s maven proxy will be available in X years time?  Generally, project resources get redeployed when a project finishes.  Your CM manager will have lots of work to do to recreate the Maven proxy when a build is needed.

7. Declarative XML.

The Maven project file describes itself in a declarative XML notation.  XML is, as noted in a previous post, a data markup language.  It is not a domain specific language written for the purposes of building software.  Ant fails this test too.

Ant is somewhat procedural, even if it does use a funny reverse execution mechanism.  Generally I’ve found it relatively easy to debug when the build system fails.  Maven on the other hand uses some sort of voodoo-magic.  When Maven builds fail, be prepared to spend several days pouring over verbose output logs trying to find out why it didn’t execute the hibernate schema generator when you thought it should.

If you’re considering using Maven, then I would suggest you’re better off researching some of the newer build tools such as Gant, Rake, or Buildr.  These have learned from Ant and Maven mistakes, and are built on easy to learn scripting languages.

Conclusion

Using Maven is like ridgewalking.  If you can stick to the beaten track, all will be well.  Wonder off, even a little, and you’ll find yourself falling off some pretty steep cliffs. Maven works, but only for a very specific type of project.  If that’s you, then by all means knock yourself out.  While it serves it’s niche well, I personally wouldn’t consider it a general purpose build environment.

About these ads

12 thoughts on “Why Maven doesn’t work for me.

  1. Good Layout and design. I like your blog. I just added your RSS feed to my Google News Reader. .

    Jason Rakowski

  2. QL says:

    I fully agree with everything you said here. I felt very much the same with these points, especially the failure of repeatabilily, when I tried to use Maven (both Maven 1 and Maven 2) a month ago. Where I need to rebuild a COTS from source with our in-house modifications, I have to spend weeks to ensure over 150 dependencies are configured correctly and I ended up had build a local repository and force the build to be performed locally, it’s such a pain. I had wondered, especially when everywhere I looked are all so cheerful about Maven, whether all the trouble and pain are because I am new to Maven. I am glad that I came across this page that exposes the dark side of Maven. Thanks.

  3. ccollins says:

    @QL
    I agree. I felt the same when I first started using Maven.

    I imagine for an open source project, the library management stuff is less of an issue, but when you’re a corporate user, it’s better to have ‘everything’ under SCM. Otherwise you can’t guarantee you’ll have what you need when you need to do a rebuild. Maven (and Ivy) break this by trying to be helpful with library management.

    -Chris

  4. Scott says:

    Okay, I’ll admit it. I’m a Maven fan. It certainly has its quirks and I’d be the first to admit it. However, many of your criticisms didn’t ring true at all to me. If you don’t mind, I’d like to take a few moments to share my perspective since I really can feel your pain. Hope you can appreciate it. Now, on to your criticisms:

    1) One build output – Okay, this can be a pain from time to time but modularizing your artifacts really saves time weeks, months and years down the line and I’ve learned to work with it.

    2) Linear build process – I build platform-specific code as well. Your difficulties strike me as a problem not with maven, but perhaps with the structuring of your project? Separate common code into core modules and pull in platform-specific code in separate modules. It’s a but more work but a ton more scalable and maintainable.

    3) Configuration overhead – This seems like a strawman. We use Maven across teams, licensing concerns, etc. with no problem. Can you be more specific?

    4) Build failures – The scenario you provided sounds like a misunderstanding of the snapshot feature. Maven will only get the latest of something if you ask for a snapshot (indicating that the resource is changing often). You can deal with this by increasing the duration between its checks for new versions or by specifying a specific release of an artifact instead of a snapshot.

    5) Repeatability – Maven copies everything to your local repo… you shouldn’t be trapped into being online unless you need something recent. You probably know this, but Maven pulls from repositories in the order specified in your POM file (with the central being the default). You can ignore the central repo COMPLETELY and restrict your builds to only pull from a managed, internal repository if you’re concerned about repeatability. That way, your release engineering team can install jars only after they’ve approved them for use.

    6) Internal processes – See above. Also, seems like you’re blaming Maven for an undisciplined working environment. We use configuration managers in the EXACT way you’re describing with no problem. *shrug*

    7) Declarative XML – Is actually great for making dependencies and relationships crystal clear. No fumbling through code or a debugger. But sometimes I wish for code-based building too… so I’m with you 50% on this one. =)

    Conclusion-
    Sounds to me like most of the issues you’re talking about aren’t Maven issues but rather issues with not understanding how to properly use Maven or dealing with Maven in an undisciplined work environment. When I first started with Maven, I probably would have written most of the comments that you have. If you do nothing else, read “Better Builds With Maven.” That will save you tons of trouble, time, and frustration. Best of luck and thanks for sharing your perspective.

    -Scott

  5. Tomek says:

    Hello,
    from what I read you simply haven’t took enough time to learn about maven before you started using it. :)

  6. ccollins says:

    @Tomek
    I took as much time as I could, but seeing as deadline pressures are continually on me, I had to make the best use of the little documentation I could find. I have to say learning Maven and it’s capabilities is a black art, given the poor state of documentation at the time I looked at it.

    I hope it’s improved in this regard at least, since then.

    -Chris

  7. russ says:

    I totally agree with the repeatability aspect of what you said. Although the range features in maven versioning is nice and it seems easier to manage: you do so at your own peril. You need to be able to checkout version x and build it today tomorrow and beyond the same way. Using mavens (1.1.3, ) syntax spells disaster for repeatability.

  8. Cliff says:

    I have mixed feelings about this post. First, I empathize with Chris and everyone who had to get their lumps using the tool. I don’t believe Chris skipped the tutorials or documentation at all. Maven is a simplified tool of huge complexity. (Or is that a complicated tool that has been over-simplified?) It’s really easy to shoot yourself in the foot even after reading “Better Builds”, the “Maven Book” online, “Maven Recipes”, “Maven For Dummies”, and “How to Teach Your Girlfriend Maven On the First Date”. There are two things that are necessary for healthy software development. There’s the pragmatic ideas and the philosophical ideas. Regardless of the tool you use, Maven, Ant, Gant, Buildr, understanding the life cycle is far more critical. The tool is only an issue as far as it’s usability. For eg. if it’s easy to use the tool for a repeatable build then the tool is good. If you can’t figure out how to manage proper cohesion between your subsystems with the tool then the tool is an issue due to it’s usability.

    Maven, just like any other build tool, is more than capable in any of the above bullet points but for certain things you have to reach deeper into its functionality, which forces you to better understand/adhere-to the development life cycle. Repeatability is a perfect example. On the surface it’s difficult to achieve because of auto jar updates. However once you dive beyond the tutorial uses and use the release feature it becomes impossible to not have a repeatable build. The point is that you now have to set up someplace to release to (which you ultimately need anyhow), and resolve all of your snapshot dependancies (another concept you’d have to learn about proper software life cycles regardless of the tool) which means you’d have to host/release all of your other dependencies in the repo as well. In the end all of these concepts are forced to the surface forcing you to deal with them early on. This is something most devs would side-step with a tool like Ant as they’d likely check jars into scm and consider it a done deal. The result is a false sense of repeatability. (I can give a perfect example of this false sense with Ant.)

    Since my reply is stretching down the page I’ll cut it short and possibly post a follow up. I’ll end by saying I can appreciate how someone would be frustrated by Maven, however it is not necessarily a bad tool, it’s just a tool that doesn’t fit into everybody’s development life cycle.

  9. ccollins says:

    Thanks Cliff,
    You get my point perfectly. Maven wasn’t suitable to my project development cycle, though it’s fine tuned to others.

    Secondly, I did have real issues in getting to quality documentation and resolving problems when things went wrong. Maven left me with the impression (rightly, or wrongly) that is was difficult to use and badly supported. I do take your point, that it’s just a tool to support a process, and understanding the process is a good place to start.

    I’m a professional programmer, and my productivity is frequently measured. When it comes to build systems, I want something that’s flexible, works with me, and is understandable. I currently use Ant, though that is not without it’s flaws either. When it comes to the crunch, and something goes wrong, the Ant documentation is good, there’s plenty of help from the community, and it’s an easier tool to understand its inner workings.

    We’re in the business of shipping product, so time spent on build systems is generally seen as a necessary cost to meeting a projects goals. That said, we don’t create elaborate or perfect build setups, as they are generally short lived while a project is running. Maven may be the bees knees, I just don’t have the luxury of time to spend learning and configuring it. Since I can achieve more in Ant in 30 minutes than in days with Maven, we go with Ant.

    My last effort with Maven had me take 4 days to get HelloWorld to compile. By then I had our build server set up, had repository caching, developer setup documentation, build instructions, etc. It took another 4 days when we attempted to integrate Hibernate into our build system (We never figured out how to make it work). At that point I threw in the towel in frustration. Two days later I had everything working with Ant, and I’ve not looked back.

    -Chris

  10. Boby says:

    I fully agree with Author’s assessment on Maven. I have used Maven for the last 2 years or so, and I have concluded that it is not built for Enterprise use with SCM systems.

    Maven complicates builds when Java build for enterprise applications are supposed to be simple. The problems with builds was not even a topic for discussions before Maven was used to solve “the problem”. It makes problems it was supposed to solve even more difficult. Yes, everything has solution in Maven. But if it is not easily understood, involves too many procedures or need too many tweaking in the POM files, Maven’s breaks its own goal.

    Versioning conflicts: The versions of code is maintained in our SCM. The POM files has a parallel versioning mechanism. Version management is typically controlled by Release Management team. Now developers manage the version as our release management team hates Maven and just do not want to manually manage version numbers embedded in some pom files, which does not have much relationship with SCM labels or versions.

    Repeatability: Maven does not guarantee repeatability of the build. Maven allows dependency definition such that one jar can dependent on any version available. There is also another problem. Maven projects typically need a parent pom (many recommend this). Typically, this parent pom is shared by applications. The reason for this is that, most enterprises have some shared code, that is reusable. When many projects share this code, an aggregation using modules are done. The problem comes when, parent pom is updated. For example, adding a new module, can change the version of the dependant jars, unless versions of jars are explicitly specified in the parent pom. The solution might be then not to use modules, but then that opens up other issues.

    One Artifact per folder needs thinking: Let us say, you have several shared components, shared by several applications. But not all applications require all components. Now, how do you organize the folders. There can be only one parent pom. But in this case, we need to have a parent pom per application so that changes in one application does not affect other applications. Again, the problem can also be solved by some workaround. But wait, why are we trying to solve problems? There was no problem before.

    Security: This is an area where there is no documentation offered. Should everyone be arbitrarily downloading packages from external repositories or should enterprise have a common repository? Is download authentic?

    Repositories: Should we use an internal repository? The question is whether Dev, QA (QA only), Prod(prod fixes) use one repository? Should repository be in version control? How do we migrate changes to one repository to another? Who is going to do all these?

    Now that, we are trying to solve more problems than before, I have concluded that trying to solve all these takes away focus from application development itself. Developers are now more focused on how to get Maven right than ensuring quality of business logic implemented.

    Maven went too far solving the original problem, thus creating new problems. All that we needed is the dependency mechanisms for Jars, and an external developer tool to download them safely. Then, we would download required jars one time during development and check into SCM. From there, SCM takes over on tracking the versions and grouping. I would think there will be an alternate tool that will allow download of Jars at *development time* in the near future.

    So, for those who are using Ant in the Enterprise, I would warn that switching to Maven can create new problems, which will consume significant time and reduce productivity.

  11. sopuli says:

    The problem existed even before Maven. How to guarantee that two projects that say RPC each other have the same version of the RPC library? By comparing bits and bytes? What if the other project has to change the library for whatever reason, who knows which projects need to have the library changed? There are lots of caveats “managing” dependencies manually.

    In enterprise you SHOULD have an internal repository for the build repeatability. Setting one up is bit more difficult, but even a developer like me without too many administration skills was able to set one up.

  12. vobguy says:

    One thing I have found a bit annoying is source code escrow.
    Normally the .m2/repository holds a bunch of stuff that may or may not be just from the last build. It can get rather large, and we have to burn our Escrow to DVDs.
    So each time I do a RC build that might have to be escrowed, I have to move aside my entire .m2/repository subdir and just do a build, then tar up the .m2/repository; as well as a scrubbed version of the settings file.
    It is also a bit of a pain to explain to the engineers on the other side what to do with the repository and how to setup their own settings file.

    I wonder how others handle this on the CM/Release side.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s