Gradle does not use the Maven Local Repository for a new dependency

Gradlebuild.gradle

Gradle Problem Overview


I have Maven with M2_HOME defined to /Users/manuelj/apache/maven/3.2.5

I have the settings.xml file, located on /Users/manuelj/apache/maven/3.2.5/conf/settings.xml

where I have the following declared:

<localRepository>/Users/manuelj/apache/maven/repository</localRepository>

Until here with Maven all works fine. Any new dependency goes there.

I have a project based with Gradle, among many things in my build.gradle, exists the following:

apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'eclipse'
apply plugin: 'application'

version = '1.0.0'
sourceCompatibility = '1.8'

repositories {
   mavenLocal()
   mavenCentral()
}
… more

Until here, all works fine too. Code compile, executes well.

My confusion is the following.

According with my understanding is that Gradle's mavenLocal() should use the same path than <localRepository> defined on Maven's settings.xml file.

Now confirming that in the Maven local repository exists some dependencies already downloaded.

When I execute for example gradle build, I did realize that

  • If a dependency already exists from the Maven Local Repository, it is used from there.
  • If a dependency does not exist from the Maven Local Repository Gradle download the new dependency to: /Users/manuelj/.gradle/caches/modules-2/files-2.1

I want that the new dependency go directly to the same Maven Local Repository.

Therefore, what extra configuration is need it?

Gradle Solutions


Solution 1 - Gradle

Resolving Dependencies From Local Maven Repository

Gradle is able to resolve artifacts stored in the local Maven repository (usually ~/.m2/repository) via mavenLocal().

According to the documentation, mavenLocal() is resolved like this:

> Gradle uses the same logic as Maven to identify the location of your local Maven cache. If a local repository location is defined in a settings.xml, this location will be used. The settings.xml in USER_HOME/.m2 takes precedence over the settings.xml in M2_HOME/conf. If no settings.xmlis available, Gradle uses the default location USER_HOME/.m2/repository.

To resolve artifacts from a non-standard local Maven repository, you can use the following configuration in your build.gradle:

repositories {
    maven {
        url '/Users/manuelj/apache/maven/repository'
    }
}

(From: [How does Gradle resolve the directory of the local maven repository?][2])

Custom Maven repositories are documented [here][3].

Storing Artifacts in the Local Maven Repository

Gradle stores resolved dependencies in its own [Dependency Cache][4]. The dependency cache is so much more than just a simple Maven artifact repository:

  • Stores binaries (jars), artifact meta-data (POM, Ivy files), dependency resolution results and module descriptors.
  • Tuned for performance, for example shorter file paths.
  • De-duplicates artifacts: Same binaries are stored only once.
  • Tracks where a dependency came from. A dependency resolved from jcenter() might be different to the one resolved from mavenCentral().
  • Automatic, time and usage bases, cache cleanup.

Artifacts produced by the build can be easily pushed to the local Maven repository via publishToMavenLocal task contributed by the [Maven Publish Plugin][5].

But what about resolved dependencies? For the aforementioned reasons, Gradle cannot store dependencies in the local Maven repository. There's currently no built-in functionality to even publish dependencies to the Maven's local repository from the build script. So what are your options:

Solution 2 - Gradle

Use

mavenLocal()

for example:

buildscript {
	ext {
		springBootVersion = '2.0.0.M1'
	}
	repositories {
		mavenCentral()
		mavenLocal()
		maven { url "https://repo.spring.io/snapshot" }
		maven { url "https://repo.spring.io/milestone" }
	}
	dependencies {
		classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
	}
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
	mavenCentral()
	mavenLocal()
	maven { url "https://repo.spring.io/snapshot" }
	maven { url "https://repo.spring.io/milestone" }
}


dependencies {
	compile('org.springframework.boot:spring-boot-starter-data-jpa')
	compile('org.springframework.boot:spring-boot-starter-web')
	compile('com.oracle:ojdbc6:11.2.0.4')
	testCompile('org.springframework.boot:spring-boot-starter-test')
}

I am using Gradle 3.5

Solution 3 - Gradle

This drove me to drink.

If I do mvn install for a project having a version of 1.1.1.SNAPSHOT it goes into my local maven repository (~/m2/repository/...) with no errors. However, Gradle using mavenLocal() will not attempt to locate it in the local maven repository (having used ./gradlew bootRun --debug and inspecting the logs).

If I change the version to 1.1.1-SNAPSHOT (note the dash), then Gradle will attempt, and will find the repository.

It doesn't make sense to me that Maven finds this to be a valid version number for local use, but Gradle completely ignores it.

Solution 4 - Gradle

I came across this issue because I'm working on a legacy project where I need to run my build with the sudo gradle build command. The build involves copying XSD files, which require root permissions. I opted not to employ the solutions of the previous answers because I didn't want to change the build file; I didn't want to accidentally checkin my build.gradle changes. What I found was that Gradle was checking for mavenLocal in the /var/root/.m2 folder. My solution was to copy /Users/me/.m2/settings.xml to /var/root/.m2 and add a line for the localRepository to point back to my /Users/me/.m2 folder. A sample line and where to add it is:

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                        http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <localRepository>/Users/me/.m2/repository</localRepository>
  <profiles>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionManuel JordanView Question on Stackoverflow
Solution 1 - GradlethokuestView Answer on Stackoverflow
Solution 2 - GradleJames GrahamView Answer on Stackoverflow
Solution 3 - GradleRichard ColletteView Answer on Stackoverflow
Solution 4 - GradleentpnerdView Answer on Stackoverflow