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.
It has some important strengths but comes at a price in workflow organization. I recommend investigating into alternatives before jumping that particular bandwagon.
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:
- 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.
- 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.
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.
So if Maven is such a bitch, why would anyone use it?
- 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.
- 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.
- 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).
- 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).
- 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.
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.)
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.
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.