When two or more developers work together on a project, issues can arise when code from one developer has a negative effect or interaction when code from multiple developers is integrated together. In a “traditional” development environment, where the code from different developers may be developed in isolation for relatively long periods of time, these code integration issues may be found much later than when the code was actually written; this makes integration issues much more difficult to identify and solve than if they were discovered early in the cycle. A newer development technique, known as continuous integration, or CI, was created to deal with this problem. In CI, the code from multiple developers is integrated and tested together early in the development process and often during the process. This helps identify issues soon after the code causing the problems is developed; in this way, the offending code is still fresh in the developers' mind and can be rectified much more quickly. In addition, finding issues early prevents them from growing and becoming more complex, more difficult, and more expensive to diagnose and resolve.
Because building and testing applications can be resource-intensive, adopting CI usually means adopting a tool to automatically perform the application build and tests. A quick search of the internet will turn up a myriad of CI servers; at the time of this writing, the Wikipedia article on CI had no fewer than 35 examples! CI servers work by waiting for some triggering condition (such as a regular schedule, a developer request, or code's being committed by a developer to the version control system) and executing a full build of the application and running appropriate tests. Teams using this approach often follow a procedure that requires developers to commit their code at least as often as daily. Developers who commit code that causes the CI build to “break” (fail tests or not compile) are often given some undesirable public task to perform, as an incentive to avoid breaking the build. There are even semi-whimsical hardware devices that provide a public display, such as flashing lights, of the build status.
With so many CI servers available, how can you choose one? For Java-based projects, there are several popular choices:
* Cruise Control – open source, built around Ant. Popular, but has a reputation for being hard to configure, requiring editing of configuration files. Cruise Control is known as the “original” CI tool for Java.
* Apache Continuum – open source, for building Java projects. Because it is the official build tool for Maven, it tends to offer the best support and experience for Maven-based projects. Administration and configuration are via a Web-based interface.
* JetBrains Team City – a popular commercial CI server. A unique feature of Team City is that it has plug-ins for several IDEs that enable developers to do a “pretested” commit when committing their changes to version control—using this capability means that it is impossible for a developer to “break the build.” Administration and configuration are via a Web-based interface.
* Hudson – open source, originally supporting CVS and Subversion only but now with many plug-ins to support other version control systems. Administration and configuration are via a Web-based interface.
For this article, I chose to use Hudson, for two reasons: first, it is a very popular system, and as such, it has a large user community as well as a wide variety of plug-ins (later on in the article, you'll see how useful plug-ins can be). The second reason is that Hudson, unlike the similarly popular Cruise Control, is quite easy to set up and configure.
Downloading and Installing Hudson
Hudson is known for being quite easy to install. The Hudson download is a single Web Archive (WAR) file that can be downloaded from the Hudson home page (the current version as of the time of this writing is 1.332). Place the file in a convenient location. Because Hudson is supplied as a WAR file, you can deploy it into an appropriate servlet container that you may already have; however, Hudson includes an integrated servlet container, so you can start Hudson simply by running the command java –jar Hudson.war. This capability makes it very easy to get started with running Hudson. For this article, we won't require any security or other features that a full-featured servlet container would provide, so we will just run Hudson by using the command given above. Once you have started Hudson, you can access it via the URL http://:8080. The default installation does not require users to log in, and anyone can create, modify, or delete Hudson jobs; obviously this isn't ideal for production use. The Hudson wiki has a page that describes how to set up security, but for this article, we'll continue with the default, unsecured setup.
Scenarios for Using Hudson
For this article, you will set up Hudson to execute two commonly used scenarios:
* Anytime someone commits a change to the Subversion repository, Hudson will compile all the code, execute the JUnit tests, and create the application WAR file. Any failure (compile error or unit test failure) will result in the build's being “broken.” This build should execute quickly so that developers get nearly immediate feedback when they commit changes to Subversion; for this reason, we will not perform the UI tests for this job.
* On a regular basis (once daily), Hudson will do the same tasks as above (compile, test, build), deploy the application WAR file to a properly configured Oracle WebLogic Server, and run the UI tests that have been created with Selenium (for more information on creating UI tests with Selenium, you can read the Selenium article in this series. As in the other scenario, any failure, including UI test failures, will result in the build's being “broken.” We will also be able to manually request that Hudson run this scenario so that we don't have to wait until the regularly scheduled time to see it in action.
We will be using the Oracle Application Development Framework (Oracle ADF) 11g application, unit tests, and UI tests that were developed in earlier articles in this series. If you haven't been following along, you can download the source code here:
oracle.com/technology/pub/files/adf-development-essentials-sample.zip. For the purposes of this article, I have also removed the “everyone” access from my VisualSVN Subversion repository and required login credentials for access so we can see how this works. If you do this, I recommend that you create a user in the Subversion server specifically for Hudson, so that any action Hudson might perform (such as tagging a build) will be recorded as having been done by Hudson. If you have an unsecured repository, you can skip the steps related to providing the credentials.