Algorithm for troubleshooting "Maven doesn't work for me" problems
One of the most common and annoying problems I encounter with Maven is the building process failing/passing depending on who, when and on which machine is executing the process.
More formally - in ideal world I would expect the build process to be repeatable. As a programmer I would say that I expect the build process to be like a pure function of source code and resources being build input and "an environment" - I would expect it to return the same result any time and anywhere I "evaluate" it using "fixed environment" and I expect (rather wish) that everyone in the team has the same "fixed environment".
In real world either "an environment" changes over time or varies between developer machines, possibly because it includes some dependencies one neither expects nor realizes.
What I am trying to achieve asking this question is finding/defining an algorithm/procedure or check list for troubleshooting not repeatable Maven build processes. Let assume we have two separate machines A and B with the same OS and that we are building exactly the same version of our application on them, but they give different results (for example one is successful and one fails). Where/how one should look for differences between these two "environments".
These are some steps I usually use:
- comp开发者_C百科are effective POMs obtained via
mvn help:effective-pom
- compare mvn executable versions + other involved tools (for example jdk)
- compare environment settings (obtained under Windows using command line's
set
command) - compare
settings.xml
files from user's home directories - compare classpaths generated using
mvn dependency:build-classpath
- delete repository or even both repositories
Any ideas what else can give valuable informations? Maybe there is a better way I am simply missing...
Let's make toast American style: you burn, I'll scrape. --W. Edwards Deming.
Instead of looking for an algorithm to troubleshoot your non repeatable builds, fix the root cause, make them repeatable by following good practices (Maven builds are 100% repeatable if you use it right):
- use the same version of Maven on all machines of a given project (distribute a packaged version)
- use the same version of the JDK (at least the same version for a given project)
- lock down plugins versions in your poms for build reproducibility
- enforce the above rules using the Maven Enforcer Plugin
- use a corporate repository (and only the corporate repository)
- avoid making builds non portable by adding non user specific things in
~/.m2/settings.xml
- put everything under version control (the effective pom should be identical on all machines)
- run clean builds on a build machine (the reference)
I've used Maven in organizations with hundreds of developers without experiencing the problems you're describing. Actually, and I'm sorry to say that, the problems you are facing are not Maven's fault, they're just the result of poor development practices (I don't mean to be rude but that's true).
Not really an answer per se, but we delete the entire local repo on the build machine every week.
The build machine is also restricted to a small set of local and proxy repos that the developers can not edit.
At first we had lots of builds that just stop working after the repo is deleted. Now its a monthly problem. Its trending to a every other month problem.
This has promoted a number of good practices in locking down version numbers, plugin versions, using profiles for local builds, using excludes when needed and adding 3rd party jars to the right places.
I've seen a lot of Maven builds slip up on different machines because of different versions of Maven or Java and associated bugs or features. I've even seen builds fail and pass on the same machine when e.g. built on the commandline vs. built in an IDE.
If commandline tools are called, you may find these are either platform- or machine-dependant. I've seen this most notably in package tasks which create .dmg files on Mac or .msi on Windows machines, and the packaging must be run on these OSs to created specific files.
File encoding of both resources and source files has caused me problems in the past. Checking that the project.build.sourceEncoding property is set seems like useful info. Rather counter-intuitively, this seems to be used when copying or filtering resources, but ignored when dealing with the source files, IIRC.
Track what you do and be able to track what developers do:
- Create a build machine (for release builds), documenting each and every piece of software installed, and each and every configuration option chosen
- Private build machines must be set up the same way to ensure maximum liklihood of a build working
- When a private build fails, list the software & configurations and diff them against the release configuration. Differences are assumed unsupported and must be corrected to reach maximum liklihood of a successful build
精彩评论