Random build failures on Jenkins
I have experienced similar things. Two important tips we have learned to maintain consistency over time:
- Configure the build to "Checkout fresh sources" each time you build. Sometimes things can otherwise go stale
- Check if you are using
clean package
orclean install
.install
will store the artefact in the.m2
repository local to the user running Jenkins. If you are not, any given project may have to download it's dependencies from your configured repository during it's build time. I would recommend usingclean install
just to get the local artefact in position ready for dependant builds.
It is important to double-check each of your Jenkins builds against those two rules. Inconsistency between projects that inter-depend is also the source of random confusion.
In addition to what @jmkgreen says, or if you try those steps and they don't solve the problem, I'd check for a problem in the artifact's classpath. Surefire and JUnit don't guarantee that tests will run in a particular order. Running tests in a different order may cause classes to be loaded in a different order and result in these weird issues. This blog post has a really nice explanation.
If that's what seems to be happening, here are some steps you can take to clean up the artifact's dependencies.
Remove any unneeded dependencies
Ensure there is only one version of each dependency included (e.g. only one Spring framework).
Pay particular attention to artifacts where the group ID or artifact ID has changed. For these cases, the Maven dependency resolution process cannot detect that one artifact should override the other and includes both. This can cause interesting and sometimes non-deterministic problems. One example is spring.jar
vs. spring-core.jar
.
If the application includes more than one dependency supporting the same functionality, you'll need to manually exclude the unwanted dependencies as described in the Maven documentation.
Ensure that related dependencies are all using the same version
For example, if the project includes several Spring artifacts (spring-core, spring-jdbc, spring-aop etc.) make sure the version is the same for all of them. Use dependencyManagement
or add direct dependencies as needed to make versions consistent.
Replace any -all
-type dependencies with their component parts
... and only the ones needed by the project. -all
jars may contain every class needed to run the library - repackaged into the jar file where Maven's dependency resolution process can't get at them - instead of referencing them as dependencies.
For example, mockito-all
contains a repackaged version of Hamcrest, which could conflict with any other version of Hamcrest a project wants to use (and likely won't cause the hard-to-fix problems until runtime!).