jump to navigation

Cruise Control and Ant problems February 5, 2008

Posted by Phill in General J2EE.
Tags: , , ,
comments closed

I had a really weird problem with Cruise Control / ant today. It was coming out with an error like this:

2008-02-05 10:48:27,903 [Thread-79] WARN ScriptRunner - java.lang.RuntimeException
2008-02-05 10:48:27,904 [Thread-79] WARN ScriptRunner - at org.apache.tools.ant.Main.createLogger(ant-1.6.5.jar.so)
2008-02-05 10:48:27,904 [Thread-79] WARN ScriptRunner - at org.apache.tools.ant.Main.addBuildListeners(ant-1.6.5.jar.so)
2008-02-05 10:48:27,904 [Thread-79] WARN ScriptRunner - at org.apache.tools.ant.Main.runBuild(ant-1.6.5.jar.so)
2008-02-05 10:48:27,905 [Thread-79] WARN ScriptRunner - at org.apache.tools.ant.Main.startAnt(ant-1.6.5.jar.so)
2008-02-05 10:48:27,905 [Thread-79] WARN ScriptRunner - at org.apache.tools.ant.launch.Launcher.run(ant-launcher-1.6.5.jar.so)
2008-02-05 10:48:27,905 [Thread-79] WARN ScriptRunner - at org.apache.tools.ant.launch.Launcher.main(ant-launcher-1.6.5.jar.so)
2008-02-05 10:48:27,913 [Thread-76] INFO Project - Project xxx: idle
2008-02-05 10:48:27,913 [Thread-76] INFO ProjectController - xxxController: build progress event: idle
2008-02-05 10:48:27,913 [Thread-76] ERROR Project - exception attempting build in project xxx
net.sourceforge.cruisecontrol.CruiseControlException: ant logfile /usr/share/cruisecontrol/projects/xxx/log.xml does not exist.
at net.sourceforge.cruisecontrol.builders.AntBuilder.getAntLogAsElement(AntBuilder.java:388)
at net.sourceforge.cruisecontrol.builders.AntBuilder.build(AntBuilder.java:198)
at net.sourceforge.cruisecontrol.Schedule.build(Schedule.java:165)
at net.sourceforge.cruisecontrol.Project.build(Project.java:226)
at net.sourceforge.cruisecontrol.Project.execute(Project.java:149)
at net.sourceforge.cruisecontrol.ProjectConfig.execute(ProjectConfig.java:369)
at net.sourceforge.cruisecontrol.ProjectWrapper.run(ProjectWrapper.java:69)
at java.lang.Thread.run(Thread.java:534)

Aaaanyway. The cause of this turned out to be that I already had a version of Ant installed (1.6.5), using a CentOS RPM, which meant that the version deployed with Cruise Control (1.7.0) wasn’t actually running. I have no idea why that was, but removing the CentOS RPM seemed to work! I think it might have been something to do with using the native library (the ant-1.6.5.jar.so should have given it away really…)

Just another one of those ‘gotchas’ which might help someone else waste time trying to figure it out…

Cleaning up old Cruise Control artifacts November 12, 2007

Posted by Phill in General J2EE.
Tags: ,
comments closed

One of the minor issues I have with Cruise Control is that there is currently no easy way to remove old artifacts – they just stay there indefinitely. You will probably not want to keep artifacts around indefinitely, so I wrote a quick script to remove all artifacts except for the most recent X artifacts (where X is configurable).

This will work if you have one root artifacts directory, and then publish artifacts to subdirectories within that directory (i.e., your artifacts dir is /builds and your projects are published to /builds/project-name).

It’s a Python script, and I have a cron job set to run it every ten minutes.

Note: apologies for the formatting, WordPress seems to screw up a bit when copying and pasting in code…

#! /usr/bin/env python
# ==== Variables ====
ARTIFACTS_DIR="changeme"
NUM_BUILDS_TO_KEEP=10
# ==== End Variables ====

import os

def rm_recursive(path):
	"""Removes a directory recursively"""

	for root, dirs, files in os.walk(path, topdown=False):
		for name in files:
			os.remove(os.path.join(root, name))
		for name in dirs:
			os.rmdir(os.path.join(root, name))
		os.rmdir(path)

def delete_old_builds(path):
	"""Deletes old builds"""

	builds = os.listdir(path)
	if len(builds) <= NUM_BUILDS_TO_KEEP:
		print "No builds to delete"
		return

	builds.sort()
	builds.reverse()

	i = 0

	for build in builds:
		i += 1
		if i <= NUM_BUILDS_TO_KEEP:
			continue

		print "Deleting", build
		rm_recursive(os.path.join(path, build))

for file in os.listdir(ARTIFACTS_DIR):
	path = os.path.join(ARTIFACTS_DIR, file)

	if (os.path.isdir(path)):
		delete_old_builds(path)

Setting up Cruise Control November 8, 2007

Posted by Phill in Tutorials.
Tags: , , ,
comments closed

In a strange coincidence, after last week’s blog post about building applications using a continuous integration tool, the past couple of days I’ve been setting up a new instance of Cruise Control.

So, I thought I would use the opportunity to write a quick guide on installing Cruise Control and setting it up with a Subversion-based project. When I say “quick guide”, I basically mean explaining a few of the problems that I came across – not a comprehensive guide going through every step of the process!

Firstly, you need to download and install Cruise Control. I was installing it on CentOS (Linux), so I used the cruisecontrol-bin-2.7.1.zip. Installation is fairly simple, just unzip the archive somewhere – see the ‘Getting Started‘ page for details.

Note: Cruise Control, on Linux at least, expects an environment variable “JAVA_HOME” to be set up. You may need to add this into cruisecontrol.sh or your .profile file so that you don’t have to set it each time you run Cruise Control.

Secondly, you need to set up a project. Cruise Control comes with an example already set up, so I won’t go into the details of what exactly you need to do. However, there are a few things that caught me out:

  • The svnbootstrapper’s purpose is not to update the working copy from the repository. Its purpose is to update (for example) a build ant script from the repository so that you always build using the latest version. More on that later (see cc-build.xml).
  • If your Subversion repository is not set up for anonymous access, you will need to modify the provided configuration example to include a username and password both for <svnbootstrapper…> and <svn localWorkingCopy…>.
  • You will need to write a new ant script to update your local working copy from the repository. Create a new ant script and name it something like cc-build.xml, and copy and paste the following into it:
<project name="Project" default="cc-build" basedir="." >
	<property name="base.dir" value="." />
	<import file="build.xml" />
	<target name="cc-build" depends="update-src" description="Cruise Control Build">
		<antcall target="build" />
	</target>
	<target name="update-src">
		<echo>Updating source from Subversion</echo>
		<exec executable="svn" dir="${base.dir}">
			<arg line="up" />
		</exec>
	</target>
</project>

Then, what you need to do is modify your <schedule…> task as follows:

<schedule interval="300">
	<ant anthome="apache-ant-1.7.0" buildfile="projects/${project.name}/cc-build.xml" />
</schedule>

What does this do? Well, let’s assume your project uses an ant build script, called build.xml. The cc-build.xml imports this file, and then will update the repository to the working copy (the update-src task), and then will call the “build” target in the build.xml file.

Note: the “svn” command line client will need to be available from your PATH.

So, once you’ve got all this set up, you should find that when you commit to the repository, Cruise Control will detect this, update your working copy to the latest version, and then run the build script. If you browse to http://servername:8080 you should be able to see the results!

Hopefully that should be enough pointers to get you up and running without too much trouble…

Building applications November 1, 2007

Posted by Phill in General J2EE, Other Stuff.
Tags: , , , ,
comments closed

I came across this email exchange today, courtesy of today’s post at Jeff Atwood’s blog.

Unfortunately the scenario was all-too-familiar for me: in my first job as a developer, I was working for a small company. This meant that we were very busy, and little things like documentation were often missed (of course, this is something which bigger companies have been guilty of as well…) My development workstation became “The development machine”. This meant that when we needed to deploy an application, someone would come to me and say “Phill, we need a new EAR file for application x” (it wasn’t actually called ‘application x’, but actually that would have been kind of cool). I would then go into my IDE, open up the project, and run the build process.

The problem came when I needed to get someone else up to speed on the project… trying to get someone else’s IDE to be exactly the same as yours is a total nightmare. The dependencies were all over the place, it took hours to get it all up and running.

(more…)

Follow

Get every new post delivered to your Inbox.