Why gradle?

Original author: Steve Ebersole
  • Transfer
If you still do not know what Gradle is , then you can read about it in the previous two reviews:
  1. Gradle: Better Way To Build
  2. Gradle: Tasks Are Code

Not so long ago, from Maven to Gradle, the Hibernate Core assembly was transferred . What the information community has reacted ambiguously . I want to bring to your attention a translation of an article on the migration of a Hibernate assembly. The article reveals the reasons for making this decision, describes the benefits of Gradle and problems with Maven2. Further narration is on behalf of Steve Ebersole.

Why gradle?


Many asked me to write down the reasons why I want to transfer the Hibernate assembly from Maven to Gradle, and here I will list them. If this is your first time encountering Gradle, it makes sense to look at the overview . First of all, I want to emphasize that the purpose of this article is not "hit the crash - Maven" and not a direct comparison of Gradle with Maven. This is just a way to tell the world about the problems and frustrations I encountered in 2.5+ years using Maven to build Hiberbnate. In many cases, the reason is that the conventions used in Maven do not match the way I imagine the Hibernate assembly. Some list items, compiled by Paul, are relevant only for Hibernate (this list is also worth a look). This is also a way to explain why I preferred Gradle to other new build tools (Buildr, SBT, etc.). By the way, there is also a wiki comparing Gradle and Maven, but it is pretty outdated in many parts. Especially with Gradle.

Here are the problems (rather in chronological order than “in importance”) that I encountered in Maven:
  1. Maven does not support multi-module assemblies. It is claimed to support, but this is not entirely accurate. To be precise, it supports on the side of a group of independent projects. What is the difference? For example, take Hibernate. We have a set of modules that we assemble. Modules exist solely for the purpose of separating dependencies according to the functions used. Not using ehcache for caching? No problem, do not use the hibernate-ehcache module and ehcache will not be in your dependencies. We are never going to separately supply these modules. Then why do we need to set the project version again and again (in all modules)? Here is an example of how maven complicates the simple. And the consequences are felt when, for example, I want to make a release. I have to manually verify that the versions match in a lot of different places (and don’t even start about the release plugin)
  2. Well, since I started about the release plugin. It is generally useless. I could make it work more or less decently on small projects, but with Hibernate it almost always crashed. Worse, you have to wait 30-40-60 minutes to find out that it will not work, then correct what he did not like (if you managed to find out), and start it again. In the end, we just gave up . (By the way, a friend just noticed that Jason van Zyl, cast the release plugin into the seventh circle of hell, and that it will be replaced with “something new”)
  3. Hibernate-core is the main artifact. Hibernate-Annotations depends on it. Maven knows about this. Well, then why can't I just go into the hibernate-annotations directory and run the 'maven compile' so that hibernate-core will automatically build too? (hint: see point 1) In any case: `cd hibernate-core; mvn install; cd ../hibernate-annotations; mvn compile`- does not climb into any gates. The build installer should understand this himself after I have overcome so many obstacles, explaining to him the nature of these dependencies.
  4. One artifact per project. I know this is a good rule. But Good Rules are rarely Absolute Truths. And for example, this limitation of Maven forced us to take tests for hibernate-core outside of hibernate-core. Because we needed hibernate-testing, which depends on hibernate-core and defines the overall runtime of the tests and is used in most other modules (we also wanted to make it available to users). And now we constantly have commits that break tests, because developers (including myself) forget to run tests because they lie in some other, completely separate module. Yes, it’s mainly a problem of attention to detail, but shouldn't the build tool help in solving such issues instead of to create them? Well, one source directory and one directory of compiled classes per project. Cm.http // in.relation.to / Bloggers / SimultaneouslySupportingJDBC3AndJDBC4WithMaven
  5. I personally hate the concept of combining "inherited pom data" and "module aggregation" in one file. This is a terrible thought. Many maven developers agree with me and helped develop a scheme whereby Hibernate posts “inherited pom data” in ./parent/pom.xml and “module aggregation” in ./pom.xml. Great, maven supports it ... well, almost fine: it almost supports. The problem is that many plugins do not support this, and small, catchy problems start. Why, then, to carry it at all? As I said, I do not think the union is right. But why not step over “correctly” and do it differently, because Does Maven work differently? The problem is in the settings after the initial checkout. You cannot build a module until there is a parent. But if the parent is an aggregator,
  6. At the very beginning, 2.5 years ago, I had to run into our DocBook assembly. Christian with his work on building DocBook using Ant in Hibernate set the bar for many open-source Java projects. I had thoughts on how to improve this, using the concept of dependency management to download the necessary components as needed. The problem is that in order to do something similar in Maven you have towrite a plugin. You can’t “just throw a script, and then, if it turns out to be useful, I will pack it for others” (I understand that now it is to some extent possible with the help of GMaven, etc., but then it was not so). So I had to write a jDocBook plugin and a few more. And there were problems with all of them. This is the only time I will directly compare Gradle and Maven, because Gradle “hit the bull's eye”. Writing plugins in Gradle (I have already written 2 quite large ones) is very nice. In a sense, this is not easy due to the lack of instructions on how to do this correctly, but the APIs and the features that are provided are simply amazing (and not that Maven had documentation on the “right plugins”).
  7. Many users would like build scripts to be configured to interact with the JBoss maven repository. It is logical: the assembly should work out of the box. But in Maven this cannot be done because the pom file used for assembly will also be used for installation in the repository. And most repositories (including JBoss and Maven Central) verify that the pom files do not contain repository settings. So, instead of setting up scripts, we have to support wiki and docbook and send users to the documentation.
  8. Running Hibernate tests over several databases is almost impossible through the IDE, in IntelliJ, at least, using integration. The problem is with profiles and how integration interacts with them (in terms of filtering resources)


So, it's time to start looking for a better way to build Hibernate. Yes, Maven3 loomed on the horizon. Yes, he adds some “script support”, but it’s more like a little thing. As far as I know, it just allows you to customize everything the same way. So I started learning Gradle, among other “DSL, build-by-convention” tools. (By the way, this “little thing” is called Polyglot Maven and, according to a friend, Jason van Zyl stated that it will be removed and replaced with “something else”).

  1. The first and main advantage was the ability to create scripts for those parts of the block that are too difficult to describe in terms of “build by convention”. I liked this mixture: the best from both worlds is at your disposal.
  2. Faced with difficulties accessing information from other modules during assembly [using Maven2 - approx. trans.], I realized that the ability to write enumeration of assembly modules using closures in many cases is simply a “gift of God”. As well as a way to configure standard settings for all subprojects in the main gradle script, this is a masterpiece that far surpasses the concept of inheritance in Maven.
  3. General flexibility in the build settings and directories as I need, without having to follow the limitations of the build system - it's great
  4. The whole concept of the build process in Gradle is much cleaner, imho. In Gradle, you can not only define dependencies between modules, but also incredibly flexibly describe dependencies on tasks, modules, directories, etc. For example, in Gradle, you can already say that one module depends on the compiled classes, and not on the result (jar) of the assembly of another. Think about it. Very, very flexible. And useful!
  5. Each project or module can have several "Source set". “Source set” sets a set of directories with source codes, a set of target directories, resource directories, etc. ... With this, for example, you can make the parallel support and testing option JDBC3 / JDBC4 the way I wanted (see in.relation .to / Bloggers / SimultaneouslySupportingJDBC3AndJDBC4WithMaven )
  6. I don’t know what to attribute it to, but it’s so nice to think, “How am I going to do this?” instead of “What options will the assembly system leave for me?”
  7. Incremental assembly is great. Like this? She understands when something has changed, and when not, and when parts of the assembly are really needed. This is built into plugins. The task determines the input and output, and Gradle uses this information to determine whether the task needs to be run, because its input has changed, and whether the task has updated its output and therefore it is necessary to run tasks depending on it. As a result, subsequent builds become very fast.
  8. Gradle’s ability to publish artifacts to maven repositories and generate accurate POMs was not only unique, but was also an important argument for deciding on the transition. I may have complaints about building Hibernate using Maven, but the ability to create and use artifacts in a unified way is extremely necessary. In general, Gradle is able to generate POM from the information that it has. And if not, you can simply describe the additional parameters in the closure to configure the POM. This is about flexibility.
  9. IDE project generation. This was another important argument. Most Hibernate developers use Eclipse or IntelliJ. Personally, I spend most of my time in the IDE: I write code, run tests, and draw up documentation. I was not going to go by complicating the work in the IDE. For quite some time now, Gradle can create projects under Eclipse. Recently, it became possible to generate projects under IntelliJ. For her, they say, gradle integration is being developed, similar to maven

Also popular now: