Версия TL;DR
Если вы не можете найти библиотеку (зависимость от Maven), необходимую для вашего проекта, после завершения работы Bintray/JCenter (или другой подобной службы), но она все еще есть в вашем локальном кэше Gradle, вы можете легко настроить свой собственный локальный репозиторий Maven с этой библиотекой в качестве замены и сохранить файлы для столько, сколько вам нужно (подробности см. в параграфах “Поиск кэшированных зависимостей в кэше Gradle” и “Настройка локального репозитория Maven”).
Просто небольшой контекст
Несколько месяцев назад JFrog объявила, что она закрывает некоторые из своих сервисов, включая Bintray и Center, где размещено множество зависимостей. Согласно MvnRepository , в Center насчитывается 841 529 индексированных jar , и его популярность в последние годы очень быстро растет 🚀
Неожиданный поворот событий
Закрытие Bintray и Center было запланировано на 1 мая 2021 года, хотя 27 апреля JFrog обновила свое первоначальное объявление, заявив, что они “сохранят JCenter в качестве хранилища, доступного только для чтения, на неопределенный срок”. Это звучит очень утешительно, но, несмотря на это, я больше не мог получить доступ к нескольким зависимостям. Я думаю, что некоторые из них были размещены в Center, по крайней мере, в соответствии с MvnRepository, так что это меня немного удивило, но, возможно, у меня были некоторые дополнительные проблемы, возможно, неправильная конфигурация, такая как неправильный порядок объявлений репозиториев в Gradle (сейчас не помню 😅 ).
В любом случае, поскольку некоторые из моих зависимостей также были размещены на Bintray, я решил, что было бы лучше просто перейти как от Bintray, так и от JCenter. Итак, я попробовал, и поначалу потерпел сокрушительную неудачу, что привело меня к необычному решению этой проблемы.
Теория против практики
Когда вы читаете некоторые сообщения в блоге и статьи о запланированном завершении работы Bintray/JCenter и путях миграции, все они утверждают, что вы можете просто переключиться на другой репозиторий Maven (предпочтительно Maven Central). О чем они обычно не упоминают, так это о том, что вы можете считать себя действительно удачливым, если добьетесь успеха.
Во многих случаях вы обнаружите, что по какой-то причине переключение невозможно, например, либо нет другого репозитория Maven, в котором размещены нужные вам библиотеки, либо окажется, что авторы библиотек запланировали миграцию только для новых или предстоящих выпусков своих библиотек. Иногда обновление версии зависимости не вызывает особых проблем, особенно если это ваша прямая зависимость, с которой вы знакомы, и если она обратно совместима. Это становится намного сложнее, когда эти зависимости являются транзитивными или когда оказывается, что их более новые версии требуют много дополнительной работы на стороне клиента.
Когда я просмотрел все неразрешимые зависимости, мне стало ясно, что это будет не похоже на прогулку в парке, а совсем наоборот.
Как найти все недостающие зависимости сразу
Несмотря на то, что я все еще мог создавать свой проект локально благодаря Gradle cache, сборки автоматической непрерывной интеграции в TeamCity терпели неудачу (и это также то, как я узнал о проблеме в первую очередь) с ошибками, такими как:
> Could not resolve com.datadoghq:dd-sdk-android:1.5.1. Required by: project :app > project :datadog > Could not resolve com.datadoghq:dd-sdk-android:1.5.1. > Could not get resource 'https://dl.bintray.com/datadog/datadog-maven/com/datadoghq/dd-sdk-android/1.5.1/dd-sdk-android-1.5.1.pom'. > Could not GET 'https://dl.bintray.com/datadog/datadog-maven/com/datadoghq/dd-sdk-android/1.5.1/dd-sdk-android-1.5.1.pom'. Received status code 403 from server: Forbidden
Выполнение следующей команды позволило мне быстро найти все неразрешимые зависимости:
./gradlew :app:dependencies | grep FAILED | grep -v "project :"
Объяснение:
:app:dependencies
просто перечисляет все зависимости проектов, поскольку app является основным модулем приложения,ошибка grep
фильтрует выходные данные таким образом, чтобы печатались только неразрешимые зависимости,grep -v "project:"
отфильтровывает ненужные зависимости модулей в многопроектной сборке , о которой также может быть сообщено какСБОЙ
.
Вероятно, вы увидите некоторые дублированные записи в выводе консоли, поэтому вы можете попробовать избавиться от них с помощью некоторых дополнительных команд и т.д., Но для меня этого было достаточно.
Выходные данные могут выглядеть следующим образом (первые 10 строк):
| +--- com.linkedin.dexmaker:dexmaker:2.21.0 FAILED | +--- com.google.android:flexbox:1.0.0 FAILED +--- com.android.volley:volley:1.1.1 FAILED | | +--- com.linkedin.dexmaker:dexmaker:2.21.0 FAILED | +--- com.google.android:flexbox:1.0.0 FAILED | +--- com.android.volley:volley:1.1.1 FAILED | +--- com.linkedin.dexmaker:dexmaker:2.21.0 FAILED | | +--- com.linkedin.dexmaker:dexmaker:2.21.0 FAILED | +--- com.amitshekhar.android:debug-db:1.0.6 FAILED | | | +--- com.google.android:flexbox:1.0.0 FAILED
Как найти ваши зависимости в других репозиториях Maven
Теперь, зная, какие зависимости вы пропускаете, вы можете использовать такой сервис, как MvnRepository , чтобы узнать, есть ли другие репозитории Maven, в которых они размещены. Например, в случае этой зависимости:
| +--- com.linkedin.dexmaker:dexmaker:2.21.0 FAILED
вы увидите на этой странице , что:
- эта конкретная версия, т.е.
2.21.0
, размещается только на JCenter; - более новая версия,
2.28.1
, размещен на Maven Central.
В этом случае вы не можете использовать какой-либо другой репозиторий Maven для получения текущей версии зависимости, но вы можете попытаться обновить его.
Кстати, разработчики Dexmaker заявили, что не будут переносить старую версию здесь .
Как применить переходную версию зависимости
Поскольку в большинстве случаев Dexmaker будет не вашей прямой зависимостью, а транзитивной (в моем случае она используется популярной библиотекой mocking Kotlin, MockK ), вы не сможете просто изменить версию где-нибудь в вашем конфигурационном файле Gradle.
Чтобы обновить версию переходной зависимости, вы можете использовать constraints like:
dependencies { constraints { implementation("com.linkedin.dexmaker:dexmaker:2.28.1") { because("The default version used by MockK 1.9.3 is hosted on JCenter only") } } }
или вы можете использовать стратегию разрешения , например:
allprojects { configurations.all { resolutionStrategy { force("com.linkedin.dexmaker:dexmaker:2.28.1") } } }
Зависимости, которые я не смог найти в другом месте
К сожалению, история на этом не заканчивается. Обновление зависимостей может привести к дальнейшим проблемам. Некоторые из них могут быть взаимно несовместимыми, в то время как другие потребуют обновления некоторых частей кода в вашем проекте, что может потребовать больших усилий. Более того, может оказаться, что автор библиотеки больше не поддерживает ее или у него просто не было достаточно времени, чтобы загрузить ее в другой репозиторий Maven, такой как Maven Central (который, кстати, считается очень строгим с точки зрения проверки ).
Во всех этих случаях вам может потребоваться каким-то образом сохранить текущую версию зависимости. Я объясню, как это сделать, в следующих параграфах, так что продолжайте читать 🙂 .
Я решил сохранить следующие зависимости, которые я больше нигде не мог найти:
com.datadoghq:dd-sdk-android:1.5.1
(прямой)com.savvy.datepicker: выбор диапазона:1.3.0
(прямой)com.google.android:flexbox:1.0.0
(переходный)com.android.volley:volley:1.1.1
(переходный)com.linkedin.dexmaker:dexmaker:2.21.0
(переходный)com.sunmi:библиотека принтеров:1.0.13
(прямая)
Поиск кэшированных зависимостей в кэше Gradle
К счастью, Gradle кэширует зависимости локально, так что я смог легко найти их все. По умолчанию вы должны проверить домашний каталог вашего пользователя: ~/.gradle
. Здесь вы можете найти полное объяснение расположения каталогов.
Вы можете выполнить подобную команду, чтобы найти кэшированные файлы зависимостей:
find ~/.gradle/caches/modules-2/files 2.1/com.linkedin.dexmaker
и он напечатает вывод, подобный:
/Users/azabost/.gradle/caches/modules-2/files-2.1/com.linkedin.dexmaker /Users/azabost/.gradle/caches/modules-2/files-2.1/com.linkedin.dexmaker/dexmaker /Users/azabost/.gradle/caches/modules-2/files-2.1/com.linkedin.dexmaker/dexmaker/2.21.0 /Users/azabost/.gradle/caches/modules-2/files-2.1/com.linkedin.dexmaker/dexmaker/2.21.0/bdfd84d002e265ab7cf7f54a71a17717f831a57d /Users/azabost/.gradle/caches/modules-2/files-2.1/com.linkedin.dexmaker/dexmaker/2.21.0/bdfd84d002e265ab7cf7f54a71a17717f831a57d/dexmaker-2.21.0-javadoc.jar /Users/azabost/.gradle/caches/modules-2/files-2.1/com.linkedin.dexmaker/dexmaker/2.21.0/423b7b6e4d772e274ba03646284b0cea83faca56 /Users/azabost/.gradle/caches/modules-2/files-2.1/com.linkedin.dexmaker/dexmaker/2.21.0/423b7b6e4d772e274ba03646284b0cea83faca56/dexmaker-2.21.0.pom /Users/azabost/.gradle/caches/modules-2/files-2.1/com.linkedin.dexmaker/dexmaker/2.21.0/680f2dbbb51f2892a4fdbbd9269d628e0b3270b3 /Users/azabost/.gradle/caches/modules-2/files-2.1/com.linkedin.dexmaker/dexmaker/2.21.0/680f2dbbb51f2892a4fdbbd9269d628e0b3270b3/dexmaker-2.21.0.jar /Users/azabost/.gradle/caches/modules-2/files-2.1/com.linkedin.dexmaker/dexmaker/2.21.0/2e6b7df791ab40f340dfd2cb41acd62bb057af82 /Users/azabost/.gradle/caches/modules-2/files-2.1/com.linkedin.dexmaker/dexmaker/2.21.0/2e6b7df791ab40f340dfd2cb41acd62bb057af82/dexmaker-2.21.0-sources.jar
Теперь вам нужно всего несколько дополнительных шагов, чтобы сохранить эти драгоценные файлы в вашем VCS столько, сколько вам нужно, и поделиться ими со своими товарищами по команде.
Настройка локального репозитория Maven
Вы можете использовать любой каталог, который хотите, в качестве репозитория Maven, используя фрагмент Gradle, подобный этому:
repositories { maven { url = uri("${rootProject.projectDir}/libs") } }
(Возможно, вы захотите поместить его внутрь все проекты { … } блок.)
В результате в каталоге libs
в корневом каталоге проекта будет произведен поиск зависимостей, как и во всех других репозиториях Maven. Конечно, вы можете назвать этот каталог по своему усмотрению.
Выбранный каталог должен быть подготовлен в соответствии с макетом репозитория Maven. Честно говоря, я не уверен, какая документация по этой теме является официальной, но я нашел эту и я проверил локальный каталог ~/.m2/repository
, чтобы выяснить это.
Для Dexmaker я создал следующий каталог:
libs/com/linkedin/dexmaker/dexmaker/2.21.0
Как вы можете видеть, я сопоставил свою структуру кэша Gradle с макетом репозитория Maven следующим образом:
~/.gradle/кэши/модули-2/файлы-2.1 | библиотеки |
com.linkedin.dexmaker | com/linkedin/dexmaker |
дексмейкер | дексмейкер |
2.21.0 | 2.21.0 |
Затем я скопировал все файлы из кэша Gradle в libs
, используя следующую команду:
find ~/.gradle/caches/modules-2/files-2.1/com.linkedin.dexmaker/dexmaker/2.21.0 -type f -exec cp -v {} libs/com/linkedin/dexmaker/dexmaker/2.21.0 \;
который напечатал этот вывод:
/Users/azabost/.gradle/caches/modules-2/files-2.1/com.linkedin.dexmaker/dexmaker/2.21.0/bdfd84d002e265ab7cf7f54a71a17717f831a57d/dexmaker-2.21.0-javadoc.jar -> libs/com/linkedin/dexmaker/dexmaker/2.21.0/dexmaker-2.21.0-javadoc.jar /Users/azabost/.gradle/caches/modules-2/files-2.1/com.linkedin.dexmaker/dexmaker/2.21.0/423b7b6e4d772e274ba03646284b0cea83faca56/dexmaker-2.21.0.pom -> libs/com/linkedin/dexmaker/dexmaker/2.21.0/dexmaker-2.21.0.pom /Users/azabost/.gradle/caches/modules-2/files-2.1/com.linkedin.dexmaker/dexmaker/2.21.0/680f2dbbb51f2892a4fdbbd9269d628e0b3270b3/dexmaker-2.21.0.jar -> libs/com/linkedin/dexmaker/dexmaker/2.21.0/dexmaker-2.21.0.jar /Users/azabost/.gradle/caches/modules-2/files-2.1/com.linkedin.dexmaker/dexmaker/2.21.0/2e6b7df791ab40f340dfd2cb41acd62bb057af82/dexmaker-2.21.0-sources.jar -> libs/com/linkedin/dexmaker/dexmaker/2.21.0/dexmaker-2.21.0-sources.jar
и вот так Dexmaker 2.21.0 стал частью репозитория Git. Повторив этот процесс для всех других отсутствующих зависимостей, я смог снова успешно создать проект 🎉
Автор: Анджей Забост, Старший разработчик Android @ Яркие Изобретения
Избранное изображение от Лурока от Pixabay
Оригинал: “https://dev.to/brightdevs/migrating-away-from-bintray-jcenter-when-there-is-no-alternative-repository-3l7m”