Maven - роздуми після двох років використання

Протягом останніх двох років я використовував Maven як інструмент для складання проектів. В результаті я залишився досить незадоволений Мавеном, незадоволений настільки, що всерйоз обмірковую переклад нинішнього проекту на Ant.

Перш ніж обговорювати причини мого невдоволення, потрібно сказати пару слів про Мавену. Я не буду його докладно описувати, просто коротко викладу його основні особливості.

Що таке Мавен?

Опис на сайті свідчить, що Мавен - це інструмент для управління програмними проектами (software project management tool). У реальності Мавен - це система для управління збіркою проекту, за цілями багато в чому схожа з інструментами типу Ant і make. Відмінні особливості Мавена такі:

  • Примат угод над конфігурацією (convention over configuration). Якщо проект слід деяким стандартам, то Мавен сам зрозуміє, що і як треба зробити, щоб зібрати проект. В описі проекту вказується тільки те, що відрізняється від стандарту (наприклад, нестандартна структура директорій).
  • Керування залежностями (dependency management). Якщо для збирання (або для виконання) проекту потрібні деякі додаткові бібліотеки, їх достатньо вказати в описі проекту - Мавен сам їх скачає, розбереться з тим, яка потрібна версія, а якщо ці бібліотеки, в свою чергу, залежать від інших бібліотек, то Мавен скачає і їх, і так далі. Для цього Мавен використовує віддалені сховища (репозиторії, repositories), в яких зберігаються бібліотеки та їх описи.
  • Описова мова. На відміну від інших аналогічних інструментів, Мавен використовує саме опис проекту, який називається Об'єктна Модель Проекту (Project Object Model), скорочено POM (я буду надалі називати це «моделлю проекту»). У моделі не вказується, що, як і коли має бути виконано для складання проекту; замість цього там описується те, як проект влаштований, від чого він залежить і так далі. Передбачається, що Мавен самостійно розбереться з тим, як на підставі цієї інформації зібрати проект.
  • Жорстка схема послідовності збірки. Мавен припускає, що збірки всіх проектів вкладаються в кілька типів послідовностей збірки (у термінології Мавена «життєвих циклів», lifecycles). Послідовність складається з певних фаз (обробка ресурсів, компіляція, тести, упаковка, встановлення...), які проект проходить в жорстко заданому порядку. У моделі проекту вказується специфічні деталі того, що саме має бути зроблено в ту чи іншу фазу («при компіляції використовувати ось такі опції компілятора»...).

Реальність

Як видно, теорії Мавен - дуже потужний і цікавий інструмент. На практиці ж картина виглядає дещо по-іншому. Безумовно, у Мавена є певні переваги, але також, на жаль, і багато вельми відчутних недоліків.

Почнемо з достоїнств. Збірка за допомогою Мавена відбувається дуже просто. Досить докорінно проекту написати mvn clean install - і проект збереться! Не треба займатися пошуком і скачуванням потрібних бібліотек, не треба вивчати скрипти. Ця команда буде працювати завжди, незалежно від типу проекту.

Крім того, оскільки Мавен дуже сприяє стандартизації структури директорій (читай: вкрай ускладнює роботу з нестандартною структурою), завжди досить легко зрозуміти де що знаходиться.

Оскільки проект описується саме у вигляді моделі, стають можливими деякі цікаві речі. Наприклад, можна з проекту Мавена автоматично створити проект для, наприклад, Екліпса - при цьому в Екліпсовському проекті вже будуть правильно налаштовані всі директорії, підключені бібліотеки і так далі.

На цьому список достоїнств закінчується. Переходимо до недоліків.

Мавен погано документований. Документація ніби як є, але знайти відповідь на багато питань практично неможливо. Це стосується як самого Мавена, так і його плагінів. Більше того, навіть книга "Maven: the definitive guide ", хоча і прояснює багато речей, але залишає дуже багато питань відкритими.

Мавен балакучий, але разом з тим незрозумілий. У стандартному режимі він виводить під час складання величезну кількість всілякої інформації, як правило абсолютно непотрібної. Налагоджувальний режим - це просто катастрофа! На нашому проекті в цьому режимі Мавен при збірці виводив понад 80 тисяч рядків! При цьому повідомлення про помилки і проблеми часто вкрай туманні і загадкові.

Моделі проекту довгі, погано читаються і важко змінювані. Муторний синтаксис на основі XML; успадкування моделей, в результаті чого часто доводиться переглядати кілька моделей, щоб визначити, яка ж конфігурація в кінці кінців буде використана при збірці; розмазування конфігурації по різних частинах моделі - ось далеко не повний перелік факторів, які призводять до такої ситуації.

Процес складання залежить від зовнішніх систем. Саме - від репозиторіїв. У мене був випадок, коли в одного нового співробітника виникли незрозумілі проблеми зі збіркою проекту. Зрештою з'ясувалося, що в одного з репозиторіїв змінився URL. Ті, у кого Мавен вже встиг завантажити все що потрібно, нічого не помічали; а ось нові співробітники не могли зібрати проект.

Мавен у процесі збирання скачує величезну кількість всіляких файлів. Справа в тому, що одним з елементів системи управління залежностями Мавена є локальний репозиторій. Все, що виявляється потрібним для складання, Мавен скачує і встановлює в цей самий локальний репозиторій. З одного боку, це добре - якщо якась бібліотека потрібна в декількох проектах, вона буде завантажена тільки один раз, а потім Мавен буде брати її з цього самого місцевого репозитарію. З іншого боку, кількість завантаженого вражає уяву. Наприклад, на моєму робочому комп'ютері, на якому я збирав близько п'яти різних (але однотипних) проектів, репозиторій займає більше гігабайта, і містить чотири з половиною тисячі файлів і директорій!

Мавен погано підходить для автоматизації «близько-складальних» завдань. Мені часто в різних проектах зустрічалися деякі дії, які часто не мають відношення до основного складання, які вимагали автоматизації: скопіювати файли з однієї частини проекту в іншу, обробити код аналізаторами, почистити деякі директорії тощо. Коли я користувався Антом, я створював додаткові цілі в проекті - і все було прекрасно (ну так, проект при цьому ускладнювався, але все було документовано). Мавен просто не дає такої можливості.

Дуже жорсткий підхід Мавена щодо послідовності складання, створює великі труднощі в тих випадках, коли потрібно хоча б на крок від цієї послідовності відійти. Наприклад, мені в якийсь момент знадобилося двічі скомпілювати один і той же модуль, але з різними налаштуваннями, і потім помістити два результати в різні місця під різними іменами. Це виявилося зробити дуже і дуже нетривіально.

Мавен важкий для розуміння і освоєння. Причини - все вищевикладене.

Висновки

Особливості Мавена здебільшого приносять більше проблем, ніж користі. Можливо, Мавен може бути хороший для проектів у стабільній фазі, коли змін у структурі проекту вже майже не відбувається. В активній фазі проекту, коли процес складання ще не сформувався повністю - додаються нові модулі, йде переміщення частин - Мавен перетворюється на нескінченне джерело головного болю.

Я сам хочу відмовитися від використання Мавена, і перейти на поєднання Ant + Ivy. Ant прекрасно впорається зі збіркою проекту, а Ivy додасть до нього можливість управління залежностями, ту саму можливість Мавена, якої дуже не вистачало в інших інструментах.