Series: Oracle ADF Development Essentials - Part 7


Continuous Integration with Hudson

The basics of installing and configuring the Hudson continuous integration engine to continuously build and test Oracle Application Development Framework applications

By John Stegeman

Published March 2010

Downloads:

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://<your_host_name>: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.

 

Initial Build Server and Hudson Configuration



For Hudson to be able to build our application and test it, the machine on which Hudson runs will need to have a Java Development Kit (JDK) installed (for compiling the project); an Ant installation (with the proper Ant libraries installed for building an Oracle ADF 11g application); and for performing UI tests, a Selenium RC server running on the same machine. Usually the Hudson server would not be installed on a developer's computer but would be installed on a computer set aside for doing the CI builds and tests. Because we have set up our application to be able to be built with Ant and have all the required libraries in Subversion, we should not have to have a copy of Oracle JDeveloper 11g installed on the CI server. For the purposes of learning, you can certainly install all the components on the same computer; however, for the purposes of this article, I will install Hudson on a separate machine (actually, a virtual machine) to prove to myself that the CI server really doesn't need to have Oracle JDeveloper installed as well as to show you what components would need to be set up on a new server. My environment looks like this:

Developer Laptop (Windows Vista)
Name: jstegema-lap
Oracle JDeveloper 11g installed
Oracle Database 11g and Visual SVN installed (for testing)
CI Server (Virtual Machine)
Name: jstegema-lnx
OpenSUSE 11.2RC2 and Hudson installed

The first thing we need on the CI server is a JDK capable of running Hudson. My CI server already has a JDK installed, which is fine for running Hudson, but it's a bit out-of-date to use as the JDK for compiling an Oracle ADF 11g application. Although Hudson has the ability to download and install JDKs and versions of Ant automatically, it does take a bit of setup and configuration to do so. So, for this article, I'll download and install an updated JDK manually. For Ant, however, you may recall from the JUnit article of this series that we need to copy a few JAR files from an Oracle JDeveloper install into the Ant library directory, so we cannot use the automatic install capability and must install Ant and copy the libraries ourselves.

To install Ant, just download it from the Ant Web site and unzip it to an appropriate directory on the CI server. As mentioned in the Ant article, you'll need to copy junit.jar and ant-weblogic.jar from an Oracle JDeveloper 11g installation (they are in <install_directory>/jdeveloper/ant/lib) into the lib directory of the Ant you downloaded and unzipped.

The next step is to tell Hudson which JDKs and Ant installations we are interested in. Fortunately, all the Hudson configurations are done via a Web interface and are quite straightforward. To start, browse to the Hudson URL (by default) and click the Manage Hudson link. Then, on the Manage Hudson page, click Configure System. On this page, you can set up both the JDK and Ant installations. To start, click the Add JDK button in the JDK section. Uncheck the Install Automatically check box, provide a memorable name (I suggest using the JDK version), and provide the location where the JDK is installed. On my system, it looks like this:



Figure 1: JDK configuration

Next, do the same thing to add an Ant installation. Here's mine:



Figure 2: Ant configuration

Click the Save button to save the configuration. Now you'll be able to use the configured JDK and Ant installations when you create the Hudson jobs.
Creating a Build-and-Test-on-Commit Job

Let's start by creating a Hudson job that has the following characteristics:

  • Triggered by: newly committed change in the Subversion repository
  • Actions to take: build the Model and UI projects of the application, compile the ModelTests project, and execute the AllOTNAppModuleTests test suite
  • After the build and test: publish JUnit test results

This job will show the basic capabilities of Hudson. Once we have the job working, we'll look at how you can add more functions to the job by using Hudson plug-ins. To get started, just navigate to the Hudson home page, located at http://<your_host_name>:8080. Getting started is easy: the center of the Hudson page invites you to “please create new jobs to get started.” Click the create new jobs link now. Hudson will ask you to name the job and pick the type of job to create. Let's call this job Build and Test OTN Trunk (we will build from the project “trunk” in Subversion; this type of job is a “free-style software project,” in Hudson terminology. Fill in the information, and click OK:



Figure 3: New job information

The next screen displayed is where you do the entire job configuration itself. If you like, provide a description of the job in the provided field. Rather than explain the purpose of each option on the job screen, let's just look at the minimum options we need in order to set up the job. To specify which JDK to use when running Ant tasks, configure the build as a parameterized build in Hudson and add a string parameter to set the value of JAVA_HOME. To do this, check the This build is parameterized check box and use the drop-down to add a string parameter named JAVA_HOME, with the value pointing to the appropriate JDK on your system, like this:



Figure 4: Setting the JAVA_HOME parameter for the build job

The next item we need to provide is the source code management (SCM) information. Because we are using Subversion, click the radio button for Subversion to see the Subversion options. The only item we need to provide is the Subversion URL from which we want to build. Provide the URL of the “trunk” of the application in your environment. Mine is http://hostname/svn/otn/trunk.



Figure 5: Subversion URL for the job

As you can see from the screen shot, Hudson knows right away that the Subversion repository is secured. Click the enter credential link, and provide the username and password for the repository. In the new window that opens, provide the appropriate details and click OK. Mine looks like this:



Figure 6: Subversion authentication

Next we need to set up a build trigger. Our description indicates that we want the CI job to run when changes are committed to Subversion. Hudson calls this option Poll SCM. Once you click the Poll SCM check box, you'll be able to indicate the schedule for polling. The schedule is specified in the same format you would use for a cron job (you can click the field's Help button for more information and some examples). Let's have our job poll for a new commit once every minute so that we don't have to wait too long to see things happen:



Figure 7: SCM polling schedule

Next you'll add the steps you want Hudson to execute as part of the build. Based on the description we created for this job, we want Hudson to execute the following Ant tasks:

  • model.compile (to compile the Model project)
  • viewcontroller.compile (to compile the ViewController project)
  • ModelTests.allTests (to execute the JUnit test suite for the ModelTests project)

Let's add the first build step by clicking the Add build step list and choosing Invoke Ant:



Figure 8: Adding an Ant-based build step

You can then specify the Ant version to use from the list. Because we have multiple Ant build.xml files in our project, we need to click the Advanced button to tell Hudson which one to use. The build file should be specified relative to the Subversion URL. So to tell Hudson to execute the model.compile task in the Model project's Ant build, xml, fill in the information like this:



Figure 9: Build step for the model.build Ant task

You can then follow the same steps to add two more build steps for the other two Ant tasks. The configuration for these two tasks looks like this:



Figure 10: Remaining build steps

The final step in configuring the job is to set up any postbuild actions for the job. As you can see from looking at the options, you can do a variety of things, such as e-mailing someone to let them know how the build went or publishing Javadocs. The one we are interested in is publishing the JUnit test results; check the appropriate check box, and tell Hudson (again, using a path relative to the Subversion URL, Hudson needs the “trunk” at the start of the path) where the JUnit test results are located:



Figure 11: Specifying the test results location

You can now click the Save button to save the job. Hudson will run the build job for the first time. You can see the progress by clicking the ENABLE AUTO REFRESH link in the upper right corner. Once the build starts, you should see the Build History widget start to animate (you can always click the Build Now link if Hudson doesn't start the build automatically):



Figure 12: Build status widget

If you want to monitor the build in detail, you can click the link of the build and then click the Console Output link to see the output. The console view can also be very helpful for figuring out why a build failed (bad job configuration, compile failure, and the like). For example, in one iteration, I had mistyped the Ant task in one of the build steps and saw this in the console view:



Figure 13: Console log from a failed build

When I went back to the Hudson Dashboard page, I saw that my job status was failed (indicated by a big red ball) and that the project “weather” was stormy:



Figure 14: A stormy project

Hopefully your first build will be successful. Once you have corrected any errors and have a successful build, the dashboard should start to reflect a more settled picture:



Figure 15: A more settled picture

Note that the project “weather” doesn't get sunny immediately, because of the recent build failure. Once you have a string of successful builds, your project should be nice and sunny. You can click any of the links in the Last Success or Last Failure columns to see information about the build. For example, when I clicked on the last successful build, I got a status page for the build:



Figure 16: Single build status page

From there, I could look at the test results:



Figure 17: Test results

. . . and even drill down to individual tests:



Figure 18: Individual test results

To test the build triggering, you can make a change to the application in Oracle JDeveloper 11g and commit the change. Soon thereafter, you should notice in the Hudson dashboard that Hudson has detected the change and initiated the build:



Figure 19: Build in progress

Once the build has completed and you click the build number, you can see an indication that the build was triggered by an SCM change, the comment provided by the developer for the commit, and even a detail link showing who did the commit and what files that person changed:



Figure 20: Build result showing initiation by SCM change

To enable you to run the UI tests, the application must first be bundled into an Enterprise Archive (EAR) file and installed on the Oracle WebLogic Server for testing. Additionally, the UITests project will need an Ant script that runs the UI tests. Showing you how to do these step-by-step would make this article much too long, so I'll summarize the steps here:

Creating a Build-and-Test-UI Scheduled Job



If you have an appropriately configured Oracle WebLogic Server available, you can also use these techniques to use Ant and Hudson to deploy the application to your Oracle WebLogic Server and execute the UI tests, using Selenium RC. Because UI tests can take a long time to set up and execute, most people do not schedule this type of a job to execute after every commit to the version control system but schedule it to run on a daily or other timed basis. This article will show you how to create and configure the Ant scripts and the Hudson job to build the application, deploy it to a running Oracle WebLogic Server, and execute the UI tests with Selenium RC. The article will not show how to set up the Oracle WebLogic Server but assumes that you have properly configured a domain with the Oracle ADF libraries. In order to follow along with this article, you should test that you can deploy the application to your Oracle WebLogic Server and access it via a Web browser. For my testing purposes, I installed Oracle WebLogic Server and the required Oracle ADF libraries on my Linux virtual machine.

  • Create a new project called build to hold all the applicationwide build artifacts.
  • Create an Ant build script for the build project.
  • Add a build.ear target to the Ant build script that builds the application's EAR file. Use the same technique you used for the WAR file (create it with Oracle JDeveloper and unzip to discover the structure).
  • Add a build.deploy target to the Ant build script that takes the EAR file and deploys it to Oracle WebLogic Server. Oracle WebLogic Server includes an Ant task called wldeploy, which helps here; additionally, this blog post shows a technique for using this task without having to run an Oracle WebLogic Server environment script first.
  • Create an Ant build script for the UITests project. Add a task to execute the UI tests with a proper dependency to the build.deploy target.
  • Commit all the changed code to Subversion, so that Hudson has access to it.

Once you have performed these preliminary steps, you can create the Hudson job. The setup of the Hudson job is quite similar to that of the first job you created; the only differences are these:

  • The job should be scheduled to execute daily (for example) or on demand rather than to poll the SCM.

     

        Figure 21: Job executing at midnight every day

  • There will be one build step in the job (execute the UI tests).

          

  Figure 22: Build step for UI tests

  • The JUnit test results will be in a different directory.

          

  Figure 23: Publishing UI test results

Once you have created the job, ensure that Oracle WebLogic Server and Selenium RC are started (you could add steps in the Ant task to start these if you like) and execute the job. If you watch on the build server, you'll eventually see a browser window pop open (thanks to Selenium RC) and execute the UI tests. If all is working well, you'll start to see two "sunny" projects in your Hudson dashboard:



Figure 24: Two "sunny" projects!

Conclusion

You should now have all the tools you need in your arsenal to be able to develop Oracle ADF applications effectively in teams, automate project builds with Ant, automate unit testing with JUnit, automate UI testing with Selenium, and continuously integrate and test your application with Hudson. I hope you have found these articles helpful.

Go to Part 8 | Back to TOC

 

Acknowledgments
Special thanks to Timo Hahn for helping me (via the great OTN JDeveloper and ADF Forum) to debug why my application wasn't working on a standalone Oracle WebLogic Server but was working fine in Oracle JDeveloper. Remember that the OTN JDeveloper and ADF Forum can be a great place for you to find assistance (remember to search first) as well as to help others.


John Stegeman ( http://stegemanoracle.wordpress.com) is an Oracle ACE director (Oracle Fusion Middleware) and the principal architect in the EMEA region for Cambridge Solutions, a global BPO and IT services firm. He has been working with Oracle products since 1990 and with Oracle JDeveloper since Release 3.