Overriding a maven repository with a local maven repository

I am trying to configure a local maven repository with some pre-cached dependencies and additional repositories for other dependencies that aren’t found locally.

For various reasons, I can’t use the default maven local repository, but I thought a similarly structured maven repository on the local filesystem should behave the same:

My current build.gradle looks like this:

rootProject.buildscript {
  repositories {
    maven {
      url "/home/user/m2repo"
    }
    maven {
      url "https://server.com/maven"
    }
  }
  dependencies {
    classpath "org.something:identifier:0.2.1"
  }
}

What I’ve noticed is that:

  • If identifier 0.2.1 is not in m2repo or if m2repo is not present, it gets fetched from server.com/maven - GREAT
  • If identifier 0.2.1 is in m2repo and server.com/maven is down, it gets fetched from m2repo - GREAT
  • BUT, if both m2repo and server.com/maven have identifier 0.2.1, it still gets pulled from server.com/maven - WRONG

Why is this happening and how do I force Gradle to use the cached version if it is available?

According to the official docs: “Gradle will look for a dependency in each repository in the order they are specified, stopping at the first repository that contains the requested module”

Any help, hints, ideas are appreciated.

The behavior should be as described in the docs, that is, we should go with the first one we find, in order of how the repositories are declared. The other thing that might be happening is a) there is something (likely an init script) that is registering the other repository first or b) the module is considered dynamic (i.e ‘1.+’) and we are checking all repos and picking the newest one.

Hi Mark,
Thanks for your response.
I have defined the module with a specific version as described in the question (if that is not the case, could you please tell me how is it not?) and I have no other init script running setting up that remote repository (it’s the only place it is define).
Could you let me know how to debug what else could be going on to make Gradle look in the remote repo even when the local one has the asset?
Thanks,
Julian

This problems is still relevant and not solved.

I posted a more complete rendition with a stand-alone sample in stack overflow in case that helps bring clarity to the issue: http://stackoverflow.com/questions/35213585/getting-gradle-to-use-an-artifact-from-a-local-maven-repository

One possibility this may be happening is, as Mark said, the local maven repository has something in the way it’s created or declared that makes Gradle treat its artifacts as if they were transient.

Could you please specify how does Gradle decide that a maven repository can be used as authoritative or not? A pointer to the code where this happens would be appreciated too.

The answer on stack overflow is correct. Gradle first searches for artifact metadata (pom.xml or ivy.xml) and will resolve the artifact from the first repository in which it is found. Only if no metadata is available will it revert to simply searching for the artifact itself. My guess is that the local repo is missing a POM file. Details on how dependency resolution is done can be found in the user guide.

https://docs.gradle.org/current/userguide/dependency_management.html#sec:dependency_resolution

Thanks Mark. That was indeed the issue. After modifying my maven download strategy to get it to include pom files, Gradle started using this repository properly.

Thank you for your help.