It is, but it uses XML right: for a declarative document, and one that has tools for editing rather than having to do it by hand. Maven is glorious because it ensures your builds are actually reproducible, something which I've never seen any other language or build tool accomplish.
For a number of reasons Bundler/rubgems does a far better job of reproducible builds.
1) Maven doesn't generate an equivalent of Bundler's lock file. It resolves the versions to be used on each build. If you have dependencies on snapshot versions then there's no way to ensure that all developers are using the same snapshot. OK, you can always specify versions explicitly, but then you lose the benefits of snapshots etc. Bundler's lock file allows you to easily check for newer versions(a gem at a time if you like) without losing reproducible builds.
2) Developers can't upload their jars to the central maven repository. There are gatekeepers. This means that the latest versions of many projects aren't in the central repository. For those projects you have to use their own specific repository. This leads to problem 3. With rubygems developers can upload gems straight into rubygems.org. Also, because most projects are in github and you can specify git dependencies with Bundler you're able to depend on any version of a project(regardless of whether or not it's been released to rubygems.org), all the way down to the commit level.
3) 3rd party repositories change and can be unreliable. This means a jar can become unavailable without any notice. In practice the only way to guard against this is to use a proxy repository like nexus or artifactory, yay, another server to maintain...
1) The whole value of depending on snapshots is letting each developer run everything against their local, possibly-modified versions; there would be no point forcing snapshot builds to be reproducible. Release builds aren't allowed to depend on snapshots. Maybe I'm just too used to maven, but I don't see how you'd do it any other way.
2) Gatekeepers have their advantages; how you run a repository is pretty independent of the build tool. It would be possible to start a "anyone can upload anything" maven repository if this was thought useful.
3) Surely the notion of having your build depend on a random third-party git repository is far more worrying than depending on a random third-party maven repository - wouldn't you need to set up a git mirror server, which is more effort than nexus or artifactory?
First of all, let me say I'm not a maven hater. If I was working on a java project I'd use it.
1) The problem is that until you lock down the dependencies you can never be sure exactly which versions will be used. When you use bundler it generates a file specifying all of the versions that should be used. This gets checked into your repository so everyone is sharing exactly the same versions. This means you don't get situations where you check some code in and you break the build because the build server has downloaded a newer version of a dependency(used to happen a lot for me).
2) It's true it would be possible to start a "anyone can upload anything" repository. Having seen how well rubygems.org works in this scenario I think the java community should really get one organised. Either by enhancing the central maven repository or replacing it entirely(it's always been damn slow to browse anyway).
3) In my experience Github projects tend to be pretty persistent, if you have any concerns though you can always hit the fork button and depend on that. Having said that, using git dependencies is definitely the plan B option.
>1) The problem is that until you lock down the dependencies you can never be sure exactly which versions will be used. When you use bundler it generates a file specifying all of the versions that should be used. This gets checked into your repository so everyone is sharing exactly the same versions. This means you don't get situations where you check some code in and you break the build because the build server has downloaded a newer version of a dependency(used to happen a lot for me).
So how's this different from using non-snapshot dependencies in maven? You mentioned checking for new versions as an advantage for bundler, but you can do that with a single command in maven.
What a non-sense. You can't sanely describe build of your project(s) in documents. Did Maven folks include every possible scenario in markup? Nope. And that's why all Maven builds that are not simple jar of classes tends to have long sequentional calls of build plugins.
I see it this way:
First we had bash and make and ability to do almost everything (run other programs, ...) by using the right thing/language for the job. There was only lack of the functions to deal with Java builds and package management.
Then we had Ant, XML programming language with very limited possibilites (I don't regard targets as a feature). But at least we could express what we wanted.
Then we had Maven. If we needed something special we need to add it to sequence of build plugins (in several hardcoded build phases). Mostly we resort to do things in Ant plugin.
The ability to call random external programs during the build of your project is not a feature, it's a bug. Likewise the ability to lay out your source arbitrarily. Your project's build is not a unique and special snowflake; it can build the same way as every other project, the way that has already been tried and tested by millions, the way that any developer will immediately understand.
If there's really some step that needs to be done in your builds that isn't covered by the existing plugins, you can write your own (it's not hard) and then at least that step is happening in a structured, testable way. But if you're doing something unique to a single project, you shouldn't be doing it in the build system.
> Your project's build is not a unique and special snowflake; it can build the same way as every other project, the way that has already been tried and tested by millions, the way that any developer will immediately understand.
No, actually, builds can get very unique in multi-language systems or in embedded systems... believe me. =)
"Did Maven folks include every possible scenario in markup?"
For me the main point of Maven is that you keep things simple and standard. By not deviating from a standard Maven web project structure and avoiding dependencies or build phases that need special care, I have projects that are simple to develop, build and package.
I am trying very hard to just depend on good behaving Maven dependencies and to stick to simple solutions. No more special build phases for code generation, no more crazy stuff. If I need some special build phase then I am probably doing it wrong.
The result of that is also that my projects are super simple. By avoiding special build phases I can pretty much load up a project in any IDE and just hit Run.
To me that is the true power of Maven. For that reason I don't want to look back at Ant or any of the fancy super flexible Groovy/Scala/Ruby build tools.
So contrary what many people think, Maven forces you to keep things simple. And I think that is a good thing in any project :)
'So contrary what many people think, Maven forces you to keep things simple.'
This is absolutely why I left Java development. Maven in my mind is anything but simple. It was always frustrating to use - this was 2.0 mind you, so maybe things have become easier, but I doubt it.
Even the terminology is totally abstract and complicated. I built a big project for a well known bank around '05-'06 and we had all kinds of problems with maven - we just went back to ant.
I used to love Java in the late 90's/early 00's. I remember the resistance to doing projects with it - it was new, unproven, etc, etc - just like Language X today. I worked with some people who built some cool things with 1.2. The collections framework was great.
But, then all the enterprise stuff started creeping in and everything was configured with gobs of crap xml. Demos would be given where you could edit the configuration via gui tools, but none of the devs I knew did this. Everyone hand edited everything.
Things like maven with their overly abstracted naming and concepts and Spring where everything is 'wired up' by tons of xml are what ultimately drove me away from Java. I just wanted to spend my time working on features instead of configuring things.
My experience is that people try to force Maven to be Ant. In particular, they want a single build to build all of the dependencies in one go. While this can bedone, my experience has been it makes a lot more sense just to keep each of your dependencies a separate project without trying to build everything all at once. It also encourages to build interfaces that change little instead of tying everything together.
I haven't worked in the industry for very long. Could someone explain why build processes tend to get so complicated? I have some intuition about the steps that a build process takes being complicated, but it seems to me that the process itself would be linear i.e
A + Config -> B -> C -> D -> E -> Compiled
Maybe you could have decision points in the compilation flow depending on config parameters, system parameters, making it a tree, but I don't see why a build tool couldn't make those decisions based on the configuration provided. Essentially, I envision a build tool that takes in a huge number of arguments (maybe reads them from an XML/JSON/whatever config file) with sane sets of defaults for each.
(Forgive me if all this seems naive, it most likely is. I want to know why.)
>Essentially, I envision a build tool that takes in a huge number of arguments (maybe reads them from an XML/JSON/whatever config file) with sane sets of defaults for each.
That's pretty much how maven works. A typical java project will have an xml file listing its name and version, the names and versions of all its dependencies, a scm URL for tagging releases and that's basically it. The problem is people who have got used to having all the freedom of calling arbitrary shell programs at any point in the build process; it's very easy to accrete a series of small hacks ("oh I'll just sed this file here to fix that") that add up to something incomprehensible.
So basically one can replace one tool in Java (maven) with four different tools with different conventions and usage scenarios and call the Ruby way simple, and Java way too complicated?
It's better to use different good tools, rather than one bad tool. And by the way, since when is Maven SCM? AFAIK Maven just pollutes SCM with it's dumb release plugin.
If you don't want your artifacts uploaded to some place (like your SCM) then don't do it.
But let me explain how useful this actually is.
When working on a Java project with a team of people, we usually use Maven and some CI tool like Jenkins or Bamboo. People commit code, Jenkins run a Maven build and then either Jenkins or Maven uploads build artifacts to a central repository.
Artifacts usually are: the jar/war/ear file, the -src.jar and the -javadoc.jar.
If code is finished then it will be a x.y release, otherwise it will be uploaded as something like 1.0-SNAPSHOT. Snapshots are usually timestamped.
Now I have a standard place where other projects can find dependencies, where the ops team can grab releases, where developers can find dependencies, code and documentation.
Three extra lines in a pom.xml and you get all that. Your IDE now picks it up and keeps it up to date. You can click/hotkey on anything and it will show source or documentation.
You call it pollution, I call it a great and pretty much completely automatic infrastructure that makes development so much easier.
Some libraries that are being stored at Maven Repository have 2 additional artifacts: source-jar and javadoc-jar.
If you're using Eclipse and Maven plugin, the beauty is that when you hit a shortcut key to navigate to either the Definition or the Implementation of 3rd-party open source library, the Maven plugin will download the source code for you and voila, no configuration or anything like that needs to be done with Eclipse (telling Eclipse where the path, etc).
Same. Maven drove me pretty crazy, to be honest. Compare it with Ruby gems or Laravel's bundles, Maven felt like using a ten thousand ton tank to round up sheep.