Last week, I posted a thread titled Maven Skepticism to the
WOProject list. It was about my misgivings about Maven, and the issues
I was having getting started with it.
So the last few days I've been playing with Maven.
I am no longer skeptical.
So I thought I would post about my newfound optimism with Maven. I
feel I owe it to Henrique and Lachlan for their help. (Thanks guys) I
also think the current maven evangelism documentation is written a
little too formally to be comprehensive.
Background:
I've been programming since I was 12, which means nearly 30 years
now. I have a saying:
Every generation thinks they invented sex, and every generation
tries to reinvent make.
Consequently, I hate Ant. I think its implementation is completely
fubar. I've ranted about it before. I also hate our current build
process at work, which is basically to hope/pray that the ant build we
do nightly for deployment/packaging matches the developer builds we do
in Eclipse.
Now that I've finally gotten my team on svn, its time to fix the
build process and reorganize our projects. Hence the interest in
Maven, basically precipitated by Apple publishing their nightly builds
as a Maven repository.
To get started with Maven, I sat down with the Wonder sources, and
tweaked the existing pom.xml files that had been broken since the
great re-org to work. (pom.xml are the only and only type of file that
Maven uses for building)
What I found:
Maven is a lot closer to how I would design a build system then it
is to Ant. In that, its a lot more similar to how typical modern IDEs
work: If Maven sees a .java file in the right place, it will compile
it and put in in the jar. If it sees a file in the right place, it
will treat it as a resource file, and put it in the appropriate
location.
In short, for most projects, you don't have to specify a bunch of
stuff, you just have to put them in the right place. Additionally,
unlike ant builds, there's very little redundant information in a
maven pom file.
To give you some examples, for the current Wonder Ant builds,
between build.xml files, generic.xml, build.properties
files, .classpath and .patternset files, there are 5320 lines of build
configuration information in the current Wonder build. The equivalent
pom files are 2447 lines, which is not only more efficient, but
includes more information to help avoid the jarmeggedon/jarhell problem.
Jarmeggedon/jarhell
It seems like one of the greatest tools in a Java programmers
arsenal is Google, or rather, 3rd party libraries. If you look at the
Wonder source, there are 65 different .jar files included, about 1 per
project on average. Many of these jar files are duplicates of each
other, or even worse, different versions of the same jar, like there
is a version of commons-logging.jar in ERJGroupsSynchronizer and
another one in EROpenID. Meanwhile, commons-logging is up to version
1.1.1.
To my way of thinking, the Wonder ant builds are already broken if
EROpenID is building against commons-logging-1.03, but then deployed
with 1.1.1...
Maven's solution goes by the fancy name of "dependency management".
What that means in practice is that most of the information in the
pom.xml is just a list of what other projects in your source tree a
given project depends on, and what jars you need by name/version. In
return, maven:
1. Finds and downloads any jars you're missing.
2. Finds and downloads any jars that those jars use!
3. Builds any inter-project dependencies.
4. Generates the correct classpath.
5. Packages jars as needed in the appropriate place.
A dependency looks like the following:
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
Most of the pom.xml file consists of these dependencies, and the
site http://mvnrepository.com will even generate them for you.
Moreover, if you put a "dependencyManagement" section in your top
level pom as follows:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
</dependencyManagement>
Then you can leave out the version specifier for your individual
projects entirely:
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</dependency>
Which means you only have to change a single file when you want
to use version 1.1.2 or something.
It works unbelievably well. How well? Well, in the course of
setting up pom.xml files for Wonder, I found out that Wonder was
missing a secondary dependency, because it used a certain jar file,
which used another jar file which wasn't included.
It's pretty cool when your build system can find bugs that
otherwise you wouldn't have found until runtime.
Particularly Suited to WO
A minimal WO application ends up with the following structure:
BusinessLogic.framework (because its always a good idea
to put the BL in a library so its shareable)
App.woa (main user app)
Admin.woa (because you have
to be able to administer the damn thing)
So immediately, you now have 3 projects to build in order to
deploy. That can mean 3 sets of jar files to keep track of, 3
classpaths to maintain. Even trickier, if a new jar is needed for
BusinessLogic, you have to add that jar (and any jar that jar
references!) to App and Admin.
With maven, you only need add the dependency to
BusinessLogic.framework, and you don't need to dig up what jar that
jar references because the maven repository will pull those in as
well. You don't even have to remember to do it, because since maven is
building the classpath for you, the compiler will automatically bitch
when it sees things missing.
So I think maven is particularly suited to WO.
Summary
I have a ways to go with my maven knowledge, but given that I was
able to get Wonder building without really knowing that much about
mvn, and without knowing all the ins-outs of the Wonder
interelationships, I think that speaks well for Maven.
Pierce
This archive was generated by hypermail 2.0.0 : Tue Jul 08 2008 - 20:06:44 EDT