This is [hopefully - Ed. ] a short post about a Maven anti-pattern that people seem to think is accepted practice and is actually responsible for a lot of their Maven woes.
Well actually it is a pattern which manifests it self primarily in two ways. The first way is what I will call the "install" hack.
Symptoms: When you try to build a multi-module project from the root immediately after changing all the version numbers to a new version number, the build fails unless you invoke a phase that is at least as far as "install" in the project lifecycle.
Now the developer moving fast just says “feck this” and runs
$ mvn install
Oh look now everything works again… except it doesn't really… but you won't know that as long as you keep on running “mvn install”
What is going on?
Maven has three stores for artifacts:
The reactor (basically any artifacts that have been built so far in your current Maven session)
The local cache of built artifacts (it is such a pity that we called this the local repository… no end of confusion for users with that name)
The remote repositories.
When you are writing a Maven plugin, you (yes, I'm talking to the plugin developers out there) are supposed to resolve artifacts in the order: reactor; local cache; remote cache.
Maven 2 did not make this trivial… you basically had to code the search of the reactor yourself first and then and only if you didn't find the artifact would you invoke the resolution API to pull from the local cache / remote repositories.
Maven 3 helps somewhat, as it will do a search of the reactor first when you invoke the resolution API… but lots of plugins still have to work on Maven 2… so you end up with code like this to make things work the right way.
Why is the "install" hack wrong?
Well the issue is that you are building with the "old" artifact until you re-invoke the "install" phase to refresh what is in your local cache. Typically this manifests itself as you not trusting the build until you have run
$ mvn clean install -DskipTests && mvn clean install -DskipTests && mvn clean install
“just to be sure as you were bitten several times before with changes you made just not showing up in the web application and Maven is a piece of shit but it's what we are using and that f*cker who switched us over to Maven should be shot on sight but he f*cked off to some other company good riddance” [Have you a source for this quote… I've seen it a lot… be nice to have a definitive source - Ed. ]
The build makes up the new artifact, stuffs it into the reactor and continues… a later module needs the artifact but pulls it from the local repository cache (not the reactor) therefore using an older version from who knows when and packages that up leading to a borked artifact that gets stuffed into the reactor and finally a third module takes that artifact out of the local repository cache again an old version from who knows when and this is all messed up.
You can have even more fun, for example when people use goals like dependency:copy to pull artifacts which are produced from the reactor rather than adding a dependency to the module and using dependency:copy-dependencies … this results in a situation where you have hidden inter-module dependencies from Maven so it cannot sequence the reactor correctly and Maven must now act like a Rabbit … not a pleasant prospect.
How to fix the problem?
Simple… refactor your build until it will work (on virgin version numbers) with "clean verify". This will result is a much improved Maven build.
Of course in practice it is not quite so simple.
You may be using some broken plugins that you will need to fix, or replace.
You may be battling a circular dependency hell (which was why you used dependency:copy in the first place) which indicates a bad build smell that you should eradicate.
You may not have the time… well think of all the time you are wasting running "mvn install" when you could get away without going so far along the lifecycle.
Good luck if you have this build smell in your build. Removing it may not stop you complaining about Maven… but it might help you see that perhaps you are part of your problems!
Stephen Connolly has nearly 20 years experience in software development. He is involved in a number of open source projects, including Jenkins . Stephen was one of the first non-Sun committers to the Jenkins project and developed the weather icons. Stephen lives in Dublin, Ireland - where the weather icons are particularly useful. Follow Stephen on Twitter and on his blog .
Stay up to date
We'll never share your email address and you can opt out at any time, we promise.