Avoid Publishing SNAPSHOTs to Nexus

Once in a while I’m running into people who deploy SNAPSHOT versions of Maven dependencies to a company-wide Nexus server with a job on a CI server. This is usually a very bad idea, especially when using branches.

Scenario: Two developers, John and Mary, each working in their own branch. They push their branches, CI builds them and they end up on Nexus.

Problem: Nexus doesn’t know or care about branches. Whichever job finishes last wins.

Often, this is not a problem. Now let’s add another project B. B depends on A.

As long as B depends on a release of A, everything is fine.

Now, John needs to make some changes in A. So he updates the dependency in B to A-x.y.z-SNAPSHOT. Everything is still fine, since Mary still uses the latest release of A.

Then Mary also creates a feature branch in her clone of A. That still doesn’t break anything because Maven caches SNAPSHOTs for a day.

The next morning, John makes a change to B and builds it.

This build might break when Mary’s CI job finished last!

The problem here, which can go unnoticed for years, is that Maven silently downloaded Mary’s version of A onto John’s computer and used that to compile. John will see the source code from his branch of A but the binaries will be something else.

Eventually, one of them will make a small changes which affects the others project. They will see MethodNotFoundException or get strange compile errors while the source code (which isn’t affected by this) will look perfectly fine or unit tests will break in odd ways.

That is the main reason why you shouldn’t deploy SNAPSHOT branches to a shared Maven repository: It creates a small chance for subtle bugs which will take a long time to find since your mental model (“I see the source, this is what I get”) will be wrong.

You can get away with publishing the master branch to Nexus (i.e. only a single branch with SNAPSHOTs will ever be published to Nexus).

Note: If your CI server shares local Maven repositories between projects, your builds can fail on the CI server for the same reason. Configure your CI server for per-project local repositories and wipe them before the build to avoid such issues for sure.

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 )

Google+ photo

You are commenting using your Google+ 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 )

w

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.