Contemporary Software Development: Building
The subject of my first post of the series “Contemporary Software Development” will be building. How to build your software project is a decision which is made quite early when you start developing.
Unfortunately in a lot of projects this very important topic does not get the appreciation it deserves. On one hand side it’s a very sad story of suffering and endurance. On the other hand side we are talking about a lot of wasted money.In my career as software engineer I experienced some different approaches to the project setup and the build process.
It started with something like find . -name '*.java' | xargs javac, which worked quite well for the first weeks of my professional career. But with a couple of software developer working on a project you want something more standardized.
So we went on with make(*). I guess most of the software engineers will know this build tool which still is a standard tool in the Unix/Linux world. make is a very powerful tools but has its peculiarities also. The make grammar is very delicate when it comes to white spaces. I quess quite a few people sat over a broken make build when a TAB char wasted your build script.
In the Java world Apache Ant was the successor to make in my career. The problem with make and the Java world is, that make is not really platform independent. There are make ports for Microsoft Windows but (at least when I made the jump from make to Ant) it does not work very well. So if you have a heterogeneous environment e.g. you develop on Microsoft Windows and you deploy into a Linux based cloud, you want your build to to be platform independent.
A nice story about platform independence. I did some consulting in a project for the Deutsche Bank Italy and a very large (and expensive) consulting company provided the BEA Weblogic build and setup. I am not 100% sure but I guess it was an Apache Ant based build. One major issue was the application server integration integration. To solve it, the complete project was placed and build in the application server which was committed in to the CVS source control management system. The delivery artifact was – of course – delivered without the application server. But this leads to another wish I have when I am using a build. You want the build to credit the current environment. If you are building for your local development environment you may have different requirements concerning the built artifact as when you are creating an artifact that will be deployed on staging or productive environment.
Back on memory lane: Apache Ant worked pretty well for some years and a couple of projects. But one thing that started to annoy me. Every project was using a slightly build setup so in the daily business there were always searching for artifacts or checking library versions.
Some former colleagues introduced me to Apache Maven. I started with Maven 1 which is a quite interesting mixture of Ant with a framework that offered the possibility to manipulate the Ant build file during the runtime. But Apache Maven had some features which I hat to get used to.
An example is the rigid directory structure defined in a Maven build: Why do I have to follow them? I want my special directory names! But nowadays I love this structure which is equal in every project. You find your files so fast now and even in foreign project. That’s another thing that you want: You want your builds to follow standards, so you can get familiar with the project in very short time. If you are working in the software business a couple of years, may have already realized that you will see very much projects during a professional career and standard projects and processes will make your life much more easy.
Let’s talk about some goodies now which modern build system offer. I will use Apache Maven as example but other systems like rake or buildr offer similar functions.
One thing I love/hate is dependency management. When I started with make or ant, we where committing all libraries into our CVS. Which worked quite well, in most cases you could check our the project, performed the initial build and started to work. But there where lots of minor but very nasty problems. Starting from which library version is really used to incompatibilities of the build tool version.
With the Apache Maven dependency resolution mechanism a new area begun. If you are having one independent project the mechanism is pretty easy to use. You define the libraries you want to use in your pom.xml and maven takes care of the rest. Okay if you want to use libraries which are not in the maven central repository it’s a little more complicated
If you are having a multi module/project environment things will get messy pretty easy, but: They would also if you don’t use the dependency management mechanism. You ask why? When you don’t use this mechanism you’ll normally have a huge monolithic project in your SCM system which will get even more difficult to manage or build. So you want to have a transparent dependency management in your build system. With Ivy for example you’ll have an add-on which offers the possibility to have an dependency management when you are using Ant.
Another goodie is release management. It’s very handy if you start a build to create your release artifact and your tag (or something similar) in the SCM system of your choice. You want your release process embedded in your build system, so you can perform the build when you are creating your release.
Another important topic is testing. You really want your build tool to support your testing facilities. At least when you create your release or deployment artifact you want your build to automatically run your test suite.
I have only one topic left in this post, that is IDE support. Unfortunately most modern IDE like Eclipe, Netbeans or Intellij IDEA offer a IDE specific build. This this very comfortable if you have a small project and what to deal only with your IDE. But you’ll grow really beyond this (my experience). But integration into other build tools is sometimes really poor. So you have to check how you can bridge the gap between your IDE and the build tool. E.g. the maven directory structure troubles some IDE
standard configurations. Fortunatly more and more projects provide solutions for this.
So let’s have a quick resume. This is what you should want in your build system:
- standardized process
- platform indipendence (if your need it)
- credit current environment
- standardized structures
- dependency management
- embeddable release process (including SCM support)
- support of your test tools
- IDE support
I think this list is not too lang and offers some major improvements for your daily work. So if your build process is missing some items from this list, you maybe should think about your build process. And remember: Your development resources are far to valuable to be wasted in an inefficient build process
Announcing: Contemporary Software Development A new home
Hi Niclas,
seems we both more or less shared the same path regarding build systems.
Today, I mostly use maven for two reasons. Its market share (most java based open source projects ship with maven builds) and the fact that it is the system getting the job done fastest (for me) – even though that occasionally implies “Downloading the internet”. Lots of people have been crying about the hard time they have/had with maven. My experiences (even with 1.x) have not been painful compared to the “predecessor” ant.
Whats your system of choice today and why ?
Nowadays, we have quite a few new players in the build arena: buildr, rake, gradle.
Yet, I personally have not found a good (time saving !) reason to switch or start a new project using one of them.
cheers
Andreas
Hi Andreas,
I guess it was you or Maik who introduced me to maven 1.
a reason may be, that we shared some time at SinnerSchrader
I am using Maven (3!) for new projects nowadays. The reasons to do so are pretty much the same. Ant is nice but you’ll always start at near zero. I tried buildr once, it’s nice but didn’t convince, especially when things get “messy”. I took a closer look at rake/grade but no one could offer me a feature that I desperately need.
I know lots of people who complain about maven too, but my experience is: When maven starts getting really complex the issue is already really complex. Maven forces you to deal with this complexity while other tools migrate complexity into other systems. For example keeping stuff in your SCM system instead of generating it on build time.
And if something is really complex do not build an Ant script or try to script using your pom.xml. Build your own maven Plugin in Java, you can deal with “any” level of complexity there quite easy. Did it a couple of times at scoyo and it worked remarkably well.
BTW: Some weeks ago I migrated my computer to use maven 3-beta and it works awesome especially with the new Eclipse plugin. It’s really a drop in replacement and saves quite some time on your daily work. In conjunction with the maven-jetty plugin and Apache Tapestry you can develop at amazing speed.