[GRADLE-2502] Latest status resolution not working properly since Gradle 1.1 Created: 28/Sep/12  Updated: 04/Jan/13  Resolved: 24/Oct/12

Status: Resolved
Project: Gradle
Affects Version/s: None
Fix Version/s: 1.3-rc-1

Type: Bug
Reporter: Gradle Forums Assignee: Unassigned
Resolution: Fixed Votes: 0


 Description   

Hello everyone,
While migrating to Gradle 1.1, we noticed an issue with dynamic version resolution. Our setup is using a local fs and a remote Ivy repository defined (in this order) using RepositoryHandler's [ivy DSL]([1]http://gradle.org/docs/current/javado...). After we publish a milestone of our plugins (e.g. `1.0-m1`), we are normally also publishing an integration version (e.g. `1.0-m2-SNAPSHOT`) to the remote Ivy repository (Artifactory).

Now if a project depends on our plugin modules using `latest.milestone`, Gradle successfully downloads the `1.0-m1` version. However, if a new `1.0-m2-SNAPSHOT` is uploaded to the local fs repository, this somehow breaks the resolution and Gradle always selects this version, although it's not having a milestone status. Furthermore, it does not load its Ivy descriptor, but uses a default one (see `org.apache.ivy.plugins.resolver.BasicResolver#getDependency`).

The issue is reproducible with Gradle 1.1 and 1.2, could it be due to the fix for GRADLE-2279 :

[2]https://github.com/gradle/gradle/comm...

I can provide you with a test case if needed, meanwhile here is a debug log done with Gradle 1.1 using a buildscript dependency to e.g. `org.foo:my-plugin:latest.milestone`:

Visiting configuration #GradleMilestoneTest;unspecified(classpath).
Visiting dependency #GradleMilestoneTest;unspecified(classpath) - > org.foo#my-plugin;latest.milestone([default])
Attempting to resolve module 'org.foo#my-plugin;latest.milestone' using repositories '[local-fs, remote-http]'
local-fs: no namespace defined: using system
tried D:\Users\detelin\.gradle\local-fs/org.foo/my-plugin/[revision]/ivy-[revision].xml
Listing all in D:\Users\detelin\.gradle\local-fs/org.foo/my-plugin/[revision]/ivy-[revision].xml
using local-fs to list all in D:/Users/detelin/.gradle/local-fs/org.foo/my-plugin/
found 1 resources
local-fs: no latest strategy defined: using default
Waiting to acquire exclusive lock on artifact cache (D:\Users\detelin\.gradle\caches\artifacts-14).
Lock acquired.
Opening cache artifact-at-url.bin (D:\Users\detelin\.gradle\caches\artifacts-14\artifact-at-url.bin)
Closing cache artifact-at-url.bin (D:\Users\detelin\.gradle\caches\artifacts-14\artifact-at-url.bin)
Releasing lock on artifact cache (D:\Users\detelin\.gradle\caches\artifacts-14).
Constructing external resource: D:\Users\detelin\.gradle\local-fs/org.foo/my-plugin/1.0.0-m16-SNAPSHOT/ivy-1.0.0-m16-SNAPSHOT.xml
local-fs: found md file for org.foo#my-plugin;latest.milestone
= > org.gradle.api.internal.externalresource.LocallyAvailableExternalResource@f93ee4 (1.0.0-m16-SNAPSHOT)
parser = ivy parser
impossible to get date for org.gradle.api.internal.externalresource.LocallyAvailableExternalResource@f93ee4: using 'now'
post 1.3 ivy file: using exact as default matcher
local-fs: md rejected by version matcher: 1.0.0-m16-SNAPSHOT [org.gradle.api.internal.externalresource.LocallyAvailableExternalResource@f93ee4]
No resource found for org.foo#my-plugin;latest.milestone: pattern=D:\Users\detelin\.gradle\local-fs/[organisation]/[module]/[revision]/ivy-[revision].xml
tried D:\Users\detelin\.gradle\local-fs/org.foo/my-plugin/[revision]/my-plugin-[revision].jar
Listing all in D:\Users\detelin\.gradle\local-fs/org.foo/my-plugin/[revision]/my-plugin-[revision].jar
using local-fs to list all in D:/Users/detelin/.gradle/local-fs/org.foo/my-plugin/
found 1 resources
Waiting to acquire exclusive lock on artifact cache (D:\Users\detelin\.gradle\caches\artifacts-14).
Lock acquired.
Opening cache artifact-at-url.bin (D:\Users\detelin\.gradle\caches\artifacts-14\artifact-at-url.bin)
Closing cache artifact-at-url.bin (D:\Users\detelin\.gradle\caches\artifacts-14\artifact-at-url.bin)
Releasing lock on artifact cache (D:\Users\detelin\.gradle\caches\artifacts-14).
Constructing external resource: D:\Users\detelin\.gradle\local-fs/org.foo/my-plugin/1.0.0-m16-SNAPSHOT/my-plugin-1.0.0-m16-SNAPSHOT.jar
local-fs: no ivy file found for org.foo#my-plugin;latest.milestone: using default data
[1.0.0-m16-SNAPSHOT] org.foo#my-plugin
checking org.foo#my-plugin;1.0.0-m16-SNAPSHOT[default] from local-fs against [none]
module revision kept as first found: org.foo#my-plugin;1.0.0-m16-SNAPSHOT[default] from local-fs
Performed resolved of module 'org.foo#my-plugin;latest.milestone' in repository 'local-fs': found
Waiting to acquire exclusive lock on artifact cache (D:\Users\detelin\.gradle\caches\artifacts-14).
Lock acquired.
Opening cache dynamic-revisions.bin (D:\Users\detelin\.gradle\caches\artifacts-14\dynamic-revisions.bin)
Resolved revision in dynamic revision cache is expired: will perform fresh resolve of '

{group: org.foo, module: my-plugin, version: latest.milestone}

' in 'remote-http'
Opening cache module-metadata.bin (D:\Users\detelin\.gradle\caches\artifacts-14\module-metadata.bin)
Closing cache module-metadata.bin (D:\Users\detelin\.gradle\caches\artifacts-14\module-metadata.bin)
Closing cache dynamic-revisions.bin (D:\Users\detelin\.gradle\caches\artifacts-14\dynamic-revisions.bin)
Releasing lock on artifact cache (D:\Users\detelin\.gradle\caches\artifacts-14).
remote-http: no namespace defined: using system
tried [3]http://my.ivy.repo:8082/artifactory/r...
Listing all in [4]http://my.ivy.repo:8082/artifactory/r...
using remote-http to list all in [5]http://my.ivy.repo:8082/artifactory/r...
Constructing external resource: [6]http://my.ivy.repo:8082/artifactory/r...
Performing HTTP GET: [7]http://my.ivy.repo:8082/artifactory/r...
Get connection for route {}- >[8]http://my.ivy.repo:8082
Connecting to my.ivy.repo:8082
CookieSpec selected: best-match
Auth cache not set in the context
Target auth state: UNCHALLENGED
Proxy auth state: UNCHALLENGED
Attempt 1 to execute request
...
Attempting to download resource [9]http://my.ivy.repo:8082/artifactory/r....
Releasing connection org.apache.http.impl.conn.ManagedClientConnectionImpl@93b59
Connection can be kept alive indefinitely
found 18 resources
remote-http: no latest strategy defined: using default
Waiting to acquire exclusive lock on artifact cache (D:\Users\detelin\.gradle\caches\artifacts-14).
Lock acquired.
Opening cache artifact-at-url.bin (D:\Users\detelin\.gradle\caches\artifacts-14\artifact-at-url.bin)
Closing cache artifact-at-url.bin (D:\Users\detelin\.gradle\caches\artifacts-14\artifact-at-url.bin)
Releasing lock on artifact cache (D:\Users\detelin\.gradle\caches\artifacts-14).
Constructing external resource: [10]http://my.ivy.repo:8082/artifactory/r...
Constructing external resource metadata: [11]http://my.ivy.repo:8082/artifactory/r...
Performing HTTP HEAD: [12]http://my.ivy.repo:8082/artifactory/r...
Get connection for route {}- >[13]http://my.ivy.repo:8082
Stale connection check
CookieSpec selected: best-match
Cookie [version: 0][name: JSESSIONID][value: dt9tnvma05jj][domain: my.ivy.repo][path: /artifactory][expiry: null] match [my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m16-SNAPSHOT/ivy-1.0.0-m16-SNAPSHOT.xml]
Auth cache not set in the context
Target auth state: UNCHALLENGED
Proxy auth state: UNCHALLENGED
Attempt 1 to execute request
...
Releasing connection org.apache.http.impl.conn.ManagedClientConnectionImpl@1f2ae62
Connection can be kept alive indefinitely
Cached resource is up-to-date (lastModified: Mon Sep 17 04:37:22 EEST 2012). [HTTP: [14]http://my.ivy.repo:8082/artifactory/r...]
remote-http: found md file for org.foo#my-plugin;latest.milestone
= > CachedResource: D:\Users\detelin\.gradle\caches\artifacts-14\filestore\org.foo\my-plugin.0.0-m16-SNAPSHOT\ivy\b74317304baa56f7ef5fb2b663500206ba6a57c7\ivy-1.0.0-m16-SNAPSHOT.xml for [15]http://my.ivy.repo:8082/artifactory/...
parser = ivy parser
downloading CachedResource: D:\Users\detelin\.gradle\caches\artifacts-14\filestore\org.foo\my-plugin.0.0-m16-SNAPSHOT\ivy\b74317304baa56f7ef5fb2b663500206ba6a57c7\ivy-1.0.0-m16-SNAPSHOT.xml for [16]http://my.ivy.repo:8082/artifactory/...
Downloading [17]http://my.ivy.repo:8082/artifactory/r... to D:\Users\detelin\.gradle\caches\artifacts-14\filestore\temp873332335132341332.part
Waiting to acquire exclusive lock on artifact cache (D:\Users\detelin\.gradle\caches\artifacts-14).
Lock acquired.
Opening cache artifact-at-url.bin (D:\Users\detelin\.gradle\caches\artifacts-14\artifact-at-url.bin)
Closing cache artifact-at-url.bin (D:\Users\detelin\.gradle\caches\artifacts-14\artifact-at-url.bin)
Releasing lock on artifact cache (D:\Users\detelin\.gradle\caches\artifacts-14).
post 1.3 ivy file: using exact as default matcher
downloading: parsed downloaded md file for org.foo#my-plugin;1.0.0-m16-SNAPSHOT; parsed=org.foo#my-plugin;1.0.0-m16-SNAPSHOT
remote-http: md rejected by version matcher: 1.0.0-m16-SNAPSHOT [CachedResource: D:\Users\detelin\.gradle\caches\artifacts-14\filestore\org.foo\my-plugin.0.0-m16-SNAPSHOT\ivy\b74317304baa56f7ef5fb2b663500206ba6a57c7\ivy-1.0.0-m1
Waiting to acquire exclusive lock on artifact cache (D:\Users\detelin\.gradle\caches\artifacts-14).
Lock acquired.
Opening cache artifact-at-url.bin (D:\Users\detelin\.gradle\caches\artifacts-14\artifact-at-url.bin)
Closing cache artifact-at-url.bin (D:\Users\detelin\.gradle\caches\artifacts-14\artifact-at-url.bin)
Releasing lock on artifact cache (D:\Users\detelin\.gradle\caches\artifacts-14).
Constructing external resource: [18]http://my.ivy.repo:8082/artifactory/r...
Constructing external resource metadata: [19]http://my.ivy.repo:8082/artifactory/r...
Performing HTTP HEAD: [20]http://my.ivy.repo:8082/artifactory/r...
Get connection for route {}- >[21]http://my.ivy.repo:8082
Stale connection check
CookieSpec selected: best-match
Cookie [version: 0][name: JSESSIONID][value: dt9tnvma05jj][domain: my.ivy.repo][path: /artifactory][expiry: null] match [my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m15/ivy-1.0.0-m15.xml]
Auth cache not set in the context
Target auth state: UNCHALLENGED
Proxy auth state: UNCHALLENGED
Attempt 1 to execute request
...
Releasing connection org.apache.http.impl.conn.ManagedClientConnectionImpl@10ee5b8
Connection can be kept alive indefinitely
Cached resource is up-to-date (lastModified: Thu Sep 13 00:58:25 EEST 2012). [HTTP: [22]http://my.ivy.repo:8082/artifactory/r...]
remote-http: found md file for org.foo#my-plugin;latest.milestone
= > CachedResource: D:\Users\detelin\.gradle\caches\artifacts-14\filestore\org.foo\my-plugin.0.0-m15\ivy\a53996ebe38e506bb45edfb990b225d38769669d\ivy-1.0.0-m15.xml for [23]http://my.ivy.repo:8082/artifactory/r...
parser = ivy parser
downloading CachedResource: D:\Users\detelin\.gradle\caches\artifacts-14\filestore\org.foo\my-plugin.0.0-m15\ivy\a53996ebe38e506bb45edfb990b225d38769669d\ivy-1.0.0-m15.xml for [24]http://my.ivy.repo:8082/artifactory/r...
Downloading [25]http://my.ivy.repo:8082/artifactory/r... to D:\Users\detelin\.gradle\caches\artifacts-14\filestore\temp350452628783015526.part
Waiting to acquire exclusive lock on artifact cache (D:\Users\detelin\.gradle\caches\artifacts-14).
Lock acquired.
Opening cache artifact-at-url.bin (D:\Users\detelin\.gradle\caches\artifacts-14\artifact-at-url.bin)
Closing cache artifact-at-url.bin (D:\Users\detelin\.gradle\caches\artifacts-14\artifact-at-url.bin)
Releasing lock on artifact cache (D:\Users\detelin\.gradle\caches\artifacts-14).
post 1.3 ivy file: using exact as default matcher
downloading: parsed downloaded md file for org.foo#my-plugin;1.0.0-m15; parsed=org.foo#my-plugin;1.0.0-m15
[1.0.0-m15] org.foo#my-plugin
checking org.foo#my-plugin;1.0.0-m15 from remote-http against [none]
module revision kept as first found: org.foo#my-plugin;1.0.0-m15 from remote-http
Performed resolved of module 'org.foo#my-plugin;latest.milestone' in repository 'remote-http': found
Caching resolved revision in dynamic revision cache: Will use 'org.foo#my-plugin;1.0.0-m15' for 'org.foo#my-plugin;latest.milestone'
Waiting to acquire exclusive lock on artifact cache (D:\Users\detelin\.gradle\caches\artifacts-14).
Lock acquired.
Opening cache dynamic-revisions.bin (D:\Users\detelin\.gradle\caches\artifacts-14\dynamic-revisions.bin)
Recording module descriptor in cache: org.foo#my-plugin;1.0.0-m15 [changing = false]
Opening cache module-metadata.bin (D:\Users\detelin\.gradle\caches\artifacts-14\module-metadata.bin)
...
Using module 'org.foo#my-plugin;1.0.0-m16-SNAPSHOT' from repository 'local-fs'
Selecting new module version org.foo#my-plugin;1.0.0-m16-SNAPSHOT
Visiting configuration org.foo#my-plugin;1.0.0-m16-SNAPSHOT(default).
Attaching #GradleMilestoneTest;unspecified(classpath) to its parents.
Attaching org.foo#my-plugin;1.0.0-m16-SNAPSHOT(default) to its parents.

In this case the local fs repository contains `1.0.0-m16-SNAPSHOT` version, while the remote http repository contains `1.0.0-m15` and `1.0.0-m16-SNAPSHOT` (and a bunch of older versions).
It is expected that the `1.0.0-m15` version is selected, but Gradle chooses `1.0.0-m16-SNAPSHOT` instead.

Regards,
Detelin
----------------------------------------------------------------------------------------
[1] http://gradle.org/docs/current/javadoc/org/gradle/api/artifacts/dsl/RepositoryHandler.html#ivy%28groovy.lang.Closure%29
[2] https://github.com/gradle/gradle/commit/461c509978d5e828da5fd77c94a968ac6cf7297a
[3] http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/[revision]/ivy-[revision].xml
[4] http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/[revision]/ivy-[revision].xml
[5] http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/
[6] http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/
[7] http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/
[8] http://my.ivy.repo:8082
[9] http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/
[10] http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m16-SNAPSHOT/ivy-1.0.0-m16-SNAPSHOT.xml
[11] http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m16-SNAPSHOT/ivy-1.0.0-m16-SNAPSHOT.xml
[12] http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m16-SNAPSHOT/ivy-1.0.0-m16-SNAPSHOT.xml
[13] http://my.ivy.repo:8082
[14] http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m16-SNAPSHOT/ivy-1.0.0-m16-SNAPSHOT.xml
[15] http://my.ivy.repo:8082/artifactory/
[16] http://my.ivy.repo:8082/artifactory/
[17] http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m16-SNAPSHOT/ivy-1.0.0-m16-SNAPSHOT.xml
[18] http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m15/ivy-1.0.0-m15.xml
[19] http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m15/ivy-1.0.0-m15.xml
[20] http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m15/ivy-1.0.0-m15.xml
[21] http://my.ivy.repo:8082
[22] http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m15/ivy-1.0.0-m15.xml
[23] http://my.ivy.repo:8082/artifactory/remote-http/com/softw
[24] http://my.ivy.repo:8082/artifactory/remote-http/com/softwar
[25] http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m15/ivy-1.0.0-m15.xml



 Comments   
Comment by Gradle Forums [ 28/Sep/12 ]

Hello Detelin,

>Furthermore, it does not load its Ivy descriptor, but uses a default one (see org.apache.ivy.plugins.resolver.BasicResolver#getDependency).

Hmmm, please check if the problem is not related to incorrect ivy metadata pattern (or incorrect location / name of the ivy.xml in the repository). Otherwise, it does not seem right that the default ivy.xml is generated.

>In this case the local fs repository contains 1.0.0-m16-SNAPSHOT version, while the remote http repository contains 1.0.0-m15 and 1.0.0-m16-SNAPSHOT (and a bunch of older versions).
It is expected that the 1.0.0-m15 version is selected, but Gradle chooses 1.0.0-m16-SNAPSHOT instead.

Why do you expect the 1.0.0-m15 version selected? I might not fully understand your scenario. If Gradle finds the module in a first repository (in your case, the local fs repo) it does not search in the next repos in queue. So, provided that '1.0.0-m16-SNAPSHOT' is the newest version in the local repo, this is the version that will be selected.

Hope that helps!

Comment by Gradle Forums [ 28/Sep/12 ]

> Why do you expect the 1.0.0-m15 version selected?

Module `1.0.0-m15` has `milestone` status while `1.0.0-m16-SNAPSHOT` has `integration` status. Therefore when depending on `latest.milestone` it is expected that `1.0.0-m15` gets resolved.

Comment by Gradle Forums [ 28/Sep/12 ]

Ok, thanks for info. One more clarification - you mentioned that it worked as expected in Gradle 1.0 but no longer in 1.1+ ?

Comment by Gradle Forums [ 28/Sep/12 ]

Yes, we suspect that this is a regression of GRADLE-2279. In 1.0, when the issue was not yet addressed, only resolving via `latest.snapshot` worked while `latest.milestone` and `latest.release` returned an error. But resolving from a resolver chain that has the local repository listed before the remote repository worked. Now, with 1.1, the first issue got fixed but the second one broken.

As mentioned before, we have a use case which we could share. It would require to change the dependency declarations though as they probably don't match with your test repository.

Generated at Wed Jun 30 12:23:42 CDT 2021 using Jira 8.4.2#804003-sha1:d21414fc212e3af190e92c2d2ac41299b89402cf.