A Sensible Java Build Tool
I've been writing Java in one sense or another for a few years now. I learnt stuff at university, then used it in a few jobs. I've written Beans and Applets, and various bits of stuff in between.
It's fairly safe to say, that I like Java.
One thing however, that's been a pretty consistent bugbear in all the time I've been writing Java, has been the classpath, and dependency resolution. Luckily, all that can now change.
I used to think that Ant was a pretty neat build tool. All the IDEs supported it, it kinda worked most of the time, but sometimes, building was a bit of a ballache - Some stuff had to be in your lib/ folder, sometimes in Ant's lib/ too.
Lately though, and this week in particular, I've been playing with Maven.
Maven is a pretty fucking cool build tool for Java applications. I suspect it probably works with other languages, but it's "designed" for Java.
I don't think I really have the expertise or knowledge to explain how Maven works, partly because I haven't studied the inner workings that deeply, but also, because it's far better explained here (http://maven.apache.org/what-is-maven.html).
Instead, I'm going to dive right in, and explain what I've been working on this week.
The company I work for currently, is making a pretty radical shift away from using PHP for everything. Instead, we've been investigating Java for creating a middleware layer that everything can talk to.
I'm pretty chuffed with this, but I do wish that it had come a lot earlier on. If it had, I might not have been so decisive to leave when offered a better job.
Basically, when we came up with this project, I insisted that we do it properly, for a change.
I suggested that a good workflow would be something like: Netbeans IDE -> Maven Project -> Git SCM -> Jenkins CI -> Maven Repository (We chose Artifactory, but I did test Sonatype Nexus too, but didn't like it).
This is a good pattern for the Joel Test's "Can you make a build in one step?"
I basically wanted to create a demo project that can be used as the basis for all future FR projects, I do the R&D to make the initial POM work, then everyone else can clone this, or inherit from it..
This decision was twofold, I also wanted to figure out JPA/Hibernate and have some clue how that works for reverse engineering the classes from an existing database, the answer to that is: Pretty well, actually. - But that's another story.
My IDE of choice is Netbeans. I've been using it since I was at
university, except for a small android-related foray into Eclipse, and
an experimental nosing around IntelliJ IDEA.
Stuff I did:
- Created a new Netbeans Maven project from the quickstart archetype.
- Added the Dependencies on Hibernate (all the sub-dependencies get resolved, and added)
- Added the <scm></scm> and <ciManagement></ciManagement> lines to the POM
- Added maven-shade-plugin to allow us to build a fat JAR, which makes the jar bigger - it includes all the dependency JARs, but does make deployment a damnsight easier.
- Configured <distributionManagement></distributionManagement> to contain the url of the repository we're using.
That's pretty much it. Here's the finished POM, with various bits of secret removed.
When I edit something in Netbeans, and commit a change, there's a post-commit hook (post-receive) that calls the Jenkins API, and builds the project. Jenkins then deploys the artifacts (a fat JAR and a POM) to the Artifactory.
Epic.
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)






Comments
Mykel Alvis replied on Mon, 2012/01/23 - 1:09am
- Make a company parent super POM (or make a hierarchy of POMs) that contain(s) the boilerplate elements of the POM and a dependencyManagement and pluginManagement section that configures dependencies and plugins.
- Use properties to set widely used values (eg. ${spring.version} to set the version of Spring you're using ). Obviously you'd want to set those properties in your super POM.
- Overcome the urge to make monolithic projects. If your POM hierarchy is good, then series of multi-module builds are simple and easy to maintain and promote breaking applications up into more testable pieces.
- Document using the site plugin.
- Use Sonar. It's awesome.
- Go to the effort to create separate integration test projects.
- Use the release plugin to make releases
I also suggest reading Kief Morris'This saves a ton of time later and keep versions consistent across your working project set
This way when a developer wants to use a new version of something, he can just over-ride the property (that his POM inherited from the parent you built) and if it becomes necessary, feed that altered version back up the chain to the company parent..
This can be a pain, but I suggest using Xdoc. It's slightly more foolproof than APT but YMMV.
Besides making integration testing possible, the separate POM prevents a form to test-dependency pollution from occurring in your actual codebase
Pick nexus over artifactory.The search interface is much better..
Meh. Pick whatever repo manager you want. Just pick one and use it.
whiningsomewhat slanted article about Maven's weaknesses. His article is chock full of examples, both of how not to use maven and how to exploit its weaknesses to make your life harder.General things to remember that aren't suggestions:
Lance Semmens replied on Mon, 2012/01/23 - 5:01am
It pains me to see people discovering (and loving) maven in the year 2012!!
I have seen days and days of development time be wasted with Maven for tasks that could be done in 30 minutes with ant. I urge you to give Gradle a try.
Hibernate have switched from maven to gradle (https://community.jboss.org/wiki/GradleWhy) and so have tapestry (https://issues.apache.org/jira/browse/TAP5-116).
"Gradle combines the power and flexibility of Ant with the dependency management and conventions of Maven into a more effective way to build. Powered by a Groovy DSL and packed with innovation, Gradle provides a declarative way to describe all kinds of builds through sensible defaults. Gradle is quickly becoming the build system of choice for many open source projects, leading edge enterprises and legacy automation challenges."
Mark Unknown replied on Mon, 2012/01/23 - 11:10am
John J. Franey replied on Mon, 2012/01/23 - 12:00pm
in response to:
Lance Semmens
Lance Semmens replied on Tue, 2012/01/24 - 9:00am
Maven is great for it's conventions... simply use src/main/java, src/main/resources, src/test/java etc and you get a lot for free
Gradle uses the exact same conventions and like maven, you get a lot for free when you use the conventions.
Where you really notice the difference is when you want to perform an extra step or do something slightly different. Maven will usually fight you tooth and nail and waste your precious development time whereas gradle is much more versatile.
There's a discussion on stack overflow here
Jason Hatton replied on Tue, 2012/01/24 - 2:30pm