When I first started using Java, Maven didn't exist. And by that, I mean Maven 1.0 Beta 2 - the oldest entry on the Apache Maven Release History page - hadn't yet been released. Ant 1.1 had been released a few months earlier, but I never used that either. Back then, it was doing the commands by hand or else using Make.
Fast forward a bit to the first time I used Java outside of Uni, and Maven 2.0.4 now existed, and the first project that I worked on used it. And it was really painful. You had to write lots of complicated XML, and locate your dependencies in the Maven Repository - or else manually upload them to your own web server with the correct metadata files, and all manner of complicated things just to get something to build. You didn't even get freedom to put your files where you wanted them - it dictated where they should go. This was drastically different to anything I'd been used to before, and it was awful. But I persevered, and I grew to accept it and get used to it's idiosyncrasies.
Forward again, and we've got a plethora of options now. Maven is still there, going strong, but we've got much improved versions of Ant, as well as Gradle, SBT, Leiningen, and probably others. And yet, these days my personal preference is for Maven over all of these.
There are two reasons for this:
The obvious one is the way they are configured. Ant is given a list of instructions to execute. Gradle, SBT, Leiningen, etc are given scripts written in actual code to configure the build system. Maven is given a simple document that describes the build. There's nothing magic about the XML. It doesn't do anything clever. There's no coding support built in to it to twist it to your own ends. It's just a document. And, as such, all Maven configurations work the sameÂ¹. You can take anyone elses pom.xml file, read it and know what it's going to do. You don't have to ponder what this clever bit of Groovy or Scala is going to do to the end result.
However, this isn't the big one for me. The biggest one is Maturity. Maven is now the one that everyone has to live up to. As such, if you want to do something unusual, odds are Maven will have support for it with less efforts and more examples. You can, of course, make the others do anything because of the fact that they are scriptable. You can do anything with them. But sometimes it's an awful lot of effort to achieve it.
As an example - one that I use a lot because it's so ridiculous. When I first started playing with Gradle, there was no support for the "provided" scope. There was no easy way to build an application that had compile time dependencies on a Jar file that it shouldn't be bundled with - such as the Servlets API. There were ways of achieving it, by writing a dozen or so lines of Groovy in your build script, using features that were poorly documented if at all, against an API that was changing every release, but it was painful and brittle.
Odds are - I'll end up having to move to Gradle instead, and I'll get used to it and it'll be fine. An awful lot of projects are adopting Gradle over Maven instead these days, because - to be fair - it does a very good job of making simple builds very simple. But there'll always be a place for Maven with me.
1) With the caveat that there's so much in there, almost certainly people use different subsets of the options.