Comments 40
Дайте попробую угадать — у вас нет своего репозитория в вашей сети?
Ну может и утрирую, но я такого никогда не наблюдал, имея всегда nexus рядом.
Могу в принципе себе представить проект, собирающийся 25 минут — например весь karaf или camel, может быть. Только смысла собирать его весь не вижу никакого. И делать проект такого размера, не разбитый на модули — тоже.
takari видели? Пробовали?
Насчёт смысла собирать и пересобирать такой большой проект — если вы ещё раз пробежите текст статьи, там как раз и упоминается возможность не собирать постоянно все модули. Надеюсь, кому-то эта возможность пригодится помимо меня, поэтому я и написал об этом.
Про takari — спасибо за наводку!
+ Отрефакторить код и избавиться от лишнего мусора, которого, я уверен, в проекте хватает.
+ Сборку можно вынести на отдельную мощную машину и собирать там.
Рефакторинг кода — это, конечно, хорошая тема для этого проекта, но такая статья будет совершенно не интересна для аудитории Хабра.
При этом описанная ситуация не является уникальной, поэтому мой опыт может пригодиться другим.
Я могу ошибаться, но насколько я понимал год назад (это то время, в течение которого я не пишу на Java), то одна и та же dependency может тянуться множество раз разными библиотеками. Например, какой-нибудь log4j может много раз тянуться разными либами. Мы это проследили, используя dependency:tree и что-то вроде этого. Затем мы довольно кропотливо и муторно добавляли секции exclude для многих зависимостей. В итоге сборка стала значительно легче, но pom.xml стал значительно запутаннее. Я не считаю это хорошим решением, так что в будущем, если бы мне вдруг еще раз пришлось поработать на большом проекте, я бы посмотрел в сторону gradle. Скажу сразу, я последним не пользовался и не хочу сказать, будто он лучше в этом аспекте.
Если используемые библиотеки — release, то выкачал maven все либы один раз в .m2 (при первом билде проекта) и всё, дальше локально подтягивает. А если хочется ускорить shapshot-ы, то можно updatePolicy в daily выставить.
Если же проблема в jar hell, когда в зависимостях куча разных версий одной библиотеки, а самостоятельно подбирать неконфликтные версии библиотек не хочется, то можно поглядеть в сторону Spring Boot.
А с чего вы взяли, что gradle вдруг будет собирать быстрее?
Ну вы как-то неопределенно сформулировали, прямо скажем.
Говорят, мавен тяжело справляется с реально большими проектами.
Это, скажем прямо, не доказано. Я знаю как достаточно большие проекты, собирающиеся мавеном, так и достаточно большие, собирающиеся gradle. И я бы сказал, что скорость сборки в основном определяется правильной архитектурой разбиения на модули. Чтобы тривиально не собирать то, что не требуется.
В качестве примера — я видел десятки проектов, где используется wsdl2java (Axis, или CXF). И к сожалению во многих из них plugin генерации java классов по wsdl вызывается при каждой сборке. И является частью проекта, который содержит как генерируемый код, так и самописный. При том, что wsdl является внешним интерфейсом, и меняется скажем раз в год. Это лечится только применением головы и разбиением на более мелкие части. И кстати, практику один pom-> один артефакт придумали совсем не дураки.
github.com/vporoxnenko/mbsa
Рискуя спровоцировать холивар, всё же спрошу. Как Вы считатете, зачем упоминаемые в статье "многие" могли бы собирать локально проект как mvn clean install
? Из Вашего опыта, чем они это мотивируют?
extensions.xml
maven.config
timing.properties
jvm.config
extensions.xml — служит для подключения различных расширений, например takari. В моём случае это:
io.takari.maven
takari-smart-builder
0.4.1
io.takari.aether
takari-local-repository
0.11.2
maven.config — параметры мавена для данного проекта:
-T8
--builder
smart
timing.properties — пустой файл, takari использует его для построения оптимального прожода по модулям проекта.
jvm.config — параметры jvm специфичные для данного проекта:
-Xmx4g
-Djava.awt.headless=true
С оптимизациями результат лучше в 5 раз, чем без них, без — порядка двух минут.
Полный же билд идет на CI серверах и задействовать инкрементальную сборку там сложно, поскольку разработка ведется в нескольких бранчах одновременно, и билд-серверам приходится переключаться между ними по мере коммитов.
Вот что давало кратный прирост на интеграционных тестах — так это параллельный их запуск (maven-failsafe-plugin), но пришлось повозиться — настроить конфигурации таким обрзом чтобы не было пересечений ресурсов (разные БД, разные exchnage в RabbitMQ, разные listen ports у компонентов, и т.д.). По идее уже должны существовать альернативные пути, например основанные на контейнеризации (думаю под Gradle точно есть), будет здорово если кто-нибудь просвятит.
И еще awaitility очень помогает избавляться от разного рода sleep'ов в тестах.
ЭххЪ, а мне на одном из проектов приходится отключать инкрементальную компиляцию (configuration/useIncrementalCompilation
в настройках maven-compiler-plugin
) иначе javac
падает также как в JDK-8037484.
~/.m2/settings.xml
<profiles>
...
<profile>
<!-- http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8067747 -->
<id>NoIncrementalCompilation</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<maven.compiler.useIncrementalCompilation>false</maven.compiler.useIncrementalCompilation>
</properties>
</profile>
</profiles>
Мне было проще в build/pluginManagement
добавить настройки, проблема только в рамках тех проектов, которые используют кодогенерацию (например, lombok, immutables).
Кроме того, подход с maven settings, что они автоматически не окажутся на машинах других разработчиков и ci/cd сервере.
Как ускорить сборку с Maven