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. 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 :
https://github.com/gradle/gradle/commit/461c509978d5e828da5fd77c94a968ac6cf7297a
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 http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/[revision]/ivy-[revision].xml
Listing all in http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/[revision]/ivy-[revision].xml
using remote-http to list all in http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/
Constructing external resource: http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/
Performing HTTP GET: http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/
Get connection for route {}- >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 http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/.
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: http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m16-SNAPSHOT/ivy-1.0.0-m16-SNAPSHOT.xml
Constructing external resource metadata: http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m16-SNAPSHOT/ivy-1.0.0-m16-SNAPSHOT.xml
Performing HTTP HEAD: http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m16-SNAPSHOT/ivy-1.0.0-m16-SNAPSHOT.xml
Get connection for route {}- >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: http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m16-SNAPSHOT/ivy-1.0.0-m16-SNAPSHOT.xml]
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 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 http://my.ivy.repo:8082/artifactory/…
Downloading http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m16-SNAPSHOT/ivy-1.0.0-m16-SNAPSHOT.xml 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: http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m15/ivy-1.0.0-m15.xml
Constructing external resource metadata: http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m15/ivy-1.0.0-m15.xml
Performing HTTP HEAD: http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m15/ivy-1.0.0-m15.xml
Get connection for route {}- >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: http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m15/ivy-1.0.0-m15.xml]
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 http://my.ivy.repo:8082/artifactory/remote-http/com/softw
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 http://my.ivy.repo:8082/artifactory/remote-http/com/softwar
Downloading http://my.ivy.repo:8082/artifactory/remote-http/org.foo/my-plugin/1.0.0-m15/ivy-1.0.0-m15.xml 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