A year ago, I posed the question “Why do you Hate Maven?”. A lot of those issues have since been addressed – if not in later Maven 1 releases, in Maven 2. This post inspired a mail on the users list listing some other issues, and whether they saw Maven 2 solving them.
It is always good to hear in-depth feedback, both positive experiences and negative ones, that are framed in a way that help shape a better future for Maven. So with that in mind, I thought I’d respond, and since it started in the blogosphere (and the author had originally intended to reply on the blog), I figured I’d respond here too.
It was definitely encouraging to note that even with the limitations discovered in Maven 1, those posing such questions still like it, and choose to use it – so its not so much a matter of hating Maven, but more of wishing it did what it does better.
Anyway, here goes…
ISSUE: Multiproject handling is a “tacked on option” whose interaction with other goals becomes problematic.
M2: Appears to have been addressed in M2.
This is correct here on both counts. Multiple project builds really was just a collection of separate builds. Improvements in Maven2 to cover this include
– building module lists into the POM as a first class entity
– the ability for a plugin to behave contextually if it is building a single project, or is an aggregating top level project
– knowledge of other builds being performed in the reactor so that they can be used instead of repository data, eventually allowing “m2 compile” to work across a series of projects, without the need to install each
ISSUE: The Clean goal isn’t clean. Requires all dependencies to be available before deletion.
M2: Appears to have been addressed in M2.
Again, this is spot on. Maven2 lets each goal declare whether it needs the dependencies, and if so, which set (compile, runtime, or test).
ISSUE: The majority of the functionality is undocumented and therefore, inaccessible at speed.
With the exception of a _small_ number of _core_ tasks there is almost no documentation.
I currently have all the plugins expanded in a subdirectory so that I have an online dictionary of jelly and java code and properties and goals.
There is certainly no argument here, and was the topic of a recent blog entry on what might be wrong with Maven’s documentation. Poor plugin documentation is a particular problem. I’m hopeful the documentation on the site is enough to get started and perform a reasonable percentage of the main tasks, but delving into advanced topics certainly requires a bit of digging and a post to the users list quite often. The artchitecture is also problematic to document as is: explaining the effects of a postGoal in a particular plugin in Maven1 is particularly challenging, as is comparing the differences between a goal, a jelly tag, or just a property.
M2: It may or may not be addressed in M2 but it looks like the basic explanantions of lifecycle are there and it looks like it may be easier for me to help update the documentation built on top of that foundation.
M2 is still in its alpha stages, so the documentation can be expected to be lean. We tend to write things as they become stable to avoid writing documentation that will change on experimental features. That stage is now coming to an end, and it is necessary to start fleshing out the main site, and set a good foundation for the reference documentation in the plugins, as well as common uses. In general, how Maven2 works is much more clearly defined and so easier to explain.
Definitely yet to be proven whether a good job will be done here, but I think the Maven team have an idea of what is necessary.
Maven’s best practices often don’t address corporate real world headaches. Even when I agree with them I bump up against the problems inherent with what an existing corporate practise and/or current tool sets.
This is a tricky one. It would be silly to call them best practices if they weren’t really best practices for the real world 🙂
There are two commons causes here. One is a misunderstanding of what Maven’s best practices really are. (I’ll emphasise this isn’t a response to the poster in question, but a general observation). This, again, comes back to a failing in our documentation. But quite often a question on the users list starting out thinking Maven is incapable of working with their project ends with the light bulb appearing above the head as it clicks. The same approach needs to be taken to builds as for coding: you can’t start with a solution and try and fit the problem to it, yet it happens all the time.
The other is probably integration with existing practices and tools. There are definitely some particular cases where limitations come up, and this is something that needs to be looked at case by case, and how we can better facilitate Maven and those tools working together. Maven does need to be inflexible in some ways to ensure everything works as designed, but this shouldn’t really stop something from being done, as long as you are still looking at this from the POV of what you want done, not how to do it.
With feedback on what those issues are, hopefull Maven will be a better default fit to more and more real world practices, but still retain the benefits it provides in giving known build patterns.
ISSUE: The attaching of the test and install goals in such a way that they cannot be separated easily and cleanly AND The assumption that testing can occur immediately after compilation and installation… without a deployment.
M2: I am not yet clear that this is resolved in M2.
The way we have looked to resolve this in m2 is to improve the definition. We have unit tests which are run before packaging as they always have been, and we have what we are calling integration tests that are run after packaging and might require some deployment into the server as is given here.
There were a few different reasons to complain about tests being intrinsically hooked into packaging in Maven1 – none of these reasons are valid, that I know of, in Maven2 as those issues have been resolved, without needing to actually prevent the tests being run.
ISSUE: The one project, one artifact rule is a great rule for configuration management BUT it puts the onus of managing complexity on the developer rather than the tool.
The ability for a project to be able to register that it produces N artifacts and list those artifacts, ids, types, etc, would make a huge difference.
M2: I have seen no sign that this is simpler in M2.
In this case, it really depends on what you are trying to achieve. In Maven, the project is a fundamental unit of work, and has a unique identifier that is used for dependencies as well as building and publishing the project. Now, in the case where you have a group of coupled artifacts, such that there is a “main one” and then a series of others that only exist because of the main one – Maven2 allows that. Examples are an ejb and its client library, a taglib JAR with its tld files, and so on.
However, when it comes to building code where they might be separated then Maven’s identification relies on being able to tell them apart, so they must be separate projects. These separate projects have their own list of dependencies, which is hopefully smaller given that there is a clear functionality separation, and this makes the final dependency management easier as the closer of a libraries dependencies is more concise and more likely to be correct straight up.
To make maintaining these separate projects easier, Maven2 makes use of its multiple project support and better inheritence so that they can all still be worked with together, and keeps the project files quite small and simple to maintain.
ISSUE: The versioning of artifacts is VERY much a “one size fits rarely” UNLESS you are in total control of all of your codebase. If there is any place where a specific artifact name doesn’t work or cannot contain a version at deployment time (.NET strongly named assemblies come to mind – painfully) then there are rarely workarounds that don’t take many hours to implement and integrate into the process.
M2: I have seen no sign that this is simpler in M2.
This is one of the more common misconceptions – that the version in the repository has to match the version used when you build. This should not be the case. It is important anything going into Maven’s repository has a version so it can tell the difference between two different versions of the same artifact, and to make builds reproducible in the future when that artifact changes. However, no matter how you reference it and it is stored in the repository, this should not affect what it is called when the artifact is actually deployed. Classic cases are DLLs and EARs which rely on specific, unversioned names.
ISSUE: Repositories assume WORA semantics for the artifacts. Building systems that require special dependencies for one platform but not for another is problematic.
M2: This appears to be handled at the repository side by the new M2 repos structure. I am not clear about the use of Maven to build multiple configurations.
This has been taken care of in recent code in Maven2 which allows defining several build profiles within your project. They are cumulative, and let you specify different dependencies, configuration, and possibly different build processes for different environments. Typical triggers for applying certain profiles are the JDK being used, the target operating system, and whether it is a dev, test, QA or production build.
ISSUE: Using multiple source paths in a single projecty is a headache. It has most often come up in the code generation arena but also when dealing with tools that require the source tree to be processed to be available AND cannot filter the source files to be processed by package name.
M2: I am not sure if this is addressed in M2.
This has been addressed in Maven2, again without comprimising the original encouragement to keep one source tree for one artifact.
There is a generate-sources phase in the build process, where you can register any goals that do so, and plug the new directories into the project for compilation automatically.
There is a process-sources phase before compilation, that takes the above source roots and can filter them or process them as needed.
So, all in all there were some great questions here that have probably been answered in pieces over time, but that I’m encouraged to say we are making positive movement in Maven2 without losing sight of the biggest advantages of using Maven in the first place to get understandable, consistent builds based on proven patterns.
If anyone has any further feedback on these, or other gripes you’ve never seen answered, or maybe even some positive encouragement, I’d be happy to take a stab at answering them.