70

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?

Vy Do
  • 46,709
  • 59
  • 215
  • 313
Manuel Jordan
  • 15,253
  • 21
  • 95
  • 158

4 Answers4

69

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?)

Custom Maven repositories are documented here.

Storing Artifacts in the Local Maven Repository

Gradle stores resolved dependencies in its own Dependency Cache. 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.

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:

  • Create a shell script that does the necessary legwork. Daniel Dietrich once wrote one and published it on Twitter (Gist).
  • Use an artifact proxy like Nexus or Artifactory. Maven and Gradle can be configured to consume dependencies from the same proxy. This setup is quite common in professional environments and my personal preference.
thokuest
  • 5,800
  • 24
  • 36
  • 1
    Thanks by the reply, Remember I want that the new dependencies gotten through Gradle go to the Maven Local Repository. Check the comment in my question. There is a link to other question. Sadly there is no solution yet. – Manuel Jordan Aug 22 '15 at 19:45
  • 1
    Neither this answer nor the answer below works for me (gradle version 4.8.1). I have an artifact in the local repo but gradle doesn't seem to see it, whereas maven itself has no problem with it. Adding `apply plugin: 'maven'` doesn't help – Jezor Jul 19 '18 at 16:44
  • @thokuest I am waiting for the version 4.9 to be available in AUR in hopes that the one I have is just broken (; – Jezor Jul 19 '18 at 18:42
  • @Jezor Gradle 4.9 has just been released: https://docs.gradle.org/4.9/release-notes.html – thokuest Jul 19 '18 at 19:09
  • Does not work and gives me this error: > Build was configured to prefer settings repositories over project repositories but repository 'maven' was added by build file 'app\build.gradle' – Jörg Jun 19 '22 at 09:10
  • @Jörg see https://stackoverflow.com/a/69197871/5006866 – thokuest Jun 19 '22 at 13:10
25

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

Vy Do
  • 46,709
  • 59
  • 215
  • 313
  • 2
    Nowadays you should not use mavenLocal() !! -> https://docs.gradle.org/current/userguide/declaring_repositories.html#sec:case-for-maven-local – Peter S. Oct 13 '20 at 09:01
  • mavenLocal() has its uses and purposes, so saying it should not be used is incorrect. When testing multiple dependencies, mavenLocal() is very useful. On a typical CI box, the local maven repo SHOULD BE clean/empty so you are never building with local artifacts, but when testing locally it is fine to use mavenLocal(). – DustinB May 24 '23 at 13:50
15

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.

Richard Collette
  • 5,462
  • 4
  • 53
  • 79
  • 3
    OMG. Thanks for sharing - I was debugging for someting like this for quite some time. Gradle is so much of a pointless "Reinvent the wheel" tool. Insead of people contributing to make maven better, they create their own tool with its own flaws, bells and whistles... – Jörg Jun 19 '22 at 09:16
0

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>
entpnerd
  • 10,049
  • 8
  • 47
  • 68