Я люблю использовать Gradle в настоящее время. Я люблю IntelliJ еще больше. Тем не менее, интеграция этих двух оказывается настоящей болью в заднице!
Для простых проектов Java все отлично работает. Хотя я должен признать, что держусь подальше от плагина JetGradle, который в лучшем случае можно использовать. Но большую часть времени я все еще использую плагин Gradle IDEA. Это просто работает лучше, и я привык всегда открывать консоль: мне нужно столько же печатать, gradle idea
сколько синхронизировать проект Gradle в IDEA.
Но…
Интеграция WAR просто ужасна, нет, даже ужасна. И плагин Gradle IDEA, и JetGradle не имеют функциональности для добавления веб-фасета в мой модуль. Парни из Gradle на самом деле не склонны добавлять функциональность в свой плагин, и парни из Jetbrains, кажется, блаженно не знают, что проблема была подана более года назад (я сам создал другую, чтобы разбудить их).
Отсутствие автоматического способа синхронизации моего файла сборки Gradle с моей IDE для веб-проектов вынуждает меня использовать Maven для этих проектов или использовать Eclipse в качестве моей IDEA (работает плагин eclipse-wtp). Я не доволен ни одним из этих вариантов.
Предлагаемые решения тоже не очень хороши. Вы можете вручную добавить веб-фасет в свой проект IDEA. Это подвержено ошибкам и не то, что я с нетерпением жду, чтобы делать каждый раз, когда я меняю зависимость. Другое решение еще хуже и включает манипулирование файлами проекта IntelliJ XML из скрипта сборки Gradle. Сколько времени может занять первое решение, это просто чокнутый.
Я сильно опечален. Gradle стал моим главным выбором для создания программного обеспечения. Но если они не могут обеспечить достойную интеграцию с веб-проектами, я вынужден использовать Maven для любых проектов, требующих войны. Gradle, не заставляй меня сожалеть о переходе к вам.
Обновление : Слава Богу, Gradle использует Groovy и имеет отличные возможности редактирования XML. Поэтому я выбрал решение, которое казалось безумным: манипулирование файлами iml и ipr. Потребовалось немного поработать, но следующий фрагмент добавит веб-аспект в ваш проект и создаст в IntelliJ развертываемый артефакт (взорванный WAR). Это не красиво, но работает (по крайней мере, для меня есть несколько вариантов использования, которые не будут работать). Я просто хотел, чтобы ребята из Gradle сделали это в первую очередь, но, возможно, мой код попадет в Gradle. Можно только надеяться.
Во-первых, в вашей buildSrc\src\main\groovy
папке есть класс, который обладает всеми функциями для процесса обогащения (как я его называю).
import org.gradle.api.Project; public class IdeaEnricher { def static updateWebArtifacts(Project gradleProject, Node project) { def artifactManager = project.component.find { it.@name == 'ArtifactManager' } as Node if (artifactManager) { Node artifact = artifactManager.artifact.find { it.@type == 'exploded-war' } if (artifact) { artifactManager.remove(artifact) } } else { artifactManager = project.appendNode('component', [name: 'ArtifactManager']); } def builder = new NodeBuilder(); def artifact = builder.artifact(type: 'exploded-war', name: "${gradleProject.name}/Exploded war") { 'output-path'("\$PROJECT_DIR\$/build/libs/${gradleProject.name}_exploded.war") root(id: 'root') { element(id: 'javaee-facet-resources', facet: "${gradleProject.name}/web/Web"); element(id: 'directory', name: 'WEB-INF') { element(id: 'directory', name: 'classes') { element(id: 'module-output', name: "${gradleProject.name}") } element(id: 'directory', name: 'lib') { gradleProject.configurations.runtime.each { element(id: 'file-copy', path: it) } } } } } artifactManager.append artifact } def static updateWebFacet(Project gradleProject, Node module) { def facetManager = module.component.find { it.@name == 'FacetManager' } as Node if (facetManager) { Node webFacet = facetManager.facet.find { it.@type == 'web' } if (webFacet) { facetManager.remove(webFacet) } } else { facetManager = module.appendNode('component', [name: 'FacetManager']); } def builder = new NodeBuilder(); def webFacet = builder.facet(type: "web", name: 'Web') { configuration { descriptors { deploymentDescriptor(name: 'web.xml', url: 'file://$MODULE_DIR$/src/main/webapp/WEB-INF/web.xml') } webroots { root(url: 'file://$MODULE_DIR$/src/main/webapp', relative: '/') } sourceRoots { root(url: 'file://$MODULE_DIR$/src/main/java') root(url: 'file://$MODULE_DIR$/src/main/resources') } } } facetManager.append webFacet } def static updateBuildOutputFolderForGradle(Project gradleProject, Node project) { def projectRootManager = project.component.find { it.@name == 'ProjectRootManager' } as Node Node output = projectRootManager.output.find{it.@url == 'file://$PROJECT_DIR$/out'} if(output) { output.@url = 'file://$PROJECT_DIR$/build/ide' } } }
Включение его в ваш скрипт сборки gradle довольно тривиально:
idea { module { iml { withXml { IdeaEnricher.updateWebFacet(this.project, it.asNode()) } } } project { ipr { withXml { IdeaEnricher.updateWebArtifacts(this.project, it.asNode()) IdeaEnricher.updateBuildOutputFolderForGradle(this.project, it.asNode()) } } } }
Я склонен немного поработать над файлом ipr, чтобы выходная папка соответствовала папке сборки gradle. Теперь IntelliJ создает свою собственную out
папку. Это небольшое раздражение, но так как я все равно меняю конфигурацию, я мог бы пройти весь путь.
Это еще раз убедило меня, что Gradle — правильный выбор. Конечно, он немного грубоват, и еще не все функции, которые есть у вас в Maven, есть. Однажды я сказал, что Грэдл предоставляет вам инструменты, чтобы оторвать всю вашу ногу, но на этот раз я был рад, что в моем распоряжении все оружие Groovy. Тот факт, что вы можете добавить дополнительную логику в свою сборку, является чем-то чрезвычайно мощным, и я вижу, что буду делать в будущем гораздо больше.