Pages

Wednesday, August 26, 2015

A Maven Plugin Developer's Thoughts on Gradle

Introduction
I use both Gradle and Maven, and I maintain a plugin for working with Groovy (GMavenPlus). I thought this gave me a somewhat unique perspective. I know this comparison is far from exhaustive, but I wanted to share some thoughts I'd jotted down.

When I first heard about Gradle, I was fairly dubious. Maven had been around for about 6 years at that point and they were making some rather large promises. Although I was intrigued, my reaction was "come back to me when you have a non-RC 1.0 release". Since then, they've had several stable releases and about 6 years of their own maturing.

What I like about Gradle
  • They kept the best parts of Maven
    • The lifecycle concept
    • The standardized project layout
    • The dependency management concept
  • Very concise syntax.  It's an amazing feeling to be able to do a standard Java build with a single line of code.
  • Keeps the simple things simple, while allowing you to use the power of Groovy and Ant if you need something non-standard.
  • Gradle Wrapper (gradlew) is a nice way to help keep builds reproducible
  • Application Plugin (Maven has ways to do this, but having it in a plugin is convenient)
  • Much more flexible than Maven (in nearly every way -- dependency management, lifecycle customization, custom tasks, etc)
  • Can put environment config and dev helper scripts right into the build as tasks instead of separate script files
  • HTML test report is nicer than Surefire's, and I now prefer it over console text
  • Has a test runtime scope (unlike Maven)
  • implementation vs api scopes are brilliant
  • Can lock transitive dependency versions for superior build reproducibility
  • Can share dependency versions between projects (called platforms)
What I don't like about Gradle
  • Allowing people to do custom things so easily might lead to the tangled mess that was Ant. There's already some pretty crazy builds out there (though arguably this isn't much riskier than what you could do with AntRun or GMavenPlus).
  • Because it's Groovy instead of XML, you don't answers get as helpful hints from your IDE.
  • Can't include multiple source directories each with their own includes/excludes patterns (they have a TODO for this).
  • Groovy building Groovy can sometimes be problematic
  • No equivalent of mvn install, which makes end-to-end testing of plugins clunkier (though they now offer TestKit that should help with this)
  • Some areas might be perceived as being less mature
  • No isolation of plugin dependencies -- they all run on the same classpath (unlike Maven), unless the author took the time to do custom classloader work, which most don't.
  • Plugins use whatever repository is declared instead of project repositories. So if you don't want to use JCenter, for example, but a plugin you use does, then you end up using that repository too (see #10376).
Notable differences from Maven
  • In Gradle, default target bytecode version is version of JDK, whereas in Maven default is currently 1.5
  • Gradle's commands are case-insensitive (something I actually really like)
  • Gradle doesn't compile tests unless specifically asked for (gradle classes != mvn compile, gradle testClasses == mvn compile) (not really a positive or negative, just something to be aware of)
  • Gradle will stop testing after the first module to have a test failure. You have to use the --continue argument to continue on to the other modules the way Maven does. I kinda wish this was the default.
What I like About Maven
  • Maven's inflexibility has largely proven very successful in preventing pointless deviation from the established pattern.
  • The lifecycle concept
  • The standardized project layout
  • The dependency management concept
What I don't like About Maven
  • XML is pretty cumbersome (though Polyglot for Maven isn't completely dead). This leads to out of control copy-and-pasting of POMs, with dependencies that have no business being there.
  • Convention over configuration doesn't go far enough (ideally, a basic Java project should be just a few lines, like it is in Gradle)
  • No ability to specify ranges of versions that are acceptable for transitive resolution (I haven't used it much -- but it's a really cool feature)
  • No TestRuntime scope
  • No Maven Wrapper equivalent of gradlew (though there is an unofficial project)
How Gradle has improved Maven
It took a while, but you can finally opt out of transitive dependencies. I think Gradle (and Ivy) earned a good deal of credit for the pressure to offer this feature.

Conclusion?
I honestly think despite there being some areas Gradle can be improved, it's generally the better choice for most projects.  There are circumstances where this isn't the case (like if you're building a Maven plugin). But in most cases, I think Gradle's pros outweigh the cons. But if you prefer Maven (or your CTO/CIO/Architect is making the choice for you), rest assured that despite my recommendation, I'm committed to maintaining GMavenPlus for the indefinite future so that the choice is always yours to make.

More Resources

Update (2021): I've added some new bullet points. Some of the newer features (Gradle 5 and 6 especially) add some pretty compelling features that might tip the scales for you, depending on your use case.

Monday, August 10, 2015

Forcing Windows 10 Upgrade

Want to get your free upgrade to Windows 10, but don't want to wait your turn? Run this reg file
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\OSUpgrade]
"AllowOSUpgrade"=dword:0x00000001
Then open the command prompt as an administrator and run
wuauclt.exe /updatenow