fat aar от Google. Дождались?
TL;DR
Google начали делать свой инструмент для создания fat aar, но сильно его не доработали. В Open Source остались сомнительные решения, написанные на Groovy, поэтому сделал свой с блэкджеком, в смысле с shadow-jar.
Интро
Думаю многие слышали про такой формат дистрибуции нескольких библиотек или Gradle модулей, запакованных в один артефакт. В любом случае напомню, что по умолчанию каждый Gradle модуль с подключенным плагином com.android.library
можно собрать как один aar, но могут быть случаи, когда все же есть необходимость объединить несколько библиотека в одном aar артефакте. Такая идея не нова. Например, в Java мире это называется uber jar или fat jar и готовится он с помощью довольно известных плагинов maven-shade-plugin и shadow-jar для Gradle.
Необходимость
Так ли нам нужен fat aar? В основном, нет. Если правильно организовать многомодульность в проекте и заложить то, что эти модули будут опубликованы как библиотеки, и все будет прекрасно.
Необходимость может появиться в ряде случаев. Например, если у вас есть локальные jar и aar файлы, которые нужно опубликовать вместе с библиотекой, но исходники уже утеряны. Другой пример, если не хочется раскрывать идеальную многомодульную архитектуру для пользователей библиотеки. В конце концов, может быть случай, что нужно поделиться куском приложения с другим проектом, а сроки горят.
Еще причин почему это может быть нужно, можете найти в issue по этой теме, который висит аж с 2017 года. В комментарии там пришли люди из разных компаний. Например, вот свежий комментарий человека из Netflix:
А Google что, не делает? На самом деле начинали делать в 2022 и назвали они свое творение Fused Library.
Fused Library
Да, плагин назван так, что его вряд ли кто-то нашёл бы... Но все же он нашёлся. К тому же, появлялись коммиты с обновлениями буквально в дни, когда я его смотрел.
Это свидетельствует о том, что ребята намерены продолжать разработку инструмента, хоть и был перерыв в два года.
Я потратил пару вечеров, пытаясь его завести, но лишь расстроился тому, насколько сырой все же инструмент.
1. Сразу бросается в глаза то, что он не умеет формировать aar файл...
Он все объединяет в jar. Понятно, что ошибка в том, не выставлено расширение файла при конфигурации задачи, но уже тут можно делать выводы, что решение нерабочее. И все же продолжил исследование инструмента на случай, если надумаю починить и доработать.
2. По картинке из пункта 1 можно заметить, что нет никаких классов в собранном jar. Все дело в том, что плагин даже это не умел делать, так как там забыли упаковать классы в jar. Благо это исправили в июле этого года.
3. Нет поддержки различных build variants. Поддерживает только один build type - debug. С учетом того, что fat aar чаще нужен в релизной сборке, такое нам не подойдет.
Тут завершу список проблем, потому что их просто нельзя починить. Да, реализация интересная и отличается от всего, что было до этого, но его нельзя доработать без форка всего AGP, так как используется internal api. К тому же, по последним изменениям непонятно, какие планы у разработчиков. Ясно одно, что проект все еще экспериментальный, поэтому велика вероятность того, что решения, которые будут приниматься, не совпадут с моими предложениями. (Как-то у меня была попытка законтрибьютить в AGP - там так же все же предпочли сделать по своему.)
Учитывая все это, прекратил ковырять этот плагин. Сильно сырой все же.
Что в Open Source?
Взяв весь свой пыл куда-нибудь закотрибьютить пошёл искать решения в GitHub. Нашёл пару решений, но самое популярное, написанное с использованием Groovy, уже заброшено. Этот заброшенный плагин был форком других похожих плагинов. Теперь уже его форкнули для поддержки AGP 8 и нетранзитивных R-классов.
В актуальном форке хоть и решили проблемы с AGP 8, но остались другие.
1. Есть проблема со слиянием ресурсов с одинаковыми id. Такое может быть, потому что плагин соединяет ресурсы только после того, как сформирует конечные артефакты.
2. Нет возможности выполнять формировать shaded jar, то есть перемещать классы в разные пакеты. Такое, например, делали в компиляторе Kotlin, чтобы зависимость для Idea не конфликтовала с зависимостью для Gradle. Ну и по проекту можно найти разные применения shadow-jar.
Пошёл искать дальше и обнаружил ещё один плагин. Он полностью написан на Kotlin, имеет еще больше проблем, некоторые вещи недоделаны, а поддерживается только AGP 4. Напомню, что на дворе AGP 8 и не за горами AGP 9.
И все же я решил оживить именно этот проект. Потому что, по моему мнению, автор старался делать иначе, чем в других проектах, и так, чтобы это было надежно. Это можно заметить по исследованию задач для формирования aar, результат которых он оставил в виде комментариев в коде.
Grease
- Переход с AGP 4 на AGP 8.
- Доработал слияние ресурсов, вдохновившись Fused Library. Решение получилось надежнее, чем у fat-aar-android.
- Подключил shadow-jar и научил его трансформировать метаданные Kotlin и AndroidManifest.xml. Кроме того, работу shadow-jar можно конфигурировать.
Может показаться, что это немного, но по сути плагин был полностью переписан в рамках первого пункта.
Было большим удивлением то, что после того, как освежил инструмент, у него сразу появились клиенты, которые начали накидывать issues. Количество звезд при этом выросло в два раза. Поэтому, пока Google доделывает Fused Library, есть альтернатива в виде Grease.
Опубликовано в Полуночные Зарисовки