Як прискорити складання з Maven

Maven
Що робити, якщо складання (build) з Maven проходить надто повільно? Адже коли збірка триває занадто довго, будь-який, навіть самий терплячий розробник, може занудьгувати і відволіктися.

Для швидкого пошуку в Google або для закладок, відразу пропоную підсумкове рішення:
mvn package -am -o -Dmaven.test.skip -T 1C

— для складання проекту без тестів.

Ця історія почалася з того, що я викачав досить великий проект на Java з нашого корпоративного сховища. Думаю, що багато хто, як і я, відразу зібрали б його командою:
mvn clean package

, ну а багато командою:
mvn install clean

Мій проект зібрався за 25 хвилин, і кожен раз збирався так само довго, як і в перший раз.

package замість install
Згідно життєвого циклу складання проекту після фази package, на якій ми отримуємо повноцінний jar-файл, є фаза verify, а потім install. Часто необхідно отримати саме jar-файл, який немає необхідності поміщати в локальний репозиторій, тому в даній ситуації я зупинився на package і зекономив трохи часу.

Паралельна збірка
При звичайному запуску Maven не використовує всі можливості сучасних процесорів з розпаралелювання обчислень на різних ядрах, збираючи модулі один за іншим. На щастя, можна скористатися параметром -T, вказавши Maven, що необхідно побудувати граф залежностей і збирати модулі паралельно.
Параметром, можна скористатися різними способами:
mvn -T 4 package

або
mvn -T 1C package

У першому випадку ви вказуєте кількість потоків для використання Maven, а в другому — що необхідно використовувати один потік на кожне ядро ПРОЦЕСОРА.
Другий спосіб завдання параметра, прив'язаний до кількості ядер, я і збираюся використовувати у своїй підсумковій команді.
Поекспериментувавши з кількістю потоків на ядро, спробувавши наступні варіанти:
mvn -T 1C package
mvn -T 1.5 C package
mvn -T 2C package

— я не отримав якогось помітного приросту у випадку з більш ніж 1 потоком на ядро на собираемом проекті на процесорі Core i7.
Зауважу ще, що паралельна збірка — це експериментальна функція Maven 3. При складанні можуть виникнути проблеми при використанні плагінів, які не є @threadSafe. Зокрема, це плагіни:
  • Surefire з параметром forkMode=never, surefire [2.6,) попереджає (assert) про це.
  • maven-modello-plugin, виправлено з версії 1.4,
  • Всі клієнти maven-archiver (EAR, EJB, JAR, WAR etc), виправлено в останніх версіях
і бібліотеки:
  • plexus-utils 2.0.5
  • maven-archiver 2.4.1
  • plexus-archiver 1.0
  • plexus-io 1.0


Инкрементальная збірка
Як ми обговорювали вище, проект найчастіше збирається командою:
mvn clean package

Команда clean використовується для очищення проекту, але чи це потрібно кожен раз при складанні? Ні, звичайно, ми хочемо інкрементального оновлення проекту, і Maven на це здатний за допомогою команди:
mvn package -am

Maven збирає модуль і оновлює ті модулі, від яких залежить цей модуль, у разі якщо в них щось змінилося.
Ця опція в рази прискорює складання проектів з багатьох модулів, в яких, як правило, вносяться точкові зміни до 1-2 модуля.

Оффлайнова збірка
Часто буває так, що артефакти на зовнішніх репозиторіях оновлюються не так вже й часто, особливо, коли це артефакти певної версії, або ці артефакти повинні підтримуватися вашими зусиллями (- Ласкаво просимо в новий проект!). Досить логічним у такій ситуації повідомити Maven, що не потрібно кожен раз заново завантажувати їх з репозиторіїв:
mvn package -o

або
mvn package --offline


Ми для лаконічності зупинимося на першому варіанті.

Пропуск тестів
Мабуть, саме спірне пропозицію з оптимізації швидкості збірки я залишив наостанок. Тим, хто повністю поділяє цінності TDD, я просто пропоную прогорнути цей абзац і прибрати з нашої підсумкової команди параметр -Dmaven.test.skip.
Не буду заперечувати, тести, безумовно, потрібні, і програміст повинен розуміти ту частину відповідальності, яку він бере на себе, відключаючи їх. Але якщо ви раптом зіткнулися з новим гігантським проектом, в якому хтось колись написав тести, і вони не працюють, то вам і так доведеться для початку відключити.
Що стосується опції запуску Maven, я хочу відзначити тільки те, що, як правило, для того, щоб пропустити тести користуються командою:
mvn package -DskipTests

Але при цьому також можна пропустити компіляцію тестів, якщо виконати команду в наступному вигляді:
mvn package -Dmaven.test.skip


Підведемо підсумки
Отже, ще раз команда, яка вийшла у нас для прискорення складання з Maven:
mvn package -am -o -Dmaven.test.skip -T 1C


Результат, показаний на собираемом мною проекті, радує: збірка замість 25 хвилин стала проходити за 30 секунд.
Автори деяких інших статей по оптимізації швидкості збірки з Maven також рекомендують використовувати параметри оптимізації запуску компілятора:
MAVEN_OPTS= -XX:+TieredCompilation -XX:TieredStopAtLevel=1
package mvn

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

Сподіваюся, що в коментарях ви також поділіться статистикою щодо прискорення складання ваших проектів!
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.