Gradle не использует локальный репозиторий Maven для новой зависимости

У меня есть Maven с M2_HOME, определенным для:

  • /Users/manuelj/apache/maven/3.2.5

У меня есть файл settings.xml, расположенный на:

  • /Users/manuelj/apache/maven/3.2.5/conf/settings.xml

где я заявил следующее:

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

Пока здесь с Maven все работает нормально. Любая новая зависимость идет туда.

У меня есть проект, основанный на Gradle, среди многих вещей в моем build.gradle существует следующее:

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

version = '1.0.0'
sourceCompatibility = '1.8'

repositories {
   mavenLocal()
   mavenCentral()
}
… more

Пока здесь все тоже отлично работает. Код компилируется, хорошо работает.

Моя путаница заключается в следующем.

mavenLocal() я понимаю, Gradle mavenLocal() должен использовать тот же путь, что и <localRepository> определенный в файле Maven settings.xml.

Теперь подтверждается, что в локальном репозитории Maven существуют некоторые загруженные зависимости.

Когда я выполняю, например, сборку Gradle, я понял, что

  • Если зависимость уже существует из локального репозитория Maven, она используется оттуда.
  • Если зависимость не существует из Madle Local Repository Gradle, загрузите новую зависимость по /Users/manuelj/.gradle/caches/modules-2/files-2.1: /Users/manuelj/.gradle/caches/modules-2/files-2.1

Я хочу, чтобы новая зависимость шла прямо в тот же локальный репозиторий Maven.

Следовательно, какая дополнительная конфигурация нужна?

Ответ 1

Устранение зависимостей из локального репозитория Maven

Gradle может разрешать артефакты, хранящиеся в локальном репозитории Maven (обычно ~/.m2/repository), с помощью mavenLocal().

Согласно документации, mavenLocal() разрешается следующим образом:

Gradle использует ту же логику, что и Maven, чтобы определить местоположение вашего локального кэша Maven. Если местное хранилище определено в settings.xml, это местоположение будет использоваться. settings.xml в USER_HOME/.m2 имеет приоритет над settings.xml в M2_HOME/conf. Если нет settings.xml, Gradle использует местоположение по умолчанию USER_HOME/.m2/repository.

Чтобы разрешить артефакты из нестандартного локального репозитория Maven, вы можете использовать следующую конфигурацию в build.gradle:

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

(От: Как Gradle разрешает каталог локального репозитория maven?)

Пользовательские репозитории Maven задокументированы здесь.

Хранение артефактов в локальном репозитории Maven

Gradle хранит разрешенные зависимости в своем собственном кэше зависимостей. Кэш зависимостей - это гораздо больше, чем просто хранилище артефактов Maven:

  • Хранит двоичные файлы (jars), метаданные артефактов (POM, файлы Ivy), результаты разрешения зависимостей и дескрипторы модулей.
  • Настроен на производительность, например, более короткие пути к файлам.
  • Дедуплицирующие артефакты: одни и те же двоичные файлы сохраняются только один раз.
  • Отслеживает, откуда появилась зависимость. Зависимость, разрешенная из jcenter(), может отличаться от зависимости, разрешенной из mavenCentral().
  • Автоматический, время и основания использования, очистка кэша.

Артефакты, создаваемые сборкой, можно легко отправить в локальный репозиторий Maven с помощью задачи publishToMavenLocal, предоставленной Плагином публикации Maven.

Но как насчет разрешенных зависимостей? По вышеупомянутым причинам Gradle не может хранить зависимости в локальном репозитории Maven. В настоящее время нет встроенных функций даже для публикации зависимостей в локальном репозитории Maven из сценария сборки. Итак, каковы ваши варианты:

  • Создайте сценарий оболочки, который выполняет необходимую работу. Даниэль Дитрих однажды написал один и опубликовал его в Twitter.
  • Используйте прокси-артефакт, такой как Nexus или Artifactory. Maven и Gradle могут быть настроены на использование зависимостей от одного и того же прокси. Эта настройка довольно распространена в профессиональной среде и моих личных предпочтениях.

Ответ 2

Использование

mavenLocal()

например:

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')
}

Я использую Gradle 3.5

Ответ 3

Это заставило меня пить.

Если я выполняю mvn install для проекта с версией 1.1.1.SNAPSHOT он попадает в мой локальный репозиторий maven (~/m2/repository/...) без ошибок. Однако Gradle, использующий mavenLocal(), не будет пытаться найти его в локальном репозитории maven (используя ./gradlew bootRun --debug и ./gradlew bootRun --debug журналы).

Если я изменю версию на 1.1.1-SNAPSHOT (обратите внимание на тире), то Gradle попытается и найдет хранилище.

Для меня не имеет смысла, что Maven находит это действительным номером версии для локального использования, но Gradle полностью его игнорирует.

Ответ 4

Я столкнулся с этой проблемой, потому что я работаю над старым проектом, где мне нужно запустить мою сборку с помощью команды sudo gradle build. В сборке используется копирование файлов XSD, для которых требуются права root. Я решил не использовать решения предыдущих ответов, потому что я не хотел менять файл сборки; Я не хотел случайно проверять мои изменения build.gradle. Я обнаружил, что Gradle проверял mavenLocal в папке /var/root/.m2. Мое решение состояло в том, чтобы скопировать /Users/me/.m2/settings.xml в /var/root/.m2 и добавить строку для localRepository, чтобы вернуться в мою папку /Users/me/.m2. Пример строки и где ее добавить:

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