NHacker Next
  • new
  • past
  • show
  • ask
  • show
  • jobs
  • submit
The Problem with Gradle (bruceeckel.com)
zmmmmm 1187 days ago [-]
What I find fascinating about Gradle is that its utterly impossible to say it lacks documentation - go to https://docs.gradle.org/current/userguide/userguide.html and see the amazing beautiful docs.

But actually learning from those docs is amazingly hard. It's like "documentation theater". If you start as a naive user coming in, it keeps teasing you that its going to teach you something but you just get abstract concept after abstract concept and you STILL don't know the mechanics of how a build works. You have to kind of reverse engineer the info that Bruce describes out of the documentation. Even when you manage to hit actual code examples with detailed explanations - they are described in a way that fails to give you the generalisable understanding of the internals that you need to actually create new things that you haven't seen before.

As a developer it generates a distinctly hostile feeling of helplessness and powerlessness.

Noumenon72 1187 days ago [-]
I love how you and others have articulated exactly how I felt. I'm not alone! There are not many tools or languages that have left me with such a memory of unlearnability. I powered through, I made things happen, but I feel less powerful in Gradle than anything else I spent so much time learning.
mumblemumble 1187 days ago [-]
Gradle's documentation falls into a trap that I find many projects falling into: thinking that, if you have documented all of the thing's parts, you have documented the whole thing.

The only projects I see reliably escaping this trap are ones with commercial backing. I'm guessing the problem is that nobody does tech writing as a hobby, so, if you want to get good tech writing, you need to actually hire a tech writer.

tn1 1187 days ago [-]
> The only projects I see reliably escaping this trap are ones with commercial backing.

Gradle is backed by Gradle, Inc. [1] who provide commercial support and presumably a lot of development as well.

[1] https://gradle.com/

culopatin 1187 days ago [-]
As a beginner this is how I feel about much of the official documentation and why I often search in YouTube/blogs for someone else to provide me the digested version of the docs.

None the abstract concept stuff means anything to me quite yet, and it’s what I find about the most.

It’s as if my Mac user GF asked me about how to get something done in my Windows desktop and I start with the history of Microsoft and how different is their philosophy instead of telling her “Use CTRL instead of CMD and most of your shortcuts will work the same, and file explorer is your Finder”.

piva00 1187 days ago [-]
Very concise description of my own experience when trying to learn Gradle from its docs, frustrating wheel spinning and utter confusing to understand from a high level to a detailed view.
lajun 1187 days ago [-]
This sums it up perfectly. Gradle is the best tool in the world for making me feel like I'm dumb. It is so hard to track where things are defined because the build script has something like 100 invisible imports by default. It makes for a beautiful file but a horrible experience for anyone who's new. I hate it.
Groxx 1187 days ago [-]
Bazel is pretty similar in that respect. It has tons of documentation, and it's mostly decent prose as well... but you can read for days and get no closer to knowing how to build or fix a thing.
oblio 1187 days ago [-]
Random guess: they never user test new docs (especially with newbies). Docs are written by Gradle devs with years of intimate knowledge of the tool and just published somewhere in their dev cycle.
cratermoon 1187 days ago [-]
And with that, they document the things Gradle does, not how to accomplish basic tasks using Gradle.
ashtonkem 1187 days ago [-]
Gradle manages to hit the same note that AWS does; lots of docs, but never the one you need.

The fact that the style and language Gradle is written in has changed doesn’t help one iota.

1186 days ago [-]
cratermoon 1187 days ago [-]
It's like trying to learn how to drive a car by reading the owner's manual.
zestyping 1187 days ago [-]
I found these to be huge stumbling blocks:

- Scoping is mysterious: things that you expect to be in scope AREN'T, and lots of things that you can't see ARE in scope. This makes it impossible for a beginner to look up the source code (or even, often, the documentation) that corresponds to a given thing in a Gradle file: you might realize that "ext" exists, but there's no way to tell what scope it comes from. That defeats most of the usual approaches that programmers have learned for exploring a new system. To use the UX lingo, Gradle is undiscoverable.

- Similarly, your Gradle script is interacting with things you can't see. When you write "sourceSets { ... }" you're actually calling a method on an object. What object? You can't see it, or even a reference to it, in your Gradle file.

- I came to Gradle with the definition in my head that a build tool is a thing that tracks dependencies so that it only has to rebuild things whose inputs have changed. Gradle doesn't do that at all. Many hours of searching for how Gradle detects changes were fruitless, because it doesn't even try, really. Gradle basically always runs everything, which is why it's so goddamn slow. This is because the entire dependency graph is constructed dynamically on every run, and that prevents the system from effectively retaining from run to run which steps have already been done.

p2detar 1187 days ago [-]
> I came to Gradle with the definition in my head that a build tool is a thing that tracks dependencies so that it only has to rebuild things whose inputs have changed. Gradle doesn't do that at all. Many hours of searching for how Gradle detects changes were fruitless, because it doesn't even try, really. Gradle basically always runs everything, which is why it's so goddamn slow.

Gradle has build cache since version 3.5 [0]. You probably mean the configuration phase for which caching was introduced in version 6.6. [1]

Gradle has been consistently improving the last couple of years. I’m quite happy with its speed since the v6.5 upgrade.

0 - https://docs.gradle.org/current/userguide/build_cache.html

1 - https://docs.gradle.org/6.6/release-notes.html

oblio 1187 days ago [-]
Its architecture is so broken that they had to introduce 3 concepts to speed Gradle up:

- daemon

- build cache

- config cache

for a build tool! And it only took them more a full decade to implement them (the config cache is still experimental).

And even all those things only take it from "molasses slow" to "bearable".

pjmlp 1187 days ago [-]
And then they sell the image that Gradle is faster than Maven, omitting what went into making it look like that.
jicea 1187 days ago [-]
> Many hours of searching for how Gradle detects changes were fruitless, because it doesn't even try, really. Gradle basically always runs everything, which is why it's so goddamn slow. This is because the entire dependency graph is constructed dynamically on every run,

Something that is not clear from the Gradle documentation is that every task must have its input and output defined (inputFile, inputDirectory, outputFile, outputDitectory property). It is absolutely essential so Gradle can infer which task has to be rerun when, for instance, a build is run. This is usually done for the ‘basic’ task (like build, test etc..) but you have to specify it when you have custom task. This can really make a difference in speed. Another trick is to use the console option (gradle build —console plain) so you will see each task that have been run and their status (if they have be runned, or if they have been skipped due to dependencies)

iainmerrick 1187 days ago [-]
I’ve tried to improve build times on a large Android project, and failed because basically every dependency gets this wrong and it’s impossible to fix them all. This includes things like Google frameworks that you might expect to be well-written.

It’s not well-documented, as you say, and beyond that the tool doesn’t do anything to enforce or encourage correct behavior, or offer you any way to fix incorrect behavior in code you depend on.

mumblemumble 1187 days ago [-]
I am beginning to think that a lot of these problems stem from Gradle's frameworkyness. You don't call it, it calls you. Whatever it's doing in between when it calls into the bits and pieces of code that you wrote is a mystery. That, in turn, makes it almost impossible to intuit how things in a Gradle script relate to each other. The relationships aren't lexical, and you can't figure out how things work by tracing through the code. Instead, its inner workings feel like spooky action at a distance.

If Gradle were more of a library, and a Gradle build script were just a Groovy or Kotlin script that calls into that library, everything might be easier to understand.

larusso 1187 days ago [-]
As others mentioned gradle has a build cache. It works different to make as it doesn't take the mime timestamp of the input/output but rather creates hashes. In the early versions these caches were project local only. Later the cache was system wide. Now you can setup a gradle cache-server so the whole team can use the same cache. But this all comes of course with some restrictions. Gradle needs full control over the inputs/outputs. If another tool makes a change to an output gradle will mark this as dirty and will rebuild it from scratch. Same when you update java, gradle or plugins since gradle can't be certain that a an update of the mentioned parts would result in a different output. On paper this all makes sense. But if you start to write custom tasks which depend on each other or work on lists of input files this becomes increasingly difficult. Luckily writing tests for custom tasks is easy if one finds the documentation and muse to set this up.
i386 1187 days ago [-]
> Scoping is mysterious

Exactly how I’ve felt about Ruby or Rails for the last 12 years. There’s always something magic in scope you can’t see.

And duck typing all the things means you just have to trace through the code to actually find out what that <thing> parameter really is and what the function is expecting.

wasyl 1187 days ago [-]
> Scoping is mysterious

It definitely is confusing, but while the rules to scoping are pretty extensive, they're also well defined. The trick is to know how Gradle "travels" through objects and looks for the property in class properties, extensions, extras, etc. I wrote about it [1] if you're interested.

> Gradle script is interacting with things you can't see

Not necessarily -- yes, the receiver for top-level calls (Project instance) is implicit, but you can access it via `project` property. You could prefix each top-level call in your Gradle script with `project.`, making all calls explicit.

Btw `sourceSets { }` calls the lambda on a `SourceSetContainer` instance, accessible via `Project#sourceSets` property [2], so you can get an instance of it. I suppose there might some objects that are configurable but not accessible, but nothing comes to my mind right away, actually.

> a build tool is a thing that tracks dependencies so that it only has to rebuild things whose inputs have changed. Gradle doesn't do that at all.

You might've had a bad experience with a misconfigured plugin/build or a bug. Gradle does track dependencies, and while it doesn't do that perfectly always, it avoids a lot of unnecessary work, on many layers (incremental compilation, task avoidance, task caching). As a general rule, when running the same task(s) twice, the second invocation shouldn't execute any taks.

> This is because the entire dependency graph is constructed dynamically on every run It's true that configuration/task graph creation is still happening on every invocation (this will change with Configuration Cache [3]). But it's definitely not accurate that this prevents Gradle from knowing which steps have already been done. Again, I fully believe it didn't work for you, but it doesn't mean Gradle doesn't do that.

I'm not trying to say Gradle doesn't have flaws. In fact, I think your comment proves the points from the article. Unless one invests in learning how Gradle works, it's impossible to spot e.g. why the build isn't doing any task avoidance, or understand scoping. It's rather unfortunate, because after that initial investment Gradle is a pretty great tool to work with.

[1] https://medium.com/tooploox/where-do-gradle-properties-come-... [2] https://docs.gradle.org/current/dsl/org.gradle.api.Project.h... [3] https://docs.gradle.org/current/userguide/configuration_cach...

oblio 1187 days ago [-]
That initial investment is non-trivial, though. It's at least tens of hours of study in my experience. And they keep adding concepts and deprecating old ones.

And keep in mind this is just for the build tool, someone using Gradle probably already has to juggle a million other details, most likely much more important than Gradle (business concerns, main tech stack concerns, etc.).

Gradle is practically consultingware.

p2detar 1187 days ago [-]
Is there really a tool that’s flawless?

Btw, when was the last time you used Gradle? For what type of projects and are you currently using it in prod?

lmm 1187 days ago [-]
> Is there really a tool that’s flawless?

Yes. Maven.

blandflakes 1186 days ago [-]
I prefer maven but it most certainly does not feel flawless to me.
p2detar 1187 days ago [-]
Funny. Maven was the reason I went to Gradle. :)
oblio 1187 days ago [-]
I last used it about 1 year ago, Java web app, in prod.
kstenerud 1188 days ago [-]
> There are Many Ways to do the Same Thing

This is the crux of the problem, and is a problem with many libraries, configuration systems, languages, etc.

The author of said tool wants it to be as widely used as possible, so he optimizes for the 100%, going so far up the flexibility curve that it becomes incredibly difficult to do 80% of the things you want.

What these authors should be doing is optimizing for the 80%, which means an opinionated top layer that offers a single way to do everything that 80% of your users would want to do. Then if you're smart, you'll have a layered architecture (which the 80% layer rests upon) that allows the other 20% to learn about how the sausage is made in order to do their complex tasks.

With this, you have a common tool that is at least 80% easily understandable with minimal time investment.

Failure to do this gives you unfriendly systems like CMake, Gradle, OpenSSL, Postfix, and Java's time libraries.

U/X applies to code as well.

Cwizard 1188 days ago [-]
I agree. When I was a kid I had a camera that had an 'easy mode' in software. If you turned it on, the software would disable most advanced features and the UI would be something incredibly simple. This allowed me a complete novice to get started taking pictures. After some experience I turned the setting off and started to experiment with more advanced features without getting overwhelmed. I always wondered why not more products adopted this type of UX.
tjalfi 1188 days ago [-]
Raymond Chen, a Microsoft blogger, has posted[0] about why Windows doesn't use an expert mode.

[0] https://devblogs.microsoft.com/oldnewthing/20030728-00/?p=43...

Hallucinaut 1187 days ago [-]
They do kinds of have an Expert mode though; all of the original menus and options that they hide behind frustratingly glib, to the point of being useless, "modern" menus, with plenty of whitespace.

A recent Windows update even went so far as to proudly boast about how they were adding back menu items that had disappeared in this drive for stupidification of the menus. Hardly progress.

szatkus 1187 days ago [-]
It's an old post, they have in Windows 10. Kinda. Many sections in Settings have options for advanced settings that would take you to the old Control Panel.
oblio 1187 days ago [-]
That's a bit different though. They're rebuilding the airplane mid flight. The long term goal is to replace the Control Panel entirely, it's just a multi-year and possibly multi-decade effort.

That's why they keep linking to the Control Panel, they're not there yet. I think they'll soon be done with the System page, for example.

merb 1187 days ago [-]
it's getting less and less. well in H20 or however that is called, I had trouble to finding the dialog to join a computer to a domain.
chr 1188 days ago [-]
Also nice how the built-in Iphone calculator app is plain and simple in portrait mode, and rivals a scientific calculator when rotated to landscape mode.
Tomte 1187 days ago [-]
The problem is that this is only discoverable by accident in specific circumstances.

I almost never hold my phone in landscape.

vosper 1187 days ago [-]
Apple did the same thing with undo. Such a commonly used feature, hidden behind shaking your phone? That’s not even an interaction. They’ve slightly improved it with three-finger swipe to the side, which at least is a bit like a gesture, but again completely undiscoverable. Apparently under no circumstances will we just be getting an undo button.

It’s not just Apple, though: there’s a whole page of useful settings for Instagram’s Hyperlapse app. Guess how you open it? You tap the screen four times with four fingers. Why on earth did they build and maintain a settings page and then hide it like that?

layer8 1187 days ago [-]
It should go RPN when holding the phone upside down. ;)
nmfisher 1187 days ago [-]
You just blew my mind.
octopoc 1188 days ago [-]
> What these authors should be doing is optimizing for the 80%, which means an opinionated top layer that offers a single way to do everything that 80% of your users would want to do. Then if you're smart, you'll have a layered architecture (which the 80% layer rests upon) that allows the other 20% to learn about how the sausage is made in order to do their complex tasks.

A good example of this approach is MSBuild + Nuke [1]. You can have as much complexity as you want in your Nuke build script (which is plain C# in a normal, debuggable C# project), but MSBuild has to exist to bootstrap the Nuke build script.

[1] http://www.nuke.build/

sn41 1187 days ago [-]
"Simple things should be simple, complex things should be possible" - Alan Kay.

Instead, in overthought out systems, complex things are simple, and simple things are possible with unnecessary effort.

not_knuth 1188 days ago [-]
I think what you are referring to is called a Turing Tarpit [0].

[0] https://en.wikipedia.org/wiki/Turing_tarpit

vips7L 1187 days ago [-]
What's wrong with java.time.* ? I've never found it to be hard to grasp.
cesarb 1187 days ago [-]
The java.time.* are the new classes (IIRC, based on joda-time), but there are also the old time libraries in java.util.* and java.text.*. I don't know which ones the parent poster was talking about, but it might be the old ones.
vips7L 1187 days ago [-]
Yes I know they're "new", but the Java time API was released 7 years ago with JDK 8. I don't think its fair to be critical of something that was fixed almost a decade ago.
charrondev 1187 days ago [-]
Unfortunately a lot of people don’t have access to Java 8 on the largest customer facing Java platform (android).

The java.time libraries are available on android starting API level 26 https://developer.android.com/reference/java/time/package-su...

That is android 11, released in September of 2020 which is not widely distributed.

Does anyone know why the delay? It looks like Java 8 language features finally became compatible through some compatibility layer in Gradle 4.

Was it because of the lawsuits?

EddieRingle 1187 days ago [-]
This is incorrect. You can use APIs like java.time on any version by using desugaring: https://developer.android.com/studio/write/java8-support#lib...
ohgodplsno 1187 days ago [-]
Basically, yes. Google has been awfully slow at implementing some Java 8+ features. Their current solution is D8 desugaring, which basically rewites all the APIs into JDK8 compatible code.
vips7L 1187 days ago [-]
Personally, I don't consider Android to be Java and I am quite happy that Google is pushing Kotlin now instead.
szatkus 1187 days ago [-]
The problem is that many Java projects in the wild are... well, old. Some of them haven't migrated to Java 8 yet and even then you can stuck with a lot of code using the old API.
jeltz 1186 days ago [-]
There is sadly still new code written which uses the old API. I just inherited code from 2019 which uses the old text me API.
adamc 1187 days ago [-]
This is a nugget of great wisdom. (I will likely get downvoted for such a useless comment... so be it.)

Trying to do everything for everyone makes for very complex systems that are too abstract to be easily used.

dlandis 1187 days ago [-]
I wonder though, how much is some extra complexity good for the bottom line of companies that make their money on consulting and supporting the tools that they create/maintain?
freedomben 1188 days ago [-]
A bit of a side note here regarding the author.

Bruce Eckel's book "Thinking in C++ Vols 1 and 2"[1][2] was possibly my favorite book ever read. Bruce is (in my personal opinion as an observer of people with zero professional training in psychology) a depth-first learner and naturally seeks to understand how things work by looking at the layers. Building up from there allows true understanding and even mastery of the material.

This is exactly how I am as well, and the result is often that it can take a while for me to pick things up and really understand them (since I have to cover so much more material than a typical person) but my level of mastery afterward is typically very high.

My experience now from well over a decade in the industry is that most people are not this way, and also that many people who are this way don't necessarily realize it. If you feel like understanding history, layers, etc helps you understand things much better, do yourself a favor and follow Bruce Eckel's blog and read his books. Thinking in C++ 2nd edition is 20 years old now. A third edition would be wonderful. Or maybe even better, "Thinking in Rust" :-D

[1] Volume 1 available for free on Archive.org: https://archive.org/details/TICPP2ndEdVolOne

[2] Volume 2 available for free on Archive.org: https://archive.org/details/TICPP2ndEdVolTwo

Tainnor 1188 days ago [-]
Interesting observation. I feel like I am like that - I hate doing anything that requires me to develop only a superficial understanding (e.g. messing around with Kubernetes configuration without understanding how it all works on a fundamental level). I also don't like systems that are hard to debug - I want to be able to make assumptions and test them, and that can sometimes be notoriously difficult with cloud-based infrastructure.
freedomben 1187 days ago [-]
Interesting you mention K8s, I had that same problem! It took me 6 months to get up to speed on K8s because I wanted to what everything meant, and those are all deep rabbit holes (like, try explaining the `apiVersion` in every object without going down a rabbit hole of how K8s works for example).

Making that even worse there wasn't much out there to cover internals. The situation is much better now though. I guess that's part of price you pay to be an early adopter of the latest hotness.

Tainnor 1187 days ago [-]
I still don't really know how Kubernetes works deep down, although I have learned enough to at least debug some of the most common issues I encounter at work, so if you have any very good resources (don't have to be free), I'd be happy to hear of them (the resources I've tried weren't very good, unfortunately).
koolba 1188 days ago [-]
> This is the problem I had with Gradle:

> To do anything you have to know everything

This sums it up pretty well. Coming from a background of using Maven purely for dependency management and basic compilation, existing Gradle projects are incredibly unapproachable and slow. And don’t get me started on the background daemons to speed things up either.

mrec 1188 days ago [-]
Yup. Gradle is by far the worst-designed technology I've encountered in ~30 years of programming. Using it not only made me not want to use Gradle, it made me not want to use Java.
usrusr 1188 days ago [-]
> Gradle is by far the worst-designed technology I've encountered in ~30 years of programming.

I nominate Groovy. Many of gradle's failures are just idiomatic groovy. The entire mindset of "friendly simplifications" that work 80% of the time, and if they give pretend that you don't notice, look, there's pretty code over there!

Even kotlin suffers from some of that (you can override a val x:Int with a val x:Int get() unless it's tied down otherwise, talk about principle of maximum surprise) but the genes from the other parent avoid the worst.

rcoveson 1187 days ago [-]
Can anybody explain to me why it ever seemed like a good idea to make both: (1) Semicolons at the ends of lines and (2) Function-call parentheses, not required, and not illegal, but optional? It strikes me as an abdication of the responsibility of a designer, like making both String::substring and String::substr available as aliases one to the other. Who cares? Choose one and stick with it! Otherwise it becomes a race between linter-writers and community programmers to see if the entire ecosystem will become polluted with an ugly mix of both styles. A race which the linter-writers always lose.
zmmmmm 1187 days ago [-]
Groovy was created during the time when Ruby was taking off and was dramatically improving productivity of creating basic CRUD type web sites. So Ruby had a beautiful simple syntax, and I think Groovy was an experiment to see how close you could get to that while maintaining compatibility with Java syntax. It's actually a remarkable success as far as it goes - most Java code can be copy and pasted in and is valid Groovy. But of course it only works because it optionally accepts parentheses, explicit vs implicit arguments etc.

It does lead though to one of the biggest lies which is "if you know Java then you already know Groovy!" - that's just a mean trick to play on people.

rcoveson 1187 days ago [-]
Maybe the rest of Ruby is more "beautiful" and "simple", but those adjectives don't apply to the inconsistency caused by optional code punctuation. I think Ruby users even realized this, and have since imposed strict requirements on their projects that only one style be followed.

Groovy is all the more guilty for carrying the bad tradition forward. It's akin to somebody looking at the success of C and deciding that its macro system must be perfectly preserved going forward.

dragonwriter 1187 days ago [-]
> I think Ruby users even realized this, and have since imposed strict requirements on their projects that only one style be followed.

A common set of conventions in the Ruby community uses both options for optional punctiation, with context controlling which is used for a particular case. E.g.,

1. Use a single expression per line, and don't combine the line starting or ending a block with the contents, and don't use semicolons where they are unnecessary (so, semicolons are used only to separate the opening and “end” of single-line blocks.)

2. Use parens among function calls, except omit them in calls that are part of internal DSLs.

oblio 1187 days ago [-]
And to make things more interesting at some point the nearly-frozen-in-time Java started evolving again so Groovy is stuck in some sort of parallel universe because Ruby failed to get mass traction and most people are not familiar with it while Java 8+ has its own concepts that don't translate as neatly as Java 6-7 concepts translated to Groovy at the time.
usrusr 1187 days ago [-]
For Groovy the simple answer is they claimed that every piece of Java code would also work in Groovy. This wasn't ever true (well, maybe before someone decided that the equals() method is confusing), but it didn't matter, because of the "80% is plenty" mindset that groovy appears to be built on.
rcoveson 1187 days ago [-]
That would justify requiring semicolons/parentheses. It doesn't justify making them optional. The real explanation is that they were mimicking another language, Ruby, that had made that mistake.
cmehdy 1187 days ago [-]
Writing Groovy scripts in JMeter (for some custom requests) when doing distributed performance testing was a good way to enjoy pretty much anything else afterwards.

I suppose I should more accurately call that thing JSR223 + Groovy, all stored in an extensive XML file and edited through the JMeter UI..

UweSchmidt 1186 days ago [-]
Off topic, but if you plan on coding your load tests I think Gatling is a better choice, you get to program in Scala which so far looks clean and readable to me.
mrec 1188 days ago [-]
I think I conflate the two, and I'm not sure that's wrong. I've never seen anyone use Groovy outside Gradle. I mean why would you, if you had a choice?
McP 1187 days ago [-]
I've had to use it to configure Jenkins. In Groovy, variables are global if you forget to declare them with 'var'. This has caused so many concurrency bugs and so much sadness.
cataphract 1187 days ago [-]
Especially before Java 8, writing Java code was very painful compared with Groovy, even though Groovy was fairly slower, and its compiler buggy. Groovy has closures, AST transformations builtin, much nicer syntax for properties (backed by getters/setters), ability to sort-of change classes at runtime (without instrumentation), multiple dispatch (i.e. dispatch based on the runtime type of the arguments), the ability to use reflection without the awful reflection API and so on.
Tainnor 1188 days ago [-]
Back in the days when Kotlin didn't exist and even Scala was in its infancy, some people genuinely liked the JVM ecosystem and even aspects of Java itself, but were turned off by the verbosity of Java. Those were the people that started using Groovy and also projects such as Grails (especially since they saw the success of Rails and Django and wanted to emulate that).

Also, I guess some people genuinely like gradual typing, although I've never found much use for it.

Nowadays, I wouldn't pick up Groovy anymore, but there was a time where it was basically that, or Java (or a different ecosystem entirely; or something like JRuby / Jython).

zmmmmm 1187 days ago [-]
Groovy is an amazing language. Don't judge it based on Gradle. It is used for all kinds of things. Gradle sort of interacts with it in a highly toxic way and brings out all its bad parts. If you use it the opposite way - as a better version of Java with mostly structured code, plenty of explicit typing and avoiding the highly "magic" aspects that Gradle focuses on, then its a great language for application development. Certainly better for high level things than Java - but completely 100% compatible with the Java ecosystem.
Too 1187 days ago [-]
Could you link to any githubs with examples of such good groovy?
zmmmmm 1186 days ago [-]
You could have a look at something like Geb - this is a completely random class I picked:

https://github.com/geb/geb/blob/master/module/geb-core/src/m...

So it looks mostly like Java, its just making use of Groovy's niceties and more powerful constructs in various parts to make the coding nicer.

tamasnet 1187 days ago [-]
Groovy is fantastic for quickly creating domain specific languages. I've done a bunch of them over the years for different problem domains and have yet to find another solution that yields effective custom languages that are as readable and easy to implement.
michaelcampbell 1187 days ago [-]
I have an old java (7, 8) app I maintain that whenever possible I move classes to Groovy as I am making other changes in them.

I would probably do Kotlin, now, but that wasn't an option when I started this.

The amount of boilerplate removed is one big win, but moreover the more functionally oriented aspects of most anything you'd do with a for-loop in java is wonderful.

And with annotations such as @CompileStatic and @TypeChecked, I am able to forgo SOME of the syntactic niceties for the compile-time binding java-comparable speed.

dvdgsng 1187 days ago [-]
Jenkins uses groovy for scripted build Pipelines, works pretty well and makes Jenkins a bit more fun to use, if that is even a thing.
imtringued 1187 days ago [-]
There are worse things than using Grails. For example using straight up Spring. Grails is a sane wrapper around Spring so you can easily bring regular Java developers into a sane ecosystem. For example Grails' Gorm is the only sane way of using Hibernate in the entire JVM ecosystem. Using Hibernate directly will drain your sanity very quickly.
EE84M3i 1187 days ago [-]
>you can override a val x:Int with a val x:Int get()

Could you expand on this? I don't follow what you mean. Are you talking about some form of shadowing?

usrusr 1187 days ago [-]
Kotlin is playing it fast and loose with blurring the line between fields and bean-style properties. In Java you could have a public final field and it was obvious that it was immutable (unless referencing a mutable object). Kotlin, in an attempt to match Groovy in syntax cuteness, allows to declare a val (supposedly the equivalent of a java final field) that is actually not backed by memory at all but a getter method in disguise.

  val x: Int // this is an immutable value
  val y: Int // this is an immutable Function0<Int> that is executed each time and but pretends to be a val
     get() = System.currentTimeMillis()
Tainnor 1186 days ago [-]
I think the reason for that is that Kotlin doesn't necessarily aim for immutability as much as it aims for read-only values. This is also why there is no truly immutable implementation of `List` in the stdlib, although the interface itself it read-only (but it can still point to a value that is being mutated somewhere else).

I agree that true immutability - or code that is more obvious about avoiding side-effects - could be useful, but I don't think that was ever the goal.

usrusr 1186 days ago [-]
That's certainly an accurate description of the cause. But I don't think that it's a valid excuse: not supporting immutability well is fine, pretending that you do when actually you don't is not.

The kotlin defense to this surely is that immutability happily exists in val constructor args (with the usual exception: not transitive through references), but that's purely contextual and a difference that is very hard to represent at usage site (e.g. they look exactly the same in the intellij "javadoc" view). If for some reason bean-style methods had to be represented through var/val syntax, I think that it would have been much better if read-only calculated getters were represented by a var without set(), leaving val to cases where you're guaranteed to get the same when referenced twice (value set once in constructor or some lazyness shenanigans).

ptx 1187 days ago [-]
C# also does this, and so do Python, JavaScript and Visual Basic. Java is the odd one out by not supporting properties.
Too 1187 days ago [-]
Supporting properties is one thing, having assignments copy the backing property as a lazy evaluated function-pointer another, even if value is supposedly a int.

Python getter properties are evaluated instantly on assignment. To convert them back into function-pointers like the Kotlin example above you really have to go out of your way by deep diving into inspect module. The result is a property-object which is not assignable to a int-variable, but type checking probably wouldn't go this deep as inspect naturally is very dynamic in its nature.

My guess is Kotlin does this as a way of structural typing, if it walks like a int and talks like an int it is an int.

usrusr 1187 days ago [-]
Do those others heavily advertise the difference between var and val as a core feature and then sabotage it by dressing up getters (that are evaluated on each call) as immutable values?
bobthebuilders 1187 days ago [-]
I think the main thing to understanding this is that Kotlin tries really really hard to not have fields. They're all properties, similar to get and set calls in Java (and if you have a feild in an interface it's basically that).
EddieRingle 1187 days ago [-]
They're confusing a read-only property that can be overridden with one that's made final.
allenbrunson 1188 days ago [-]
hard agree.

i took up flutter a couple of years ago, which means i am now saddled with (ugh) gradle for android builds. i am used to being able to intuit the underlying architecture of various tech things and fix them, which is utterly impossible as far as gradle goes.

not only are the error messages unhelpful, they are usually confidently incorrect. they tell you the problem is likely thing X, which in fact has nothing to do with the problem. (to be fair, this seems to be coming from whatever stuff google has added to the android build process, rather than gradle itself.)

these days, once gradle starts spitting errors, i know better than to read them. instead, i have to start thinking about when the build last worked, and what might have changed. if that path proves not to bear fruit, then it is time to trash that project completely and recreate it from scratch, which experience has taught me will take a lot less time than trying to “fix” the gradle build errors.

kohlerm 1187 days ago [-]
Come on. Gradle might have many features you might not need, but IMHO the one popular alternative maven is one of the worst designed build tools. Dependency resolution is a joke just taking the shortest path in the tree in case of conflicts. No good support for incremental compiles etc
pjmlp 1187 days ago [-]
Thanks Android, the only reason to ever touch Gradle.
p2detar 1187 days ago [-]
Sorry that you feel this way, but this is simply not true. If it were the case, why would all these companies [0] waste their time with Gradle? Bad technologies tend do die out. Not the case here.

0 - https://gradle.com/customers

(Edit: Heh, TIL rage downvotes are a thing in HN as well.)

blandflakes 1187 days ago [-]
It isn't really the case that poorly designed technologies die out, necessarily. They just need to have one killer advantage. Javascript, as the only option, PHP prior to getting its act together won with its extremely low barrier to entry both in terms of learning the language and getting it running somewhere. So gradle having users doesn't convey to me that it's necessarily well-designed. I think it's "killer advantage" was that it's not xml.
p2detar 1187 days ago [-]
Js and PHP: fine, but it’s not quite clear from your post what that killer advantage of Gradle is. Having users? Hmm.
blandflakes 1187 days ago [-]
I tried to say in the last sentence that I think most people who abandoned maven for Gradle mostly just hate xml, sorry if you missed the sentence saying that.
pjmlp 1187 days ago [-]
Android.
p2detar 1187 days ago [-]
So what are the alternatives for building stuff on Android other than Gradle?
pjmlp 1187 days ago [-]
What Google's own teams use instead of what they push to everyone else via Android's SDK, Bazel and Soong.

Or Facebook's Buck.

p2detar 1187 days ago [-]
Nice. I'm genuinely interested.

I do not work on Android apps, but I use Gradle in semi-large web app and lots of fat jar projects. Do you happen to know if there are any perf measurements that outline Gradle is slower?

pjmlp 1187 days ago [-]
Basically every Android conference has a set of talks on how to make Gradle perform in usable ways, including setting up the background daemon to use as much RAM as it can, RAM disks, SSDs.

Tricks that Maven, or the other build systems never required.

p2detar 1187 days ago [-]
Well, in all fairness I switched from Maven to Gradle exactly due to low performance. Gradle gave my projects a boost of 3 to 7 times faster build speeds. RAM is not an issue for my setups, although I can’t recall how Maven held there against Gradle.

Buck looks quite interesting. Thanks for pointing it out!

blandflakes 1187 days ago [-]
The implication that there are few alternatives would lump gradle exactly into the same group of technologies as Javascript, then :)
pjmlp 1187 days ago [-]
C, JavaScript and PHP prove otherwise.

Gradle has Android giving it wind on its sails, because a couple of people there are really into it.

Yet even Google's own teams rather use Basel and Soong instead.

TheRealSteel 1188 days ago [-]
I don't understand why Gradle breaks every second time I build my project, and I have to run Clean Project.

If Clean Project is required to build the project, why isn't that part of the build process?

rwoerz 1188 days ago [-]
Same for Maven. Common reason: the mere presence of a "leftover after refactoring" file beneath target/ breaks the build because it is still included in the classpath.
eitland 1188 days ago [-]
FWIW: I've used Maven for years and I don't have these problems.

When I am tasked with fixong other peoples config I usually move things to the correct location, delete the corresponding configuration qnd then everything works (better).

60secs 1187 days ago [-]
Scala / SBT is so much worse
eplanit 1188 days ago [-]
Exactly. And now, android development is by design impossible without it. So stupid.
atc 1188 days ago [-]
I second this. Java's paid the bills for most of my career (17 years) and it is second only to NPM and its ecosystem in my book.

Compared to Cargo (Rust) and Cabal or Stack in Haskell, it's constantly painful to use.

bitcharmer 1188 days ago [-]
I have the same impression of gradle. If I have to learn another language (groovy) and a whole new platform infrastructure and APIs just to understand what a build does, it's definitely not worth the effort. Most of my peers have the same views.

Fun fact: look up gradle in urban dictionary.

zmmmmm 1187 days ago [-]
This argument I don't really get. You're going to learn a "language" anyway - whatever build system you employ. It may or may not be Turing complete, but you're going to end up learning it once you get to any level of complexity in what you are doing.

Why not have it be something with more general usefulness as well?

santoshalper 1187 days ago [-]
I have something with more general usefulness. It's called Java. I don't need a programming language to build my programming language.
posedge 1188 days ago [-]
Yeah about that, do you have some insight on why the X background daemons are always 'incompatible' and gradle launches up new ones?
gddhn 1188 days ago [-]
Being new to Gradle, I used to run into this same issue. In one of the projects I use, I happened to find this comment, in github, which helped me fix the issue https://github.com/quarkusio/quarkus/issues/10454#issuecomme...

So increasing the default max heap size of the gradle build helped fix the issue https://github.com/quarkusio/quarkus/pull/10508/files.

benibela 1187 days ago [-]
And how could I make sure that the gradle I start on the command line and the gradle started by Android Studio use the same daemon?
rwbhn 1188 days ago [-]
Came here to post the same quote. Matches my experience as well.
smitty1e 1188 days ago [-]
Then there is Jenkins. I looked at the jenkinsfile and said "I guess Java and Python had a tryst?"

Eventually we'll get to the GitLab CI/CD, but the existing disaster supports the status quo, so it's not a priority.

noisy_boy 1188 days ago [-]
My experience with JenkinsFile has improved once we setup library functions for it to leverage on. Only downside is that you need to write them in Groovy but the payoff is that the JenkinsFile reduces to basically a function call or two per stage which makes it super clean + it makes JenkinsFiles more or less "standard" (because there is practically no project-specific stuff in it - the complexity is managed by the library functions). This approach has made fixing issues or enhancements so much more easier for us.
smitty1e 1187 days ago [-]
The "goodness" of Jenkins for my use-case is that the service can be a kind of "sudo" for capabilities we don't want to spread around.

That said, learning Yet Another Language that only deals with a niche requirement is a total bore.

If we can cook it down to executing some garden-variety bash in a special context, along with some spiffy pipeline visualization, that is enough.

noisy_boy 1187 days ago [-]
At the end of the day, its just the shell executing the commands :) sure, you can always distil it down to a script (or a set of scripts) and nothing wrong with it either - as always, depends on the context.
cataphract 1187 days ago [-]
The article seems to boil to down to: you need to understand Groovy to effectively use Gradle.

It's impossible to disagree with this, but this is a realization you should have after interacting with it after 10 minutes.

I may be biased because I'd been using Groovy (Grails apps) for years before I used Gradle so the syntax was not a problem at all for me. For me, the problem with Gradle is the very poor documentation. If I want to do something more complex, I either find the answer in Stackoverflow/the Gradle message board, or I will have to look at the source code of the plugins. Creating a task for scratch is fairly simple, it's interacting with the plugins that's difficult, and while I agree with the author that excessive abstraction through DSLs doesn't help, if these DSLs didn't leak and were properly documented it wouldn't be a problem.

Another problem is that it's clear what the right conventions are. Say you want some classes to some exec task. Where should these classes live? Do you use a configuration? Create a sourceSet? Add a directory to an existing sourceSet? You just edit the classpath property in the task to point to a directory? I miss some of the rigidity of Maven, though not its XML syntax. The ability to write actual functions in Groovy (e.g. a closure implementing a file filter) is very much welcome.

emsy 1187 days ago [-]
Having used Gradle, I disagree. Even if you know Groovy, declarations in Gradle are executed in a certain order and you don't really know what a closure does or what it's side effects are. Sometimes you have to read the source code because the documentation is insufficient. Gradle is not a simple tool and the documentation (last time I was using it) isn't helping.
cataphract 1187 days ago [-]
I agree that order of execution is sometimes problematic in Groovy and you have to use evaluationDependsOn() or afterEvaluate {}. I don't think the DSLs are per se particularly problematic; they generally just set some properties of the task (when they're more complex and yet the abstraction leaks, then they do more harm than do). But yes, the documentation is awful, and is IMO the biggest problem with Gradle.
acaloiar 1187 days ago [-]
While I agree with you that it should be obvious that Groovy knowledge is necessary to operate Gradle, I think it's important to note that the intersect between people building things in Groovy and people building things in Java/Kotlin is quite small. And for that reason Gradle, with Groovy as its star feature, will always be a fraught choice for a build system.

Developers simply have to know too much Groovy to operate Gradle effectively.

twic 1187 days ago [-]
I entirely agree. But i also don't know what the Gradle authors could have done instead. Writing build scripts in Java 1.6 (the latest version at the time Gradle was written) would have been a showstopper. Kotlin didn't exist. XML alone isn't expressive enough, so you would have needed some sort of Ant-like crummy language expressed in XML.

Buildr, which i think predated Gradle, used Ruby. I'm not sure Ruby is any better than Groovy here.

Perhaps Jython would have been a good choice.

zmmmmm 1187 days ago [-]
> Perhaps Jython would have been a good choice.

It's interesting because plenty of build systems exist written in Python but they don't get much used because Python itself is not really flexible or expressive enough for writing good DSLs - and build systems are just specialised enough that a good DSL is actually required to do them efficiently.

So we seem to be on a never-ending treadmill of wheel reinvention searching for the right compromise between these things.

bsder 1187 days ago [-]
> It's interesting because plenty of build systems exist written in Python but they don't get much used because Python itself is not really flexible or expressive enough for writing good DSLs - and build systems are just specialised enough that a good DSL is actually required to do them efficiently.

Meson seems to be a counterexample.

Too 1187 days ago [-]
Scons is another example of Python as the config language. In fact most of the times you don't need a comlicated DSL, or any language at all. Look at Webpack, npm, Android Blueprint or Bazel which more or less is just JSON-flavor, or Rusts Cargo.toml which is just toml markup.

You can get very very far with just a list of files and some config properties, if there is something complicated needed in the configuration the markup can refer to an external script.

In fact not accidentally mixing the configuration step with the execution step, as Gradle often does, can be considered a feature.

twic 1187 days ago [-]
Cargo isn't just TOML, it's TOML, plus a build.rs script, written in Rust, for everything you can't express in the TOML.

I agree that a lot of the time, you don't need Gradle's sophistication. But large, complex projects, in my experience, inevitably develop strange and unusual build needs. At that point, if your tool doesn't support them naturally, the complexity ends up going somewhere else - you have to write plugins, or standalone tools, or build script generators, or manage a lot of repetition in the build script, or multiply subprojects, etc, so you can do what you need to do.

bsder 1186 days ago [-]
> Cargo isn't just TOML, it's TOML, plus a build.rs script, written in Rust, for everything you can't express in the TOML.

Cargo is nice--until you have to coexist with something else that also wants to own the world of the build process.

And that build.rs script causes a LOT of heartburn when your needs get larger or you need repeatable builds.

I don't know what the right answer is, but cargo is exactly the kind of system you describe that you have to start working around when you have more sophisticated needs.

zmmmmm 1187 days ago [-]
> this is a realization you should have after interacting with it after 10 minutes

The problem is, it is presented as if you don't need to know Groovy. And its not surprising because, if everybody contemplating using Gradle was first told "You should only do this if most of your team is willing to learn Groovy to good proficiency" - hardly anybody would do that.

Now groovy is a great language IMHO but I think the way this goes down results in people hating it because they get handed a build as if they should understand it easily and then experience hours and hours of frustration as it exhibits unexpected behavior as they learn all the surprising things about Groovy (and not just Groovy but the Groovy+Gradle DSL dialect that is much weirder than plain Groovy).

ncmncm 1187 days ago [-]
The problem with Gradle is that people try to use it, and so try to understand it, and then treat the sunk cost to understand it as a reason to keep using it. Bruce correctly sees being locked into Gradle as a way to need his expertise, but that is not a reason to follow him down the rabbit hole.

The correct response to discovering the nature of Gradle is to abandon it, immediately. (Similarly Waf, and Scons.) The world does not need yet another one-or-two-language-target build system, or another build system as full general scripting language. Things work better when you don't need expertise. A build system should be just barely powerful enough to do builds, but not powerful enough to mystify. A build system should work equally well for all the languages you might find you need to use. A build system should not need to be studied to be understood: isolated examples should suffice for each need.

Similarly, the build for a project should not need to be understood: everything you need to know about what you are looking at should be right there, or (failing that) in a single, central place for the project. The build should be the least interesting or engaging part of the project; the project itself inevitably demands more attention than you can spare. A build system that demands attention is a child screaming when you need to work.

huodon 1187 days ago [-]
I agree with you very much. Since gradle supported kotlin script(typed), I seem to have a little understanding of it. I have used it for a long time. Besides the treat the sunk cost, Maven makes people less willing to use it than gradle.
jzoch 1187 days ago [-]
Many have posted about gradle builds forced on them but I've found modern Gradle to be quite nice. I don't reach for anything too complex - I just list deps and plugins.

Writing new plugins is far easier with Gradle than Maven (and way way way less ugly to configure) and there are more plugins available (and usually of higher quality than their maven counterparts).

Speed is significantly better than Maven. Incremental builds gave us back 80% of our time spent sitting on maven. Reusability is much better than maven too.

There are definite footguns but if you can avoid them (which I understand requires work and itd be better if they were not there at all!) then Gradle is decent. Its no Cargo but woe is life. The few times I had to parse a file at build time to read some credentials in jenkins I've been grateful im using Gradle instead of Maven.

strulovich 1188 days ago [-]
If you work on any seriously big Java/Kotlin/Android project, and value your time, I recommend looking at Buck (or Bazel or other tools) for building instead of Gradle if you haven’t done so yet.

It would be annoying to move build tools, and plenty more of hookups are not as convenient in a bunch if cases, but when you get it going things will run faster. (So again, the bigger the project, the more likely you would like that)

A big part of the reason is that tools suck as Buck (which, like Bazel, uses Skylark as the language, which is a very limited python in essence) avoid the general programming patterns to avoid the issues described here.

anuragsoni 1187 days ago [-]
I concur. I worked on a java project at a previous job and Bazel was instrumental in getting fast deterministic builds. There were some growing pains as the bazel docs weren't great back then (this was before bazel reached 1.0), but once we got things to work it was nice to work with. We were able to leverage Bazel for our Angular application as well so it was nice to have everything building with one tool.

> A big part of the reason is that tools suck as Buck (which, like Bazel, uses Skylark as the language, which is a very limited python in essence) avoid the general programming patterns to avoid the issues described here.

I also agree with this. My current language of choice is OCaml and the most popular build tool is dune [1], which uses an s-expression based configuration language, and its nice to have a more restrictive DSL that avoids some pitfalls of using a full blown programming language for configuring builds.

[1] https://dune.build/

emsy 1187 days ago [-]
The problems match my experience with Gradle pretty well, and they point to a bigger issue in build systems: you usually can't easily debug the build system. Most build systems try to be declarative, but can't help to have imperative parts where order of execution matters or when a certain environment variable is set. You have these kind of problems in Gradle and I experienced them in Cmake, Maven and Make as well. At some point you just want to step-debug or have the environment variables print at a certain point during the build. All I want is a build tool where I declare my build by simply calling functions (or extend with custom functions) and if there's an issue I want to be able to step through the script and check what's wrong.
cataphract 1187 days ago [-]
You very much can debug Gradle. It's just like any other Java/Groovy application. You set a breakpoint in the build file or some Gradle source file and you attach a debugger. In this respect, it's probably more debug-friendly than, say Makefiles where all you can do is add some print statements or go through megabytes of debug output.
wasyl 1187 days ago [-]
Adding to that, in IntelliJ it's as simple as running the task from the 'run Gradle task' window (not sure how it's called) with Shift pressed. All the breakpoints in the build scripts will now work.

If you also use wrapper with sources (`-all` instead of `-bin` suffix in the `gradle/wrapper/gradle-wrapper.properties`) you can step into the entire Gradle source code as well

santoshalper 1187 days ago [-]
In over 30 years of programming, I have never had to debug a makefile. I think I would just retire if I ever had to.
emsy 1187 days ago [-]
Sometimes builds are complex. You have several deployment paths, platforms, modules, features, signing and what not. Then the build is akin to a small program. That’s still reasonable. The problem is that all build tools that allow this make it more complex than simply writing a small script that does exactly what you need. Add to that that some dependemcies use a different build tool that you use. Adding a cmake dependency to a make project makes everything even more complex.
PaulHoule 1188 days ago [-]
Many people dont appreciate Maven because they get hung up on XML. If you need to do anything in Maven which isnt dead easy to do in XML you just write a plugin in Java which is the language you are coding in anyway.
Macha 1188 days ago [-]
I wonder if this is a reflection of enterprise processes. Writing a plugin in a previous employer meant creating a new repo, a new CI/CD pipeline, getting it pushed to artifactory, making sure people had the inhouse artifactory set up in their settings.xml, and all that had internal overhead. Also learning the maven plugin API. And nobody on your team would want to, so you'd be stuck answering every question about this feature forever more. Compared to gradle where the same tasks just require a few if statements in a scripting language.
dmitryminkovsky 1188 days ago [-]
This very much lines up with my experience.

A long time ago I wrote a Maven plugin and decided to clean it up for open source. It got absolutely nowhere because after everything you describe—setting up a repo; learning the Maven API, which is one of those expansive APIs that has a lot of metaphoric semantic constructs—distributing it involved getting it into Maven Central by which point I had run out of time/mental bandwidth and never made it happen.

Compare if I had been using Gradle at the time: I would have just coded it up in Groovy, a language I thoroughly enjoy, right there in setup. There are some things I don't like about Gradle, but there's a lot it has going for it, too. Personally, I like XML and enjoy Maven for situations where existing plugins are enough—which is 99% of the time—but that lack of flexibility can be constraining when existing plugins aren't enough.

lmm 1188 days ago [-]
I find that little hurdle actually improves the quality a lot. It means people don't write maven plugins for every single conceivable scenario; usually there will be at most one or two plugins for whatever you wanted to do, properly documented and maintained, whereas with gradle there will be four or five different plugins with no documentation each of which only covers half of the task. And forcing people to put logic in actual released plugins rather than ad-hoc one-liners in the middle of the build definition means you avoid ending up with a bunch of ad-hoc one-liners scattered throughout your build definition, which is much better for long-term maintenance.
dmitryminkovsky 1188 days ago [-]
Yeah for sure, and that's what makes Maven a great tool at the end of the day. It's just those instances you encounter rarely where existing Maven plugins are not enough that I've wished I was using Gradle so I could drop a few one-liners and be done with it. I really like Groovy so any excuse to write some Groovy is always tempting. As you say, a few one liners here and a few one liners there can make a build incomprehensible. So people need to recognize that and keep their Gradle builds approachable if they're going to be doing that. It's pros and cons.
chii 1188 days ago [-]
if you had made the groovy script in gradle, the code/capability would not have been sharable to anyone else but this single build (other than copy/paste sharing).

if you had the same code as a maven plugin, it would've been instantly sharable, and easily updatable centrally via a release process (as maven plugins tend to also be built with maven). Upfront work, but for long term reward.

1188 days ago [-]
happyweasel 1188 days ago [-]
>Writing a plugin in a previous employer meant creating a new >repo [..]

I just used the maven groovy plugin to invoke a groovy script containing the functionality instead of a maven plugin (a few lines of code). the groovy script was part of the source code and therefore easy to tweak. A lot of maven variables from the project are accessible from the script. Yeah, it's not really nice.

norswap 1188 days ago [-]
Maybe so. But there's also a ton of legit criticism of Maven for how inflexible it is. Doing any sort of custom task requires addons.

Gradle also sucks, but at least you can script it much more easily.

twic 1187 days ago [-]
> If you need to do anything in Maven [...] you just write a plugin

You should not need to write a plugin!

pjmlp 1187 days ago [-]
Android is the only reason I put up with Gradle, for anything else Java related, I turn to Maven and happily forget that Gradle even exists.

It is Ant all over again, with Groovy slowness and game rig hardware requirements to perform in a sane way. There is hardly any Android conference without build related performance improvement talks.

nsonha 1187 days ago [-]
Maybe this is a dumb question but I thought gradle kts was released a while ago. Why does everyone in this thread still complains about groovy? Could they not just use kotlin?
wasyl 1187 days ago [-]
It's not an easy switch. Still most of the examples and articles are in Groovy. Until recently, IDE (IntelliJ) support for Gradle Kotlin DSL was abysmal (like analysing stuff on the main thread). Only recently it's getting more traction as the worst issues have been resolved.
pjmlp 1187 days ago [-]
Because it still is work in progress.
wasyl 1187 days ago [-]
> There is hardly any Android conference without build related performance improvement talks.

fwiw I think the Android toolchain being slow doesn't help. On the same conferences someone will also speak about how the new Android Gradle Plugin is X% faster, so it's not all Gradle's fault :) That said there's plenty more Gradle can do (and is doing) to improve performance. The startup cost to configure all tasks is definitely high on my annoyances list

bassman9000 1187 days ago [-]
Gradle was the excuse ant writers/maintainers wanted not to migrate to Maven, because the latter forces you to be cleaner with your project organization.
jayd16 1187 days ago [-]
Can someone explain to me why Gradle is popular? It seems like hot garbage even though most teams can make it work.

Maven was painful as well but it felt more consistent to me.

You know whats really sad? MsBuild proj and solution files are easier to understand!

I'm sure there's a lot of great work that's going into Gradle but I just don't understand why this is the DSL and syntax we decided to put effort into.

zmmmmm 1187 days ago [-]
I reckon the best thing gradle ever did was the 'gradle wrapper' which means, if you have just java installed it'll bootstrap everything up from nothing. So if starting a new project and I just want people to be able to build it and I want them to use exactly a specific version of gradle I can create a 1 line build file and it works for just about anybody who runs it on any platform.

So on the one hand, its the easiest way to get started, and on the other hand its a turing complete language so there isn't anything it can't do so once started, people can always keep going.

And then, yes, Maven is complex and mysterious in completely different ways but almost to the same extent as Gradle.

wasyl 1187 days ago [-]
Coming from Gradle, it always baffles me how there's no wrapper for every popular tool out there. I'm always confused by the venvs, rbenvs, and overall managing multiple versions of the toolchain for different projects. In Gradle it's just so simple, and with toolchains support [1] it's going to be a very predictable build environment with just a simple `./gradlew` invocation.

[1] https://docs.gradle.org/current/userguide/toolchains.html

Tainnor 1186 days ago [-]
tl;dr

I think that especially compared to Python with its... very fragmented landscape of dependency and version management tools, Ruby has a pretty standardised way of making sure you run everything in a reproducible environment, which maybe isn't 100% perfect, but usually works quite fine, even though it is a different approach than the gradle wrapper.

--

More details:

In Ruby, it is by now completely standard practice to use some sort of Ruby version manager (rbenv, rvm, chruby, for example - they should all work). Those version managers always can pick up the correct Ruby version from the ".ruby-version" file. This is actually an improvement over the Java situation where different people might in theory run the same project with different versions of the JDK without them even noticing (although the JVM is of course much more backwards-compatible than Ruby usually is, but it can still lead to problems). Even the gradle wrapper doesn't help you there - it assumes you already have the JDK installed.

Also, Gemfiles (dependency declaration files) typically (or maybe nowadays always?) include the version of Ruby used, and the Gemfile.lock also specifies the version of Bundler that was used.

It is standard practice to run every Ruby command in a project through "bundle exec", in which case Bundler will always check all your dependency versions. If the Ruby version is wrong (which can only happen if you don't use a version manager anyway), I think it will just refuse to run and print an error message, same if you haven't installed some dependency with the right version. If the bundler version doesn't match, I think it will at least output a warning in some cases.

So, in practice, the only true differences between that and the gradle wrapper are:

- you need to install bundler yourself (although that's just "gem install bundler")

- you need to remember to use "bundle exec" (although there are tricks to avoid that, e.g. binstubs + something like direnv)

- you might not use the "right" bundler version, unlike with Gradle - however, in several years of writing Ruby I ran into the problem that a mismatched Bundler version led to an issue, exactly once - and they've since added the warning - so I don't think it's that big of a deal

- on the plus side for Bundler, it actually enforces transitive dependency locking, unlike Gradle, for which you have to explicitly enable it - and also many other tools don't support that properly (e.g. Dependabot)

mr_tristan 1187 days ago [-]
I suspect that Android and Kotlin have really helped Gradle adoption. But even before this, Gradle has a very easy "customize it" approach. Though... honestly, it might just be that people hate XML.

Personally, I've stuck with Gradle, even though I'm not really happy with it, mostly because of these features:

1. Composite builds - https://docs.gradle.org/current/userguide/composite_builds.h... 2. Dependency substitution 3. "local" plugins, i.e., stuff in `./buildSrc`

These features let me combine projects defined in multiple git repositories in a "workspace" project. Then IntelliJ can read all these projects, and it magically substitutes my local version over a specific version. Ergo, I can have multiple libraries, edit and debug them and and application code. When it's time to commit, I push them up in individual MRs back in GitLab - And I could swear GitLab was going to make some kind of multi-project MR possible at some point.

So, the "workspace" is generally for development, then we use GitLab CI for each project independently, for a "formal" versioned approach. It's quite nice.

In any case, I'll typically work with a pretty broad set of apps and libraries in a single workspace, typically between 15-30, and Gradle and IntelliJ handle this just fine. Our Maven projects with fewer modules never seem to get things working as smoothly ironed out - I suspect it's something wacky going on with the build.

So, while Maven allows build composition, but doesn't really have the dependency substitution concept, useful for local workflows. Also, it just doesn't seem to perform as well, especially with the IDEs we've been using. I can't explain it, haven't investigated it, but then again, I've found a solution that works.

lmz 1187 days ago [-]
That's really nice. Does maven support anything similar? Last time I tried this in maven it devolved into playing weird tricks with the local cache (custom versions and mvn install) for the included dependencies that I wanted to change.
mr_tristan 1185 days ago [-]
AFAIK, Maven allows you to reference multiple builds like the Gradle composite build feature, but, I don't know of any kind of official dependency substitution mechanism.

I'm very far from a Maven specialist, though.

I suspect with Maven this would require some plugin work.

gozzoo 1187 days ago [-]
Because it fixes some of the problems of Maven, which was the defacto standard in the Java world, and is quite horrible. Gradle is to Maven what svn was to cvs.
pjmlp 1187 days ago [-]
What problems? The only one is XML allergy.
gozzoo 1187 days ago [-]
Actually XML is the smaler problem. Maven forces you to use a predifened structure for your project. The more some project deviates from Maven's assumptions about how it should be organized, the more complicated the pom file becomes. For each medium sized project I've seen it looks completely uncomprehendable. Usually there was only one member in the team who can touch it.
pjmlp 1187 days ago [-]
Which is a very good thing, Gradle is back into Ant cowboy land.

Ever managed to understand Gradle complex files?

There is a full application living there.

gozzoo 1187 days ago [-]
> Ever managed to understand Gradle complex files?

Well, there is a funny annecdote I can share.

In some presentation a guy was showing how you can implemnent some non trivial functionality for a Android app. He was very proud to demonstrate how it can be implemented in just few lines of code. Then he showed casually just for few sec the gradle file for the demo app, which was about 50 lines. We were joking how simple and easy things can be as long you are gradle magician.

twic 1187 days ago [-]
Maven is overly rigid.

Years ago, i worked on a project where it made sense to have two integration test tasks - main tests and some special separate set of tests, i forget why. In Gradle, that's trivial. In Maven, it is impossible. You would have to write a new plugin which duplicates the existing integration test plugin to do it.

Maven runs the stages of the build in a fixed order, defined by the plugin code. If you have a reason to run two stages in a different order, bad luck, that can't be done.

There are tons of things like this.

jdmichal 1187 days ago [-]
I'm pretty sure I've done this before... Maven is generally nothing more than some plugin executions with default configurations bound to specific phases. Both `surefire` and `failsafe` plugins allow you to configure the pattern of files executed (via `includes`). So you should be able to easily configure three executions, all with mutually-exclusive file patterns, one unit-test and two integration-tests. And you can choose whether or not to bind them to phases or run them manually.
blktiger 1187 days ago [-]
Speed - a gradle build computes hashes of all the build steps so it knows when to skip things that don’t need to be run. Spring converted their builds to gradle and were able to cut their builds from an hour to 10 minutes (full-ci bulds). https://spring.io/blog/2020/06/08/migrating-spring-boot-s-bu...
pjmlp 1187 days ago [-]
After getting several GB allocated to the Gradle daemon and using SSDs, I would bet.
jayd16 1187 days ago [-]
I've seen people claim Gradle is language agnostic and Maven isn't. Not sure I agree but its what I'm told...
jdmichal 1187 days ago [-]
Maven defaults to Java, but I'm pretty sure there's compilation plugins for all the JVM languages.
pjmlp 1187 days ago [-]
It has Google's Android team as sponsor that has decided to push it no matter what, which act as if there was no other alternative to Ant available.

Ironically even Google own teams rather use Basel and Soong as the Gradle based builds that the Android team imposes to everyone else using the Android SDK.

stunt 1187 days ago [-]
Both Maven and Gradle suffer from bad user/developer experience. I think it's partly due to the culture and mindset that Java dictates to its ecosystem. The languages determines our experience, and the experience influences the culture.
0x445442 1187 days ago [-]
Yeah, I've never used the combination professionally but Any wity Ivy always struck me as the happy zone. Although, over time, Maven's lack of explicit flow control has bothered me less and less.
larusso 1188 days ago [-]
I work a lot with gradle and had the same problems in the beginning. I overcome most problems by extending gradle through custom plugins and reading a lot of code. The documentation became clearer and clearer. Granted that is obviously not the desired way of learning a tool. Whenever I talk about Gradle and what it’s biggest problems are it’s exactly that. The introduction docs glance over so many aspects. It gets worse if you are completely new to groovy, Java and gradle. The idea to hide everything behind conventions is smart to keep the amount of configuration low. But if one has no idea about these conventions it becomes insanely hard to figure out how this black box works. One thing I have to disagree is the way he describes how to create tasks and that there are multiple ways of doing it. What he shows is the internal gradle API mainly targeted for plugin authors or gradle itself. There is no barrier. Build script authors should stay away from these APIs to stay forwards compatible with future versions. That’s also why gradle has 3 types of documentation: DSL, API and the raw Java Docs. Again nothing that makes the Tool easier to use for beginners.
ashtonkem 1187 days ago [-]
It’s not clear to me that Gradle provides any benefit worth the pain it incurs. Every single Gradle file within $COMPANY seems to be completely distinct, with there being god knows how many ways to do something as simple as compiling a Spring application into a jar. I have no idea why each file is different, and which style is the “right” way, or even what the trade offs are.

It’s when I found myself attaching a debugger to my Gradle session to debug it that I threw up my hands in disgust and said “you know what, give me XML back” and went back to Maven.

pcw888 1188 days ago [-]
I'm surpised to see such negative comments. I really enjoy using it - for a build tool that says a lot.
cmckn 1187 days ago [-]
Accomplishing what I thought were standard tasks with Gradle always felt like fragile hacks. The nature of being a younger build system with more API evolution means there are at least 3 ways to do something, without good explanation, and they often can’t be mixed. Maven feels like a build system that I’m configuring. Gradle feels like a piece of software that I’m developing to build my project.

I will say, Gradles files and console output is usually easier on the eyes. And Maven seems to needlessly re-build things when Gradle does not. Still, I want to fiddle with my project, not my build scripts.

coding123 1187 days ago [-]
If I had to go back to Java tomorrow I would use Gradle hands down. I don't know why the author didn't grok it too well, but for me it has tons of plugins, the scriptability when a plugin is slightly off from what you need, and can be extremely tiny when you just need to build a simple jar.
DrBazza 1187 days ago [-]
Make is still popular (not necessarily loved), because it still largely adheres to the Unix philosophy of doing one thing and one thing only. Anything more complex, make it executable and put it on the path and then call it from make.

Gradle. It's a full programming language. And let's not forget there's a ray tracer in pure cmake doing the rounds.

Being cross-platform without having to drop out of the main build tool isn't necessarily a benefit, and that's part of the reason for it's complexity.

vbezhenar 1188 days ago [-]
When someone does not understand basic tool which is used by most Java developers and that person writes book on that language, that's makes me very surprised. Obviously that person does not have any practical experience with Java, because there's no way you wouldn't stumble onto Gradle or Maven if you're writing real world code in Java.

I guess, that book writing skill is more important in writing good books, than programming skill.

0x445442 1187 days ago [-]
Or, if someone like Bruce Eckel has these observations it may be time to take a step back and listen.
sorokod 1188 days ago [-]
The person is Bruce Eckel, you may want to lookup his credentials.
siva7 1187 days ago [-]
I think you might have issues comprehending what the Author is talking about or the history of maven/gradle.
1188 days ago [-]
deathcap 1187 days ago [-]
I forked a project [1] in 2015 to remove Gradle, and it then quickly subsumed the original project, remaining under active development to this day.

There were other reasons, but de-gradling was one of the main motivations for my fork, and among the first of the major changes I made. The project is an implementation of an API which was discontinued by the original developers, but initially was built using Maven.

After switching from Gradle (which the project switched to in 2014) back to Maven, build times significantly decreased and development became much more pleasant. I found Gradle to be like a speed bump slowing down development, and reverting back to Maven was like a breath of fresh air. Simple, straightforward, and fast. Maven may not be perfect, but it does the job well.

[1] An open source Bukkit server implementation, https://github.com/GlowstoneMC/Glowstone -> http://github.com/GlowstonePlusPlus/GlowstonePlusPlus

therealdrag0 1187 days ago [-]
A lot of the complains here remind me of SBT. Makes me dearly mis Maven. I have had a lot of fights with maven, but at least the XML schemas are straightforward. Also strangely all my teams SBT project configs are full of red-underlines in IntelliJ even though they work fine...
misja111 1187 days ago [-]
+1. SBT is a lot like Gradle but worse. Funny anecdote: SBT originally stood for 'simple build tool'. At some point this was changed to 'Scala build tool' and I can fully understand why ..
habosa 1187 days ago [-]
Gradle was designed on such shaky foundations, namely Groovy. Let's make build files in an unpopular scripting language with limited tooling ... what could go wrong!

I despise it. XML seemed bad when we had Maven but at least it was a markup language.

hiram112 1187 days ago [-]
I've developed Java for a long time. Ant was at least predictable, though left a lot to be desired. Gradle has always been a tangle of DSL that nobody understands, but just gets copied from random examples and Github repos without any understanding of how or why it works.

Maven is still the best build system I've used in any language or ecosystem. It is predictable, stable, has a great community of plugins, and uses XML as it was meant to be used, which is far better than the JSON / DSL monstrosities I see with newer, "cooler" build tools.

devnull255 1186 days ago [-]
As someone tasked with supporting build and release automation in a large company using Gradle, it's never been enough to learn just enough Gradle and Groovy to build any project, because I learned in a relatively short time that there's no end to all the ways something won't build because of what I didn't know about Gradle or Groovy for a particular build scenario. I also didn't expect to see how a gradle process might behave differently in a Jenkins pipeline job from how it behaves when you run a build interactively at the command line. And least but not last, who would have thought how much of a headache it might be figuring out why an IDE with a Gradle plugin built a project just fine while building with Gradle on the command line or in Jenkins failed.

Some of the issues I eventually figured out had to do with missing or incomplete documentation explaining some of the caveats or gotchas of Gradle constructs that one might assume should work the same way. For example, the use of old-style vs new-style code for plugins (buildscript/apply plugin vs. plugin DSL) is not always interchangeable. The new-style works at the top-level of multiproject builds but one must use the old apply plugin form in subprojects.

We've had to use Gradle to build non-java projects as well, which need to use Exec and Copy tasks to build and stage build artifacts. However, the Copy tasks, which are usually dependent on the Exec build tasks, don't always execute after the tasks they are dependent on have completed. Or rather, a Gradle project built on the command line will successfully respect those dependencies while a Jenkins job will output NO-SOURCE in the task execution step.

The problem with Gradle is that it is not as simple as Make, which I had to use in a prior position. However, successful use of Gradle does require significant more investment in learning more than you first think you might need to know about Gradle in a tutorial. It also requires significant investment in learning about Groovy, which will help illuminate how the Gradle DSL works.

grandinj 1187 days ago [-]
And when gradle fails (which is frequent) your debugging abilities are extremely limited.

For example, someone “donated” a gradle build script to an open source project I help maintain. It lasted less than 6 months before it began breaking, not because we changed stuff, but because gradle updates had changed how some things worked and a plug-in stopped working. Now “obviously” the answer is that we should have pegged the version of gradle required to use the script, but (a) I don’t even know if that’s possible (b) the donator definitely didn’t think to do that (c) who changes such things in such a production level tool during a stable release cycle?

Now the gradle people certainly seem decent, in my interactions with them, but I think there is unfortunately a strong case of Stockholm Syndrome going on there.

pbourke 1187 days ago [-]
> Now “obviously” the answer is that we should have pegged the version of gradle required to use the script

My first step with either gradle or maven is to install the wrapper generator, which has this effect. After adding the wrapper you invoke it via ./gradlew or ./mvnw in the project directory. The version of gradle or maven is then pinned until manually updated.

It’s not perfect - especially in terms of IDE support - but it’s crucial for keeping your CLI builds consistent across team members and in automation.

gradle wrapper: https://docs.gradle.org/current/userguide/gradle_wrapper.htm...

maven wrapper: https://github.com/takari/maven-wrapper

wbkang 1188 days ago [-]
Recently I had the pleasure of learning Ruby and then suddenly Gradle started making sense. Things like having more than 1 way to do something, or the magic DSL syntax achieved by using the Ruby unary block syntax - it's a bit more understandable once you learn Ruby.
coffexx 1187 days ago [-]
I know that there are more possibilities now, but back when I was having my first interactions with gradle it was made infinitely harder by groovy and the auto-completion in intellij never working for me.

After years of working with gradle configs, to this day I still don't know groovy or gradle as intimately as I know other things I've spent as much time with. I wish I did, but I just don't.

I can explain to you what our configs do, but if you asked me to make it do something else it'd be straight to google for examples to mangle, a metric tonne of trial and error, and lookups for simple groovy syntax that I keep forgetting in-between the actual work I want to do.

joshum97 1187 days ago [-]
Back in college, I had a summer research internship where the previous year, the interns tried to migrate a large Java code base to Gradle and left it in a broken state. Knowing little more than the Java language at the time, I spent about a month getting Gradle to build it correctly. It was incredibly frustrating not to be able to understand what Gradle was actually doing, instead only copying random lines from example configurations. Almost every time I would fix some errors, new ones would appear with no way to know how close I was to the end.

It’s nice to know that I wasn’t the only one who struggled!

ohgodplsno 1187 days ago [-]
Ohohohoh Gradle. Making Android software turns this into a form of Stockholm syndrome, where you just get used to it. (And as some colleagues go, even pretend to like it. That is, until the next time it does something utterly stupid.) I have spent half a day trying to get a set of tasks to run depending on files that were changed since the original commit that started the git branch. This ought to be simple. Get all the files changed since the start, figure out their modules, figure out modules that have a dependency on those, run the tests only on those modules!

In Gradle-insanity land, you'll need a whole plugin for that. That you have to register in the buildScript.classpath closure. Wait, is it also in the plugins block of the root file ? But maybe also the modules themselves, as an apply. Or is it a plugin block too ? Oh wait, you're using buildSrc ? Well that's a whole other problem. Don't forget you need a basic .properties file in META-INF that just gives out the plugin's name so it can discover it through reflection instead of having a proper API to do so.

You would think the Kotlin scripts instead would fix it, but oh no. Not content with adding a solid 10 seconds every time gradle builds your model (which it rebuilds... Kind of when it feels like it), half of the pretended benefits of it simply do not exist. Almost all the documentation online is for the Groovy scripts, which is, obviously, incompatible with the .kts scripts. And I'm not just talking about syntax, no! Entire APIs are different. Setting a flag like `enabled = true` in groovy ? Have fun, we've added an isEnabled instead, because why not. Registering tasks? Wait, hold on, we've added new solutions in Kotlin! The existing APIs weren't batshit insane already, so let's abuse kotlin delegation. Kotlin's `by lazy {}` is nice and simple, why do we not make your write `val taskName by creating { }` ? And through some horrible logic, the name of your variable is what is exposed to Gradle. Or abusing the same thing for you to read things from a .properties file, because what is more clear than `val isFlagEnabled by project` ? Isn't it obvious that it's going to read a .properties file ? Not the values given through the -P flag when building though, because that would actually make sense. But wait! Let the gradle website explain to you the logic of lazy registered tasks. Why do you need these, you ask? Because Gradle is so absolutely terrible that having a large amount of tasks means they all get created when your daemon starts. Or when it performs anything.

Oh, right, you need a daemon because why would you not need to eat 1GB of RAM just to not have horrible startup times for a build tool? Load all the tasks, at all the times! Add a development flavor to all your modules ? lol you've just doubled your amount of tasks.

Let's add to this of course the absolute insanity that are the Android build tools. Making those work in a Makefile would be hell. aapt2, dexing... An absolute abomination of an amalgamation of bad tools (lol aapt2 silently ignoring your vector drawable overrides because it doesn't like the android:fillType attribute.) and horrible performance (aapt2 taking over a minute to process files on a medium sized project, or kapt (but that's a Kotlin problem) being awful in terms of performance.) All this to output a glorified .zip in the end. Or whatever new format's Google drug addled minds have invented to lock you in further to the Play Store and to make you give them your signing keys.

I am not a fan of Gradle. Or Android's build tools.

netvl 1183 days ago [-]
While Gradle does have a lot of issues, some of the things you mentioned are not correct.

> Don't forget you need a basic .properties file in META-INF that just gives out the plugin's name so it can discover it through reflection instead of having a proper API to do so.

Not really clear what do you mean, but declaring plugin names should not be done in properties, Gradle has syntax for declaring plugin ids inside its build config. If the plugin author haven’t used it, well, that’s on their conscience. Plugin users should never ever declare anything plugin-related in meta-inf.

> And through some horrible logic, the name of your variable is what is exposed to Gradle.

This is a feature of Kotlin as a language - in it, delegates know the names of the properties they are used for. `lazy` is just the simplest use of the delegates feature, which happens not to care about property names.

> Isn't it obvious that it's going to read a .properties file ? Not the values given through the -P flag when building though, because that would actually make sense.

This is simply untrue. Extracting properties this way most certainly will read them from .properties files and from all other sources of properties on a project, including the -P arguments.

Gradle does have a lot of issues, I can talk about them for hours (there are really nasty ones where there are no non-awful workarounds, for example, the built-in `tarTree` does not support symlinks in TAR archives, and there is no way to rebase the archive contents when extracting, i.e. to specify which directory of the archive to extract from, and these issues are very unlikely to be fixed, and these two are just the surface), but too many of your examples are somewhat wrong.

pjmlp 1187 days ago [-]
Android is very special indeed.

Not only has the Android team managed to push Gradle no matter what, they sell Android Java as the real Java.

They purposely use Android Java samples, with its half broken support for modern Java, as means to sell Kotlin in the platform, and when one points out the real differences, radio silence.

huodon 1187 days ago [-]
Kotlin is great, gradle has improved a lot in the past two years, especially since it supports .kts scripts, but it's still shit. Now, I'm very happy write rust
moonbug 1187 days ago [-]
Gradle's purpose is to make cmake seem palatable.
pabl0rg 1187 days ago [-]
Cedric Beust made a great alternative to Gradle called Kobalt. Unfortunately, Jetbrains went with Gradle — probably in order to associate Kotlin with a known entity.

Now we are stuck in a terrible situation where step 1 of any java/kotlin project is unpleasant because you have to write a long XML file (Maven) or a magical and incomprehensible build file in groovy/kts (Gradle).

nucatus 1187 days ago [-]
all you need to know about gradle is that there are two phases: configuration and execution. Everything else are details :)
twic 1187 days ago [-]
It took me months of working with Gradle before this clicked, but once it did, everything seemed far simpler.
tn1 1187 days ago [-]
One thing that helped me a lot is to decompile the compiled build script classes with e.g. JADX [1] to see how my code gets turned into Java, since that is what I already knew.

That was my "Ah-ha!" moment in using Gradle.

[1] https://github.com/skylot/jadx

cdaringe 1187 days ago [-]
Strong agreement with the author's points. https://cdaringe.github.io/rad/#why-not-my-favorite-build-to... is my less verbose compaction of some of these claims, albeit in tabular format
franzwong 1187 days ago [-]
About point 6, even you don't execute task "a", gradle will still execute the configuration part of it.
kimi 1187 days ago [-]
I was rather happy with Ant; its tasks were usually 100% spot-on, but scripting them was a PITA and there was no downloading of Jars.

Gradle was easy to start with, but it hides way too many things that end up biting you in the back (sourceSets, anyone?) and those build.gradle files gets way too big.

Too bad there is not much choice.

ma01zm 1187 days ago [-]
In my experience Gradle offers great experience only if you understand Groovy closures' "owner" and "delegate" concepts and how Groovy runtime metaprogramming model works. Otherwise you are lost in its magic methods and conventions.
irateswami 1187 days ago [-]
I'm so glad I don't have to deal with Java and it's ecosystem anymore.
pjmlp 1187 days ago [-]
Luckily it is possible to be happy in Java ecosystem without touching anything Gradle related, unless one needs to deal with Android.

That is my path to happiness, Netbeans | Eclipse + Maven.

mateuszf 1187 days ago [-]
Intellij + Maven here, also very happy with it
irateswami 1184 days ago [-]
Maven is worse than Gradle.
lazulicurio 1187 days ago [-]
Reading this, I'm reminded in many (not good) ways of the .NET build system. Where trivial projects look simple, but once you pull back the curtains there are horrors to behold.
avmich 1187 days ago [-]
I've found similar problems with all by-convention platforms, like Django and Rails.
npstr 1187 days ago [-]
Gradle was really not that great back around v3. It was using a ton of my ram, and required frequent cleaning, it was just as bad as Maven in that regard. I think it has improved by lot since then - or maybe thats stockholm syndrome speaking ;) or maybe it's because I stopped doing Android stuff.

In any case, one of the large problems remaining is the bad discovery of stuff-it-can-do-and-how-to-configure-that, and making it too easy for devs to write imperative code when they should be staying declarative.

Also, I don't very much like how complicated some of the newer features are to use, and how much weird magic they require to be turned on / configured.

Another thing I absolutely hate is how it splatters the build scripts into half a dozen files. Personally, even for large monorepos or multi-module builds, I prefer to have one huge script file + plugins.

The strengths of Gradle, if the scripts are written properly, however are very clear to me:

- Task avoidance and therefore crazy good build speedup ofc that requires tasks to be well defined, ideally the whole project to be split up into smaller modules, and each of the build tasks being deterministic. unfortunately many devs don't understand how to do this, and some of the more exotic build steps in monorepos might not be properly deterministic (looking at you, frontend build tools)

- It can be wrapped around other langs and exotic build steps for monorepos. E.g. you can first fire up a database in a container, and run your migrations against that, then use the resulting schema to generate your database entities. In parallel, you might want to run some protobuf generation, that is then used by e.g. a Java backend and a JS frontend built that's actually using yarn in the background. There are plugins available that will wrap the yarn scripts to the Gradle lifecycles. The output of the frontend can be used to be included in the static files of your jar, which you can fire up for tests with browsers running in docker containers and doing e2e tests from the Java BE code, so you can do amazing test setups. Gradle can do all of that, with incremental builds / cached in- and outputs. Imagine having to keep all these steps in your head and running them on-demand when you think its necessary. Or running them every time no matter what (looking at you, Maven) Gradle allows me to write down all of these steps as individual, declarative tasks, making use of a vast and high-quality plugin ecosystem. Then wire up their order, again, declaratively. Once that is accomplished, I can turn off my brain and focus on building code and don't have to know which parts needs to run when exactly.

When I joined one of my previous teams, they were using a rube goldberg machine of Bash, AWK, Python scripts with a lot of JSON slurper and AWK sprinkled in to manage multiple modules in different repos into a monorepo-like state with individual releasing and versioning. With Gradle, that was much easier to accomplish: The dependency resolution rules could be written as simple code with easy and well defined conditionals, instead of manipulation of Maven pom files during random build steps. Also introspection into the build dependencies allowed an easy way to find out which projects dependend in which other ones. (Now was doing all of this a good idea in the first place? probably not :) but they certainly didnt allow themselves to be stopped by Mavens inflexibility, and the resulting horror of a build pipeline was certainly worse then writing all of that in Gradle)

In think, in the end, for small projects, Gradle isn't that benefitial. Maven can accomplish simple builds with no special rules and no necessary task avoidance just as well as Gradle, if not better due to the restrictions. But once you need to build something bigger (did someone say Enterprise?), Gradle starts shining - as long as you tread carefully.

motoboi 1188 days ago [-]
One thing caught my attention on this site: where is the scrollbar (safari iPhone)?
jlund-molfese 1188 days ago [-]
It's still there, it's just white instead of grey. Which works fine with the header, but disappears as you scroll.
fctorial 1187 days ago [-]
build.sh ftw.
draw_down 1188 days ago [-]
> Commands are indented (horribly, by tabs, because make was created in the early days of Unix when they were still obsessed with saving bytes)

See, to me this is exactly not simple (a reference to make’s “simplicity” appears shortly after this). It’s a form of complexity because every time something is wrong with the build, this is one of the things I will need to check.

Moving the complexity elsewhere so that it becomes someone else’s problem just does not work for me as a definition of simplicity. You see this pattern a lot. Golang is pretty much an entire object lesson in this dynamic. Everything is “simple”, aka, “your problem”.

alisausaaaa 1187 days ago [-]
Wanna have hot-lovin' conversations? You’re on the right way! - https://adultlove.life
Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact
Rendered at 03:51:55 GMT+0000 (Coordinated Universal Time) with Vercel.