How does Maven resolve SNAPSHOT dependencies when there are SNAPSHOTS with different timestamps in the local and the remote repository?
Asked Answered
A

1

26

Say I have a project A in development that depends on project B - which is also currently in development and not yet released.

So, in A's POM file, I have the following section:

<dependency>
  <groupId>com.example</groupId>
  <artifactId>project-b</artifactId>
  <version>1.0.0-SNAPSHOT</version>
</dependency>

At work, we have a remote repo (Nexus) and a CI box (running Jenkins).

When my colleague makes a change to B and commits to SVN, Jenkins will pick that change up, compile it and put it into the remote repo. Around that time, I might open B locally, make a change, compile it and install it into my local repo.

How does Maven now resolve B when I try to mvn clean install A locally?

  • Will it always default to my local SNAPSHOT if it finds one?
  • Will it always default to the remote SNAPSHOT?
  • Will it look at time stamps?
  • Will it do something different?

We got ourselves a bit into a mess the other day, and basically had to manually remove the local repositories to ensure we got the version we were expecting to get. So I'm now trying to figure out what really went on. (Therefore, if you have links to places in the docs that go into detail, that, too, would be much appreciated...) Locally, I sometimes have a few SNAPSHOT builds in my repository folder, one without and a few with what looks like a timestamp after the SNAPSHOT part of the file name...

Aswarm answered 4/9, 2015 at 17:0 Comment(0)
K
17

Artifacts that you just mvn install don't get a timestamp. A timestamp is applied once you mvn deploy to your internal/remote repository. If you look into the maven-metadata-local.xml in your local ~/.m2/repository/B/1.0.0-SNAPSHOT/ folder you'll see lines with:

<updated>YYYYMMDDHHMMSS</updated> 

This is how the Maven dependency resolver decides what the latest snapshot is.

If it happens that you and your colleague deploy to your internal/remote repository within the same second it's up to the repository manager – Nexus in your case – to handle this.

Please note: The paragraphs above rely on my experience with Maven since I haven't seen a docu page where this is described in all details so far. Inputs where to find a reference as well as additions and corrections are highly welcome.

See Maven / Introduction to Repositories for an overview.

If you want to assure that you use the latest snapshots:

„A timestamp after the SNAPSHOT part of the file name“ is unusual to me. AFAIHS it's either the one or the other only. Though this can happen if there is "-SNAPSHOT" in the <artifactId> in your project's POM.

UPDATE

See also:

Kahlil answered 5/9, 2015 at 18:34 Comment(5)
So, if I have a local SNAPSHOT, then my colleague commits to the remote repo, the remote repo will win (as it has a timestamp)? And what if I then make another change to the local SNAPSHOT? Will the remote still win?Aswarm
There is no answer possible who will win without knowing all the circumstances. It depends on your updatePolicy setting, on the point in time Maven last updated your local repository (during a build initiated by you) and whether you override the updatePolicy setting with the command line option -U at your current build. (And, BTW, you and your colleagues deploy to a remote artifact repository. Commiting is for SCMs.) Not only the remote repo artifacts have a timestamp (in the file name). The locals have one, too: in maven-metadata-local.xml.Kahlil
OK, so let's assume I did not change the default update policy. Will maven compare the local jar's timestamp to the remote one's and base its decision on that? Or do local ones (or remote ones) usually have precedence, no matter what (e.g. the local one is 5 days old, there is a newer SNAPSHOT one available remotely, who will win, assuming defaults)? Also thanks for pointing the vocabulary issue out; I guess that slipped in because we commit to SVN and CI deploys for us if the build passes... :)Aswarm
As for the file name, you are right. I have the following files (i.e file name patterns) in my local repo; the artifact was never released (so both are SNAPSHOT builds) artifactId-version-20150904.140213-59.jar and artifactId-version-SNAPSHOT.jar Should have taken a closer look; sorry.Aswarm
Artifacts with a newer timestamp take precedence no matter where they come from. With the default settings "remote timestamps" are checked only once every 24 hrs. The latter means that your local artifact might take precedence (even if there are newer ones available remotely) because it isn't even checked whether newer ones exist remotely.Kahlil

© 2022 - 2024 — McMap. All rights reserved.