Maven is declaritive. IMO it's the best of the Java build tools. Gradle is not declaritive, unless it's changed since the last time I looked at it.
Maven has problems. It's not perfect by any means. I would love to see it rewritten, get rid of the verbose XML which makes viewing dependencies hard and fix the craziness around generated code.
Honestly, I'm tempted to make a fork of Cargo for Java, it's nearly perfect. But this goes against my opinion that build tools should be in the same language as the code they build.
Generally speaking gradle plugins take a very declarative syntax. Yes, it's easy to write non-declarative builds in Gradle, but that's what is awesome about it. Start with fully declarative builds, then add in non-declarative tasks if/when you need them.
My experience generally mirrors what you state. I transitioned a fairly significant code base & complex deployment process from a mix of maven and ant to gradle. I found Gradle's 'opinionated but flexible' approach to strike a good balance. It's definitely more complex, at least in our build, simply because of the size and scope of our project which has a wide variety of inter-dependencies which makes for a very complex task graph to build. But, the parallelism results in a far faster build/deploy cycle which is a worthy tradeoff.
We initially planned on going full maven, but its strict lifecycle and plugin system was simply too rigid. Beyond that, XML makes for some verbose configuration for even simple things.
We ended up developing our own Gradle plugins in static groovy and java, but it's very easy to do small bits/tests based on scripts and migrate functionality into specific-purpose plugins. Using Gradle was especially fortuitous when it came time to implement new areas of the product that relied on npm/node and webpack for front-end resource assembly.
Gradle hasn't been without its own minor growing pains (early lack of tooling support, rapid version changes), and it's certainly possible to create a big complex mess if you script everything ala ant -- but it's also possible to create very nicely defined DSLs and build systems that are expressive in use. Our onboarding got significantly easier in switching to gradle from maven+ant, and teams can now easily make minor tweaks for their build needs without having to learn maven's plugin architecture.
Builds, just like anything else, benefit from some best practices. I have no issue with Maven, but I won't start a new project with it.
> Honestly, I'm tempted to make a fork of Cargo for Java, it's nearly perfect. But this goes against my opinion that build tools should be in the same language as the code they build.
The problem with that is that it doesn't work with slow / compiled languages. That's the worse thing about Maven (tied with the insane unnecessary complexity of the plugin architecture). The dev cycle for trying out a new plugin is atrocious. Compare that to editing a local copy of a Python, Ruby, or Groovy script.
Oddly enough, my experience was quite opposite of yours, but it sounds like the scope of your system might be a little larger than ours.
The key to cleanliness (from my perspective) was to create versioned plugins for any build functionality that was required in more than one subproject. This simple rule prevents spaghetti task dependencies and maintains sanity for everyone. It gives us the best of both worlds -- a little bit of flexibility when needed for one-offs, but then a well defined DSL via plugins for anything that is done more frequently.
I tend to agree. Gradle can be nice if you have a talented team, but in the hand of mediocre developers, its opening the box of pandora.
I have seen build files you people wouldn't believe. And unfortunately, all that code will not be lost in time like tears in rain.
Maven in general is widely workable in almost any of the major Java IDE's out there, even with all the work Jetbrains has put into Gradle support it's still not up to par with what they've done for Maven (and considering how hard it is to introspect Gradle builds it may never be).
I feel like most people just hate Maven because of XML, if that's your problem then just use YAML (you can do that now). The other group seems to dislike that everything in Maven is done with plugins; I can understand this, there's no easy escape-hatch to do something no-declarative, but writing a Mojo isn't that much harder than putting some random task in your Gradle build.
> I feel like most people just hate Maven because of XML
I see this a lot. I definitely don't want to go back to the days of J2EE/Hibernate XML hell, but there are places where XML isn't terrible, and Maven feels like one of them - it is easier to figure out context when in bigger files (as opposed to JSON and the like), and it is nice that you can get very easy/quick feedback about the structure of the document via XSD. But when I ask people why they hate Maven, they give some handy-wavy "but XML..." argument about it.
I understand some of the more valid knocks against Maven, and there has been a time or two where I've been frustrated with it, but most of the time I used it (and I used it over a period of 8 years or so), I've been happy with it. I know that tools like Gradle and SBT allow you to do more, but I've always come away frustrated when using those tools.
* custom tasks AND up-to-date checks for them (for when you invariably need special tasks like custom generated code, filtering only some resources in a certain way, calling other build systems like grunt/gulp, etc)
* up-to-date checks in general
* better task exclusions
* better dependency version resolution abilities, including custom strategies
* groovy syntax
Things I think maven does better that matter to me:
* classifier handling (it is really frustrating gradle still has a lot of messed up handling of them)
* way less magic is possible in the buildscript - makes it easier to trace through
End result: I could never go back to maven, every single project I've worked on has desired custom tasks and maven just makes it painful every step of the way. The only thing I worry about in gradle is making things easy to understand so someone else can follow behind - can't use too much magic.
What's the opposition to simply writing a Maven plugin versus tossing a bunch of extra logic in your build configuration? I understand there's some extra ceremony around it (you have to write a new project, publish the plugin to a maven repo or install it in your local .m2) - but I find it's a much cleaner and reusable solution than having a bunch of custom tasks dangling around build scripts.
The custom tasks are never reusable - they are specific to that one build. If they ARE reusable they become gradle plugins, same as in maven.
Effort of banging out a custom task to make a tar in a particular way and get it published: gradle=a few lines of groovy, maven=a full plugin in java?
To be fair my maven experience is the lowest of all (between gradle/ant/make/maven), but I was being honest in that I would never want to go back to maven (or ant) - I get more things done faster in gradle.
What MrBuddyCasino mentioned about mediocre teams though, that is a real risk. I'd nominate one or two skilled people to create and maintain it, but be sure to crosstrain and use comments liberally. The initial learning curve on gradle can be brutal for complex projects.
I'm kind of surprised you found Gradle slow. I did a fair amount of testing when we evaluated Maven vs Gradle for redoing our build, and I found Gradle to be significantly faster, even when running without the Daemon. Maven did not seem to have true parallelism at the time, I wonder if that has changed? Gradles task graph, though more complex, seemed far faster due to its ability to run non-inter-dependent tasks concurrently.
I never liked the way Maven built projects - it just seemed like overkill for simple things. I tended to use hand-written Ant builds backed by Ivy for dependencies. Then again, I also build odd outputs, like self-executing jars.
Except when you're using multiple Spring libraries with XML config and are running on servers without access to the general internet.
I tried all the listed tricks to get the schemas into the shaded jar and none of them worked. So now I have to put big fat warnings in my README.md files that "yes, there's a bunch of errors on startup, and yes, there's a 60 second delay, but you can ignore it".
Spring Boot? I guess it doesn't produce a shaded jar, but I find the custom classloader w/embedded dependency jars to have fewer issues than shaded jars (of course, one disadvantage is you can't run proguard, if that's something you do).
The only thing that will survive from the Maven era is the directory structure. It's the default structure in SBT and many other built tools. It's a little verbose, but it does make sense and I've learned to embrace it.
Maven is terrible. Give SBT or Gradle and try and you'll see just how terrible Maven is. SBT still has its issues (OMG why is everything a macro!), but I still prefer it to trying to build anything in Maven.
I have exactly the opposite view. Until very recently modules in sbt required a scala Build file. There is not one single file where you have a view of everything - plugins, build properties, sbt file, and sbt scala file. I prefer maven over SBT any time of the day. Have not tried Gradle, so cant comment
For simple things, I love the way maven builds projects.
If I want to make a "scripty" Java program I can generate a project file from the archetype which sets me up with dependencies I need and an easy way to write tests.
Maven solves the problem Ivy is designed to solve, but it also solves the build problem. You may just think of it as a "build tool", but I think of it as a "build and dependency management tool". There are build systems out there that don't solve dependency management (obviously Ant is one of them, there is also SBT, Pants, Buck, and probably more I'm not familiar with). Ivy is a component of creating hygienic builds for these build tools, and it would be very sad if it disappeared.
just today i replaced maven with ivy + a few scripts to build a java project i'm working on. it is so much better. ivy just for downloading the dependencies, the scripts for building and running. the scripts are easier to read and understand. the builds run much faster (incremental builds + starting go from 25s to 5s).
i appreciate maven's downloading of dependencies. but ivy does that too, only better: it generates a classpath list of the deps for me, to use when building and running.
maven does also handle builds, but it does so poorly. it is huge, overcomplex, slow. things that are easy on the command-line, are hard/weird to do with a maven pom.xml. the phases, lifecycles, goals, encoded in their xml format. so much stuff for so little gain. i've recently spent hours figuring out how to get my javadoc+doclet invocation in a format that maven understood (running it on a command-line was relatively easy; to get it to work in maven easily i ended up committing a compiled version of the doclet).
it baffles me maven is used so widely. i think java developers have a high tolerance (and often even love for) the unnecessarily complicated... that, or they haven't seen and can't imagine better ways.
Doesn't sbt still use Ivy under the covers? I know Gradle used to but maybe not anymore. In any event, Ant is still an active project and Ivy is it's dep system.
I had to dig into gradle dependency resolution once I think I did see it falling back to ivy if it couldn't find it in the maven repo, or if the workstation had a config file for ivy but not maven. Kind of fuzzy on the details at this point.
sbt uses Ivy, and pretty obviously too. It did recently switch to Maven Aether instead of Ivy for Maven repos.
IMO, Ivy is one of the worst parts of sbt. Take a build system with great ideas, like immutable state and parallel by default, and insert a complex single-threaded dependency resolution library.
We see Ivy as a widely used component.
We use archiving some components to
recalibrate our focus. I don't think
that we want to archive Ivy in the near
future. Instead we try to push Ivy.
If you want to help with Ivy, you're welcome.
"It's already a challenge to stick with
Ivy build system itself given the lack of
fixes/releases/responses." What are the
problems you think are resolved with new
Ivy releases?
Jan
That's a nice boilerplate comment that could be applied to any open source project, but the reality is that Ivy is essentially abandonware.
At one point recently, I did a search and couldn't find any committer activity of any kind (code, mailing list messages, JIRA updates) for the better part of a year. And it's not like the project is "stable" or "complete" either -- users are constantly making posts about serious bugs that go unanswered, because there's nobody active who has the knowledge to investigate or fix them. (I've run into a couple of these myself.)
EDIT: Just took another look to see if anything had changed. The good news is that a couple of very minor bugfixes were committed in November, amounting to a grand total of 14 lines of code changed. There have been no other commits in the past 12 months, and the last time one of the committers responded to a question on the mailing list was March 2015.
Irrelevant aside: my eyes! I was astounded to see plain text twisted up so badly. It literally made my eyes water. Was that some artful/ironic attempt to reproduce ink-bleeding typewritten pages? *View/Page Style/No Style" was the only way I could tolerate this.
I was a long time user many many years ago of Ivy. I will say Ivy is one of the most sophisticated dependency management libraries/tools. It has things I have yet to see other dependency managers do (and probably should not do anyway).
The flexibility was sort of good for our enterprise code base that was still using Ant but over all it was just way too complicated (this was in part because it was not integrated with any particularly build system at the time ~ 8 or so years ago).
I have come to the conclusion that with proper parent poms and enforcer plugins (particularly dependency convergence) you can generally get Maven to do a fairly good job.
The only thing I can't decide is if Maven (and Ivy for that matter) should have lock files. I have some ambivalence to lock files (ie a file that gets auto generated and that you check in). Bundler and cargo do it as well as a netflix gradle plugin.
I deal with the lack of a lock file by using maven parent poms, sonatype, enforcer plugins, and version plugins.
44 comments
[ 4.3 ms ] story [ 114 ms ] threadMaven has problems. It's not perfect by any means. I would love to see it rewritten, get rid of the verbose XML which makes viewing dependencies hard and fix the craziness around generated code.
Honestly, I'm tempted to make a fork of Cargo for Java, it's nearly perfect. But this goes against my opinion that build tools should be in the same language as the code they build.
We initially planned on going full maven, but its strict lifecycle and plugin system was simply too rigid. Beyond that, XML makes for some verbose configuration for even simple things.
We ended up developing our own Gradle plugins in static groovy and java, but it's very easy to do small bits/tests based on scripts and migrate functionality into specific-purpose plugins. Using Gradle was especially fortuitous when it came time to implement new areas of the product that relied on npm/node and webpack for front-end resource assembly.
Gradle hasn't been without its own minor growing pains (early lack of tooling support, rapid version changes), and it's certainly possible to create a big complex mess if you script everything ala ant -- but it's also possible to create very nicely defined DSLs and build systems that are expressive in use. Our onboarding got significantly easier in switching to gradle from maven+ant, and teams can now easily make minor tweaks for their build needs without having to learn maven's plugin architecture.
Builds, just like anything else, benefit from some best practices. I have no issue with Maven, but I won't start a new project with it.
The problem with that is that it doesn't work with slow / compiled languages. That's the worse thing about Maven (tied with the insane unnecessary complexity of the plugin architecture). The dev cycle for trying out a new plugin is atrocious. Compare that to editing a local copy of a Python, Ruby, or Groovy script.
A chaos in a three site distributed system, with around 300 developers at its peak.
In this regard, Gradle is even worse than Ant in what concerns keeping a build infrastructure clean.
The key to cleanliness (from my perspective) was to create versioned plugins for any build functionality that was required in more than one subproject. This simple rule prevents spaghetti task dependencies and maintains sanity for everyone. It gives us the best of both worlds -- a little bit of flexibility when needed for one-offs, but then a well defined DSL via plugins for anything that is done more frequently.
Also Maven is a project format in NetBeans. Just need to open it and its goals are mapped to IDE actions.
I feel like most people just hate Maven because of XML, if that's your problem then just use YAML (you can do that now). The other group seems to dislike that everything in Maven is done with plugins; I can understand this, there's no easy escape-hatch to do something no-declarative, but writing a Mojo isn't that much harder than putting some random task in your Gradle build.
I see this a lot. I definitely don't want to go back to the days of J2EE/Hibernate XML hell, but there are places where XML isn't terrible, and Maven feels like one of them - it is easier to figure out context when in bigger files (as opposed to JSON and the like), and it is nice that you can get very easy/quick feedback about the structure of the document via XSD. But when I ask people why they hate Maven, they give some handy-wavy "but XML..." argument about it.
I understand some of the more valid knocks against Maven, and there has been a time or two where I've been frustrated with it, but most of the time I used it (and I used it over a period of 8 years or so), I've been happy with it. I know that tools like Gradle and SBT allow you to do more, but I've always come away frustrated when using those tools.
* custom tasks AND up-to-date checks for them (for when you invariably need special tasks like custom generated code, filtering only some resources in a certain way, calling other build systems like grunt/gulp, etc)
* up-to-date checks in general
* better task exclusions
* better dependency version resolution abilities, including custom strategies
* groovy syntax
Things I think maven does better that matter to me:
* classifier handling (it is really frustrating gradle still has a lot of messed up handling of them)
* way less magic is possible in the buildscript - makes it easier to trace through
End result: I could never go back to maven, every single project I've worked on has desired custom tasks and maven just makes it painful every step of the way. The only thing I worry about in gradle is making things easy to understand so someone else can follow behind - can't use too much magic.
Effort of banging out a custom task to make a tar in a particular way and get it published: gradle=a few lines of groovy, maven=a full plugin in java?
To be fair my maven experience is the lowest of all (between gradle/ant/make/maven), but I was being honest in that I would never want to go back to maven (or ant) - I get more things done faster in gradle.
What MrBuddyCasino mentioned about mediocre teams though, that is a real risk. I'd nominate one or two skilled people to create and maintain it, but be sure to crosstrain and use comments liberally. The initial learning curve on gradle can be brutal for complex projects.
I tried all the listed tricks to get the schemas into the shaded jar and none of them worked. So now I have to put big fat warnings in my README.md files that "yes, there's a bunch of errors on startup, and yes, there's a 60 second delay, but you can ignore it".
Maven is terrible. Give SBT or Gradle and try and you'll see just how terrible Maven is. SBT still has its issues (OMG why is everything a macro!), but I still prefer it to trying to build anything in Maven.
If I want to make a "scripty" Java program I can generate a project file from the archetype which sets me up with dependencies I need and an easy way to write tests.
Maven solves the problem Ivy is designed to solve, but it also solves the build problem. You may just think of it as a "build tool", but I think of it as a "build and dependency management tool". There are build systems out there that don't solve dependency management (obviously Ant is one of them, there is also SBT, Pants, Buck, and probably more I'm not familiar with). Ivy is a component of creating hygienic builds for these build tools, and it would be very sad if it disappeared.
i appreciate maven's downloading of dependencies. but ivy does that too, only better: it generates a classpath list of the deps for me, to use when building and running.
maven does also handle builds, but it does so poorly. it is huge, overcomplex, slow. things that are easy on the command-line, are hard/weird to do with a maven pom.xml. the phases, lifecycles, goals, encoded in their xml format. so much stuff for so little gain. i've recently spent hours figuring out how to get my javadoc+doclet invocation in a format that maven understood (running it on a command-line was relatively easy; to get it to work in maven easily i ended up committing a compiled version of the doclet).
it baffles me maven is used so widely. i think java developers have a high tolerance (and often even love for) the unnecessarily complicated... that, or they haven't seen and can't imagine better ways.
SBT is quite a used one too.
IMO, Ivy is one of the worst parts of sbt. Take a build system with great ideas, like immutable state and parallel by default, and insert a complex single-threaded dependency resolution library.
---
---At one point recently, I did a search and couldn't find any committer activity of any kind (code, mailing list messages, JIRA updates) for the better part of a year. And it's not like the project is "stable" or "complete" either -- users are constantly making posts about serious bugs that go unanswered, because there's nobody active who has the knowledge to investigate or fix them. (I've run into a couple of these myself.)
EDIT: Just took another look to see if anything had changed. The good news is that a couple of very minor bugfixes were committed in November, amounting to a grand total of 14 lines of code changed. There have been no other commits in the past 12 months, and the last time one of the committers responded to a question on the mailing list was March 2015.
The flexibility was sort of good for our enterprise code base that was still using Ant but over all it was just way too complicated (this was in part because it was not integrated with any particularly build system at the time ~ 8 or so years ago).
I have come to the conclusion that with proper parent poms and enforcer plugins (particularly dependency convergence) you can generally get Maven to do a fairly good job.
The only thing I can't decide is if Maven (and Ivy for that matter) should have lock files. I have some ambivalence to lock files (ie a file that gets auto generated and that you check in). Bundler and cargo do it as well as a netflix gradle plugin.
I deal with the lack of a lock file by using maven parent poms, sonatype, enforcer plugins, and version plugins.
Are there any good cross-platform alternatives for C++ dependency management?
Google gave up on their plugin for C++ and is now advising cmake as the future for new NDK projects.