Skip to main content

Setting up NetBeans-based projects with a Continuous Integration server

Posted by fabriziogiudici on November 17, 2006 at 5:04 PM PST

Continuous Integration (CI) servers are facilities able to monitor changes in a source repository (e.g. CVS or Subversion) and schedule a new build automatically, in order to verify if the new committed code broke the stability of the system. They are installed on remote servers and usually don't run on programmers' computers - so apparently a problem arises if we're thinking of projects developed with the NetBeans IDE.

As most CI products can be easily configured by just pointing them to a build.xml ant script, the problem just translates to being able to setup a working "headless" environment for a NetBeans-based project - with "headless" I mean that the environment must be configurable by only using a text-based remote connection (e.g. ssh), and not a graphical console (e.g. X11).I've been recently able to setup some projects of mine by using Hudson, a simple but effective CI product that is getting increasing attention by users (in any case most of what I'm saying should apply to other products as well).

Basically things are different according to the following project profiles (which I've experimented):

  1. Java libraries or Java applications that don't use Matisse or other NetBeans-managed technologies (e.g. J2EE);
  2. Java libraries or Java applications that do use Matisse or other NetBeans-managed technologies;
  3. OpenIDE suite projects;
  4. projects based on the Sun Grid Compute Server Plugin.

Dealing with projects of type 1 is straightforward, as NetBeans-generated build.xml is autonomous - that is it can be run as is. You just need to checkout the sources from the repository and point Hudson the the build.xml file.

Dealing with projects of type 2 is slightly more complex, as your projects needs some extra-JRE libraries in the classpath (e.g. if you used Matisse, you need swing-layout.jar). The point is that those libraries aren't part of your workspace (i.e. your files committed in the source repository), but are stored inside the NetBeans installation. When you open such a project with the NetBeans GUI, it fixes the problem by adding the required references; but now that we can't run the NetBeans GUI, as we're connected with ssh, we have to manually perform the same operations.

The first thing to do is to store in the server a working NetBeans installation. As NetBeans can't be installed text-only, the only feasible solution is to install the GUI on another computer, then zip the installed files and unpack them on the server. If you need to upgrade the NetBeans GUI with the latest patches or to install some extra plugin, do it before creating the .zip, as manually patching an installation is tricky. As the NetBeans file setup is the same for each operating system, you don't need to zip the file on the same platform as your target - for instance, I was able to .zip the files on my MacBook Pro and have them working on a remote Linux box.

This was easy. The second step is to setup a user profile, that is the settings that are usually stored into a directory named $HOME/.netbeans:

  1. create the directory $HOME/.netbeans/5.5 (5.5 should be replaced with the NetBeans version you're using);
  2. create a file build.properties - there's a lot of stuff inside it, so it's better that you copy it from a working installation. Basically this file contains properties pointing to .jar files: you have to change them in order to point to your NetBeans installation (for instance, on my MacBook Pro, NetBeans in installed in /Users/fritz/Applications/NetBeans5.5.app, while on my Linux box I installed it in /home/tomcat/HudsonWorkspace/NetBeans5.5). Probably you need only part of the settings inside build.properties, but the only reasonable way to understand what you need and what you don't is by trial-and-error. Too expensive in my opinion, it's much easier to fix all the paths with a simple search & replace.

It's to be pointed out that the above steps have to be performed once for all, when you first create your enviroment.

The final step is to fix something inside your project workspace. Go to the nbproject directory, where all the metadata about the project are stored. Create a private directory and inside it a file named private.properties (i.e. the path is nbproject/private/private.properties), which should contain the following line:

user.properties.file=/home/tomcat/HudsonWorkspace/.netbeans/5.5/build.properties

You got it, you must point to the build.properties you created before. That's all: at this point, you've manually performed the same operations that the NetBeans IDE execute when it opens a project, and the build.xml script should work as usual: now it can be run by Hudson with no problems.

For projects of type 3 (OpenIDE suites), it's pretty much the same; the only difference is that the file you have to create in nbproject/private is named platform-private.properties (instead of private.properties).

For projects of type 4 (Compute Server plugin)... things should be the same, but at the moment I still have a compilation problem. :-) I'll post a follow-up when I fix it.

TIP: in case you have a project which uses its own libraries, or a group of projects that reference each other, there's a thing you should check (and eventually fix) in order to have everything working. Cross-references are usually stored in the nbproject/project.properties file; for instance, these two properties:

project.EditableImage=../EditableImage
file.reference.jai_core.jar=../lib/jai-1_1_3/lib/jai_core.jar

reference EditableImage and jai_core.jar, a project and a library that we depend on, and locate them with relative paths. Usually all this referencing stuff should be in the nbproject/project.properties and appear with relative paths. But sometimes NetBeans fails and store them in the nbproject/private/private.properties and uses an absolute path (when this happens, opening the projects with the NetBeans GUI pops up the "Reference problems" warning, and you are invited to resolve references manually). For instance:

project.EditableImage=/Users/fritz/Projects/Mistral/EditableImage
file.reference.jai_core.jar=/Users/fritz/Projects/Mistral/lib/jai-1_1_3/lib/jai_core.jar

Before setting up your projects with your favourite CI facility, check these out, as it can't work on the CI server: first, because nbproject/private is never committed in a source repository, second because absolute paths are likely to be different. So, replace any absolute-path references in nbproject/private/private.properties with relative-path references in nbproject/project.properties.

That's all. It might sound complex, but once you've gone through for the first time, it's easier to repeat for other projects. And having a CI that works for you, checking out broken commits and createing nightly builds, is well worth while the effort!

PS Other tips about NetBeans + Hudson on the Tor Norbye's blog.