Gradle pulling stale SNAPSHOT dependencies

I’m having the same issue as described in Gradle does not check SNAPSHOT timestamps across repos

I have projectA that depends on projectB-SNAPSHOT. When a new version projectB-SNAPSHOT is uploaded, projectA does not detect a newer version of projectB-SNAPSHOT, and continues to use a stale version.

To troubleshoot this issue, I do NOT have mavenLocal() as a repository, have projectB-SNAPSHOT as a changing module, and my configuration resolution strategy does not have caching turned on for changing modules.

dependencies {
implementation (‘projectB-SNAPSHOT’) { changing = true }
}

configurations.all {
resolutionStrategy{
cacheChangingModulesFor 0, ‘seconds’
}
}

I have tried running with --refresh-dependencies, and no luck.

While debugging I can see the log message “Found cached version of changing module” from CachingModuleComponentRepository.resolveComponentMetaDataFromCache(…).

There’s either a misconfiguration on my part, or gradle does not think this module should be refreshed.

The only way I can get this SNAPSHOT dependency to update is delete ~/.gradle/caches/modules-2/metadata-2.31/descriptors/.

I have filed another Help topic on how to attach Gradle’s source code so I can debug what it’s doing - Debug Gradle Source Code .

Any suggestions are appreciated. Thanks!

Can you please provide your repository {} configuration or a reproducible example project? As mentioned in the other thread, Gradle will take the snapshot from the first repository where it finds it. It will not check other repositories.

Here is the repositories code block. If you need more than this I will put together a small sample project this evening.

  allprojects {
    repositories {
        maven {
          url "http://<internalRepo>/nexus/content/groups/public/"
          credentials {
            username "<userName>"
            password "<password>"
          }
        }
      }
    }

After the weekend (more than 24 hours since last snapshot update), the artifact metadata expired.

What defines the metadata cache time?

The following log output is what I would expect to see:
[DEBUG] [org.gradle.api.internal.artifacts.ivyservice.ivyresolve.RepositoryChainComponentMetaDataResolver] Attempting to resolve component for foo.bar:foo-bar:0.0.3-SNAPSHOT using repositories [maven]

[DEBUG] [org.gradle.api.internal.artifacts.ivyservice.ivyresolve.CachingModuleComponentRepository] Cached meta-data for changing module is expired: will perform fresh resolve of ‘foo.bar:foo-bar:0.0.3-SNAPSHOT’ in ‘maven’

[DEBUG] [org.gradle.internal.resource.transfer.DefaultCacheAwareExternalResourceAccessor] Constructing external resource: http:///nexus/content/groups/public/foo/bar/foo-bar/0.0.3-SNAPSHOT/maven-metadata.xml

[INFO] [org.gradle.cache.internal.DefaultCacheAccess] Creating new cache for metadata-2.31/artifact-at-url, path /Users/user/.gradle/caches/modules-2/metadata-2.31/artifact-at-url.bin, access org.gradle.cache.internal.DefaultCacheAccess@336bef63

[DEBUG] [org.gradle.cache.internal.btree.BTreePersistentIndexedCache] Opening cache artifact-at-url.bin (/Users/user/.gradle/caches/modules-2/metadata-2.31/artifact-at-url.bin)

[DEBUG] [org.gradle.internal.progress.DefaultBuildOperationExecutor] Build operation ‘Metadata of http:///nexus/content/groups/public/foo/bar/foo-bar/0.0.3-SNAPSHOT/maven-metadata.xml’ started

[DEBUG] [org.gradle.internal.resource.transport.http.HttpResourceAccessor] Constructing external resource metadata: http:///nexus/content/groups/public/foo/bar/foo-bar/0.0.3-SNAPSHOT/maven-metadata.xml

[DEBUG] [org.gradle.internal.resource.transport.http.HttpClientHelper] Performing HTTP HEAD: http:///nexus/content/groups/public/foo/bar/foo-bar/0.0.3-SNAPSHOT/maven-metadata.xml

After this update, I update the snapshot and the following is logged:

[DEBUG] [org.gradle.api.internal.artifacts.ivyservice.ivyresolve.RepositoryChainComponentMetaDataResolver] Attempting to resolve component for foo.bar:foo-bar:0.0.3-SNAPSHOT using repositories [maven]

[DEBUG] [org.gradle.api.internal.artifacts.ivyservice.ivyresolve.CachingModuleComponentRepository] Found cached version of changing module ‘foo.bar:foo-bar:0.0.3-SNAPSHOT’ in ‘maven’

[DEBUG] [org.gradle.api.internal.artifacts.ivyservice.ivyresolve.CachingModuleComponentRepository] Using cached module metadata for module ‘foo.bar:foo-bar:0.0.3-SNAPSHOT’ in ‘maven’

[DEBUG] [org.gradle.api.internal.artifacts.ivyservice.ivyresolve.RepositoryChainComponentMetaDataResolver] Using foo.bar:foo-bar:0.0.3-SNAPSHOT from Maven repository ‘maven’

I have a project that has one dependency (foo-bar)

plugins {
id ‘org.springframework.boot’ version ‘1.5.2.RELEASE’
}

group 'foo.bar’
version ‘1.0-SNAPSHOT’

sourceCompatibility = 1.8

repositories {
maven {
url "http:///nexus/content/groups/public/"
credentials {
username "user"
password “password”
}
}
}

dependencies {
implementation (‘foo.bar:foo-bar:0.0.3-SNAPSHOT’) { changing = true }
}

configurations.all {
resolutionStrategy{
cacheChangingModulesFor 0, ‘seconds’
}
}

Do you also see this problem without the spring boot plugin?

1 Like

Thanks so much for taking the time to look at this. I do not see this issue when I remove the spring boot plugin.

When I have changing = true, I see the expected log message:
Cached meta-data for changing module is expired: will perform fresh resolve of ‘foo.bar:foo-bar:0.0.3-SNAPSHOT’ in ‘maven’.

When I do not have a changing module, I see the expected log message:
Found cached version of changing module

I did a little more research around this. It looks like once you apply the spring boot plugin, you have to use Spring’s Dependency Management Plugin rules and set dependencyManagement resolutionStrategy cacheChangingModulesFor to 0 seconds.

This relates to https://github.com/spring-projects/spring-boot/issues/7411
The documentation for dependencyManagement resolutionStrategy https://github.com/spring-gradle-plugins/dependency-management-plugin#configuring-the-dependency-management-resolution-strategy

1 Like

Thank you for investigating this! This seems easy to miss indeed. I hope other users will find this useful :slight_smile: