Maven experiences

Hi,

after having used Maven in anger in private and work projects for three months, here’s a run-down on what Maven does, how it might help and where it has problems for a project like jme.

Executive summary
It has some important strengths but comes at a price in workflow organization. I recommend investigating into alternatives before jumping that particular bandwagon.

Details follow.

Maven’s principal mode of operation

An “artifact” is a file provided by a build.
A “Maven project” defines a “build”, i.e. a process that collects artifacts from dependencies (other Maven projects) and in turn creates new artifacts. The definition lives in the pom.xml. You can push recurring configuration elements into a “parent pom”.

Standard practice is to have two kinds of Maven projects:

  1. In-pipe ones that create a single principal artifact, for use as a dependency by other Maven projects, because Maven imports just the principal artifact from any dependency.
  2. End-of-pipe projects that may create a multitude of files; it’s the responsibility of whatever picks up the build results to choose the files to use.
    In-pipe projects usually create multile files as well. For example, in JME, you’d want to create not just the class jar but also the sources and the javadoc jar. Dependent projects will ignore source and javadoc during build because the principal artifact is the class jar, but the IDE will pick these up during debugging and javadoc browsing.

Required infrastructure

You need to set up a Maven Repository on a server.
The Maven guys told me that setting that up is a five-minute experience, but they conveniently forgot to mention that
a) this applies only to setting up a server on the local machine where development happens, which is useful only for a single-developer project;
b) setting up a repository is a full-day experience for an untrained administrator;
c) it’s easy to waste a day on an installation what, ultimately, won’t work (I spent a futile day on Nexus, which wouldn’t work, then another day on Artifactory, which would; it’s probably random which repository will happen to work first;
d) you can hit all kinds of odd problems with NTLM authorization and 64-bit installers not built for 32-bit Windows VMs - stuff that will bite you only if you’re in a Windows-only shop;
e) getting Maven configured to finally push to that repository has been taking me another day and not all details are in proper working order yet.

All or nothing

Maven is an all-or-nothing proposition. Setting up a Maven project and gradually switching over is going to create a lot of hassle and little or no benefits.
This makes it quite hard to switch over.

Geared towards Java

Maven’s standard settings are heavily geared towards Java. Building a C or C++ library and including it in a Java build (as JME requires) is being done but a less well-explored road than a pure Java build.

Benefits

So if Maven is such a bitch, why would anyone use it?

  1. It’s an incredible work saver for anybody using the jars. Specify domain, library name, and version, and Maven will pick up the jar, any associated source and javadoc.
  2. Dependency management. Pull in a dependency, and indirect dependencies will be loaded as well. E.g. for JME, one could set up a pure bullet subproject that offers just the physics engine, and a scenegraph-bullet that does the scenegraph integration; if scenegraph-bullet is imported, it could pull in bullet automatically. The main project specifies just what it needs and doesn’t need to concern itself much about indirect dependencies.
  3. There’s also the possibility to suppress a dependency. Or to override it to use a different version number (important if, say, two different imported libraries disagree about which version of slf4j they want).
  4. Build stability. An artifact published under a given release version is guaranteed to remain unchanged for all eternity. You don’t need to worry what version you’re pulling in, it’s right in the library name (this is also great for handling bug reports because the reporter can easily determine what version he’s using).
  5. Maven can do automated release processes, up to and including setting up a new SVN branch for the next version, after asking what the next version number will be.

Liabilities

Maven is very strict in its ways.
Adapt your workflow to what Maven expects, and all will be fine.
Deviate from it, and Maven will throw a hissy fit, force you into writing tons of nonstandard configuration, throw unexpected and hard-to-solve problems at you, and mislead IDE plugins about what it’s doing so that in-IDE builds and command-line builds will deviate. (Generally, the command-line build should be considered authoritative. IDE plugins tend to have trouble keeping up with all the plugins that are available for Maven.)

Alternatives

The most important thing about Maven is Maven Central - a repository of published open-source jars and other artifacts. It relieves people from hunting down jars, sources, and version information from a gazillion of different websites with a gazillion of different conventions about what versions are retained and where to find each detail.
Fortunately, you don’t need to use Maven to publish to Maven Central, nor do you need Maven to import from there; directory layout are standardized but that’s about all. Just contact Maven Central and claim the org.jmonkeyengine groupId and upload what you need - they will want to make sure that the stuff you upload can be used from Maven, but that’s covered in the tools that do the upload.

Alternatives that I’m aware of include Buildr, Ivy, and Gradle.
I’m definitely not happy with Maven, but it’s good enough that I’ll stick with it for now; the next project that I’ll set up, I have settled - somewhat arbitrarily - on Gradle.

Recommendations

Inconclusive; I don’t know enough about the JME project’s workflow to say how much it would have to adapt to fit Maven.
Maven certainly won’t budge to accommodate JME.

4 Likes

I agree on most things you said. Also don’t forget that for libraries in development / unstable stages maven can only play out its strengths if the developers think about maven and its needs. If theres no official version maven is pretty much stumped.

If you want the advantages of maven and dedicate yourself to one build system completely, take a modern alternative like gradle instead of maven. If you want a working and compatible build environment, just use the most basic implementation there is: ANT. Can be integrated in any build environment. Just like for C/C++ make files are still the standard and only special projects use things like cmake, automake and whatnot.

1 Like

Gradle is excellent. All of Maven’s strengths and none of its weaknesses. And when you are under deadline and must “just make it work” you have the freedom to do all sorts of things.

In fact, in gradle it was rarely “how do I get this to work” as much as “how do I get this to work the way the gradle authors meant me to”. :slight_smile:

Also gradle allows you to do shart hacks with ant if needed, withotu to uch hassle, eg a own prebuild tool without the need to write a proper plugin or revert to command line. (as ant plugins are far easier to write)

@Empire Phoenix said: Also gradle allows you to do shart hacks with ant if needed, withotu to uch hassle, eg a own prebuild tool without the need to write a proper plugin or revert to command line. (as ant plugins are far easier to write)

Easier to write than maven plugins? Yes. Easier to write than gradle plugins? No. :slight_smile:

I’m seeing some people praise Ant here, but in my book, it’s too permissive where Maven is too restrictive.

Maven builds are extremely limited, which is horrible for configuring a build but makes it really easy to combine them.
Ant builds are far easier to get to do one’s bidding, but can’t really be integrated across projects. If a subproject’s build script changes the way it works, and dependent project that leverages that build script for its own purposes will have to be adapted or even rewritten. This kind of problem cannot exist for Maven.

My real criticism of Maven is that it’s unnecessarily restrictive.
E.g. you’re effectively prevented from injecting an externally-built jar into a Maven build, you’re supposed to register it in a corporate repository so your builds will become repeatable. Telling the head honchos in the Maven lists that a fixed revision number in an external SCM is as stable as a Maven repository didn’t interest them in the least, nor did they invalidate the argument; instead, they insisted that setting up a team repository would be the simplest thing in the world. (They were oh! so wrong… and they should have known it.)

The one thing that’s really fine in the Maven world is the repository.
I understand Gradle reuses that.
I’d really like it if JME set went from Ant to Gradle, and uploaded the resulting jars to Maven Central. Projects could then use Maven or Gradle or just plain downloads, whatever suited them best, without nagging anybody about how fantastic a Maven build would be or anything. (I don’t know how well Gradle can support a Maven Central upload though; if it’s as good as people say, this should be a breeze, but I really don’t know, the devil is in the details, and the proof of the pudding is in the eating.)

Like I say, you can easily integrate a jme build in your gradle build. No issues at all. Because its ANT :wink:
The content of this post is meant to be read as a straight information or question without an implicit dismissive stance or interest in having the other party feel offended unless there’s emotes that hint otherwise or there’s an increased use of exclamation marks and all-capital words.

The issue I mean is that the Gradle build cannot infer from the Ant script whether a rebuild is actually needed.

Sure it can, depends on you ant script. The SDKs script doesn’t rebuild stuff if its not needed.

Yes, but Gradle is unable to infer on its own that the SDK scripts have that property, and can be run repeatedly with impunity.
Not a problem with “gradlizing” the SDK if that’s ever going to happen, but possibly a problem with other projects that don’t want to write scripts that determine what needs to be done.

You would just need to check the last mod date of the jar…?
The content of this post is meant to be read as a straight information or question without an implicit dismissive stance or interest in having the other party feel offended unless there’s emotes that hint otherwise or there’s an increased use of exclamation marks and all-capital words.

Not sure what scenario you have in mind - which jar, building the jar or rebuilding the dependent project, how many dependencies either on the jar or on the dependent project.
Not going to spend the time to cover all these bases.

Here is what I’ve learned when dealing with Maven.

  1. If you are the person mavenizing your project, you will have to learn a lot about maven. If you don’t, prepare to be perpetually frustrated.
  2. If you are not the person mavenizing your project, consider yourself blessed.
2 Likes

Sounds to me like Gradle is much more welcome than Maven. I can’t compare these solutions technically, but I can definitely say Gradle wins the “buzz competition” based on the cool stuff developers are doing with it (and subsequently share for buzzhungry people like me to find).

How’s your foray into Gradle going so far @toolforger ?

Unfortuantely, shifting priorities have diverted my attention away from trying out Gradle, and simply kept my current Maven setup “just good enough to make it build”. (It’s lots of explicit manual configuration just to have a build for those parts of the engine that I need, so it’s probably not going to help anybody else.)
Curiously enough, Maven’s maven-assembly-plugin proved to work out of the box for merging jars. So Maven is actually scoring on the “good enough” tab.

Gradle seems to reuse some of Maven’s conventions, and I’d recommend adopting them. Not because that’s anything earth-shattering, but because following established conventions makes life a little easier for those who’re trying to find their way.
Some of the issues with mavenizing jme had to do with splitting up jme into separately compilable modules. jme’s modules are pretty well decoupled actually, I suspect that those surprising dependencies that I saw were inadvertent and should never have made it into SVN. (No concrete example, unfortunately, I dimly recall having seen the blender importer depending on terrain for some test code, or something like that; in all, it was less than a handful of such dependencies.)

@toolforger said: Unfortuantely, shifting priorities have diverted my attention away from trying out Gradle, and simply kept my current Maven setup "just good enough to make it build". (It's lots of explicit manual configuration just to have a build for those parts of the engine that I need, so it's probably not going to help anybody else.) Curiously enough, Maven's maven-assembly-plugin proved to work out of the box for merging jars. So Maven is actually scoring on the "good enough" tab.

Gradle seems to reuse some of Maven’s conventions, and I’d recommend adopting them. Not because that’s anything earth-shattering, but because following established conventions makes life a little easier for those who’re trying to find their way.
Some of the issues with mavenizing jme had to do with splitting up jme into separately compilable modules. jme’s modules are pretty well decoupled actually, I suspect that those surprising dependencies that I saw were inadvertent and should never have made it into SVN. (No concrete example, unfortunately, I dimly recall having seen the blender importer depending on terrain for some test code, or something like that; in all, it was less than a handful of such dependencies.)

Just an FYI, gradle would deal with JME’s structure just fine. I’ve even had gradle pretty trivially build multiple modules out of the same source tree (ie: package by package). JME is actually way more organized than even that.

To the general question:
My experience with ANT was that, after getting the build setup, my “mess with the build scripts” time was measured in hours per month on average.
My experience with maven was that “mess with the build tool” time was measured in hours per week… even after being completely setup.
Gradle was very freeing because it had all of maven’s strengths (convention over configuration, access to repos) and all of ANT’s strength’s (easy access to local jars versions in SVN, etc.) while having a few additional features like being able to script plugins right inline and easily break them out into separate plugins for sharing. Even ANT’s awesome plugin support felt onerous in comparison. Moreover, my “mess with the build” time was back down to hours per month.

@pspeed seeing you have done the transition already: How much work do you think would moving a project from Maven to Gradle be?
Say, half a dozen projects, one parent pom, nothing complicated in the poms?

@toolforger said: @pspeed seeing you have done the transition already: How much work do you think would moving a project from Maven to Gradle be? Say, half a dozen projects, one parent pom, nothing complicated in the poms?

If they are pretty standard POMs then it should be a piece of cake. I haven’t upgraded gradle in a while but it used to be dead simple. Import the Java plugin, import the maven plugin, define your dependencies. Done.

Sounds good.
Now I just need to find the time and energy to actually convert a project :smiley:

Looks like Gradle recently became Android’s new weapon of choice as well: