Part I. Build Tools

“It just shows what can be done by taking a little trouble,” said Eeyore. “Do you see, Pooh? Do you see, Piglet? Brains first and then Hard Work. Look at it! That’s the way to build a house.”

“A House is Built at Pooh Corner for Eeyore,” The House at Pooh Corner, A. A. Milne

Putting some thought and effort into planning your build process from the outset can pay off abundantly further on down the line, when the going gets tough and the pressure is on. This is where a well-designed build process and fine-tuned build tools show their worth.

Like many things, in IT and elsewhere, build tools are primarily the fruit of human laziness. Compiling C or C++ (or Java, for that matter) from the command line is a terribly tedious affair. And, in the Unix world, where scripts abound, the next step was natural: why not write a script to do it for you? A basic shell script written to compile a few C source code files was probably the oldest ancestor of our modern Java build tools such as Ant and Maven.

Shell scripts work fine for a small number of source code files, but this approach is difficult to scale to larger applications. This is where Make enters the scene. Make is the principal Unix build tool, and anyone familiar with linux or Unix will have come across it at some stage. A makefile (the name of the scripts run by Make) is basically a list of instructions used to compile your application. The idea is to automate the build process, by working out exactly what files need to be compiled, and in what order. You do this by defining dependency rules, which tell Make when it should compile a particular file, and how it should go about compiling it. A very simple makefile is shown here:

# top-level rule to create the program.
all: main

# compiling the source code.
main.o: main.c
        gcc -g -Wall -c main.c

# linking the compiled files.
main: main.o
        gcc -g main.o -o main

# Remove generated files
clean:
        /bin/rm -f main main.o

This makefile will compile and link the C program contained in the main.c source code file. Real-world makefiles can get much bigger and more complicated than this, and Make does a lot more than what can be gleaned here. Indeed, Make is a powerful tool: it is used regularly to build very large and complex C and C++ applications, including the Linux kernal itself. It marks an important step in the history of automating the build process. Make, along with Unix/Linux, also helped to promote the idea of a portable build: you should be able to build an application from the source code on any machine. Of course, the use of libraries in Linux and Unix makes this a bit more complicated then that, but the idea is there.

However, as we will see, nowadays there are build tools that are much better adapted to Java development: leave Make to the C and C++ programmers.

The history of builds in Windows environments is slightly different. In the days of yore, when Turbo Pascal was king, you usually would write, compile, and build your application directly from within the IDE. This remained the tendency for a very long time—builds would be performed on an individual developer’s machine from within his IDE.

This approach is still used in many organizations. However, it is not a good idea for several reasons. A build process that relies on an IDE is likely to depend on how the IDE is installed. This in turn makes it dependent on the configuration of particular machines. If your build process depends on how a particular developer has configured his or her machine, you’re in trouble.

A good build process has a certain number of characteristics, for example:

  • Builds should be portable. A new developer should be able to check out the source code of a project, and run a build, independent of the IDE. Builds should also be portable between operating systems. Nowadays, it is common to develop on one OS and to build on another.

  • You should be able to run a build without human intervention. This is one of the underlying principles of Continuous Integration, which we look at in Part VIII of this book. A build that needs human intervention reveals a very fragile and vunerable build process.

  • A build tool should federate a set of tools and processes into a single, coherent build process. Building a software application can involve many steps—compiling the code, of course—but also other steps such as downloading dependencies, running unit, integration and functional tests, performing automatic code audits, bundling the application into an executable package, possibly deploying the application into a test environment, and even generating technical documentation. As we will see throughout the rest of this book, the build tool is the underlying framework that ties all of these tools and processes together.

In Java, there are two main build tools: Ant and Maven. These two products are radically different in their approach and in the way they are used. Both tools have staunch partisans and opponents, and the choice of build tools is a subject that tends to evoke a lot of passion amongst Java developers. However, both are worthy of interest, and we will try to look at both with the diligence that they deserve.

Ant is a well-known and widely used build scripting tool based on a procedural, task-driven approach that gives you a very high degree of flexibiliy. Build scripts are written in XML, rather than the somewhat fickle syntax found in Make files. Ant comes with a rich set of built-in tasks, allowing you to automate virtually any part of the software development lifecycle, from compilation and unit tests to deployment over the network and notifications to team members by email.

Maven takes a higher-level, declarative approach, favoring convention over configuration, and relying on standards and conventions to take much of the grunt work out of the build process. Like Ant, Maven uses XML for its scripting language. However, rather than describing the steps required to build your project, a Maven script describes the project itself, in a very declarative manner. Maven provides built-in support for declarative dependency management, and is a powerful means of organizing your internal and external dependencies. Maven also benefits from a rich library of plug-ins that you can use to integrate extra features into your build process. And, if there isn’t a plug-in, you can always use an embedded Ant script, or even write your own plug-in!

Which build tool is best for you? Build tools are subjective things, and your choice may be as influenced as much by your own personal background and experience as by technical matters. Personally, I would recommend Maven for any new project, even for small ones. Despite the higher initial learning curve, Maven actively encourages better programming habits and compliance to best practices, whereas Ant really leaves these matters to your own personal judgment and better nature. I find that Maven pays off in the long term with a more consistent, well-structured project organization.

On the other hand, I wouldn’t rush off and convert my 10,000 lines of Ant build script to Maven without a good business justification. Such justifications do exist, but they need considered thought. As a rule, the bigger the Ant file, the more work will be involved migrating the project into a Maven structure. Ant is also a good choice if you really do need to do things a little “out-of-the box”—for instance, if you are writing a build script that doesn’t really involve the classic build structure. There’s no point trying to fit a round peg into a square hole, so to speak.

In the following chapters, we will look at both of these tools in some detail. In addition, throughout the rest of the book, you will find many examples of how to integrate the other tools that we discuss with Ant and Maven.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.216.88.54