<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Machines</title>
	<atom:link href="http://www.trampolinesystems.com/blog/machines/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.trampolinesystems.com/blog/machines</link>
	<description>Ideas, thoughts and observations from Trampoline's technical brains</description>
	<pubDate>Thu, 03 Jul 2008 10:47:13 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5</generator>
	<language>en</language>
			<item>
		<title>removing global fixtures for ruby tests</title>
		<link>http://www.trampolinesystems.com/blog/machines/2008/07/02/removing-global-fixtures-for-ruby-tests/</link>
		<comments>http://www.trampolinesystems.com/blog/machines/2008/07/02/removing-global-fixtures-for-ruby-tests/#comments</comments>
		<pubDate>Wed, 02 Jul 2008 12:20:22 +0000</pubDate>
		<dc:creator>mccraig</dc:creator>
		
		<category><![CDATA[Programming]]></category>

		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.trampolinesystems.com/blog/machines/?p=27</guid>
		<description><![CDATA[global fixtures are evil, but we&#8217;ve got a bunch of unit tests depending on them, so we still need them around
here&#8217;s a neat [and generally fast, though a degenerate O(#tables^2) case is possible] way of deleting all fixtures without invoking db dependent ways of ignoring foreign-key constraints, and without loading all the objects into memory [...]]]></description>
			<content:encoded><![CDATA[<p>global fixtures are evil, but we&#8217;ve got a bunch of unit tests depending on them, so we still need them around</p>
<p>here&#8217;s a neat [and generally fast, though a degenerate O(#tables^2) case is possible] way of deleting all fixtures without invoking db dependent ways of ignoring foreign-key constraints, and without loading all the objects into memory :</p>
<pre>classes = ActiveRecord::Base.connection.tables.map {|t|
  t.singularize.camelize.constantize rescue nil
}.compact.reject{|cls| !cls.ancestors.include?(ActiveRecord::Base)}

while classes.size &gt; 0
  classes = classes.select{|c|
    begin
      c.delete_all
      false
    rescue
      true
    end
  }.reverse!
end</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.trampolinesystems.com/blog/machines/2008/07/02/removing-global-fixtures-for-ruby-tests/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Open Visualisation Workshop at the Trampery</title>
		<link>http://www.trampolinesystems.com/blog/machines/2008/05/21/open-visualisation-workshop-at-the-trampery/</link>
		<comments>http://www.trampolinesystems.com/blog/machines/2008/05/21/open-visualisation-workshop-at-the-trampery/#comments</comments>
		<pubDate>Wed, 21 May 2008 18:49:42 +0000</pubDate>
		<dc:creator>jan</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.trampolinesystems.com/blog/machines/?p=25</guid>
		<description><![CDATA[Trampoline Systems is hosting a visualisation workshop this coming Saturday, 24th May, organised by the Open Knowledge Foundation. Come along if you&#8217;re interested in open source visualisation technologies (Prefuse, Flare etc.). The goal is to have a very informal setting to talk about various aspects of visualising data. Find out more in the official announcement.
Hope [...]]]></description>
			<content:encoded><![CDATA[<p>Trampoline Systems is hosting a visualisation workshop this coming Saturday, 24th May, organised by the <a href="http://www.okfn.org/">Open Knowledge Foundation</a>. Come along if you&#8217;re interested in open source visualisation technologies (<a href="http://prefuse.org/">Prefuse</a>, Flare etc.). The goal is to have a very informal setting to talk about various aspects of visualising data. Find out more in the<a href="http://blog.okfn.org/2008/05/20/open-visualisation-workshop-saturday-24th-may-2008-trampoline-systems/"> official announcement.</a></p>
<p>Hope to see you here!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.trampolinesystems.com/blog/machines/2008/05/21/open-visualisation-workshop-at-the-trampery/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Creating DMG Files Without MacOS X</title>
		<link>http://www.trampolinesystems.com/blog/machines/2008/05/19/creating-dmg-files-without-macos-x/</link>
		<comments>http://www.trampolinesystems.com/blog/machines/2008/05/19/creating-dmg-files-without-macos-x/#comments</comments>
		<pubDate>Mon, 19 May 2008 16:07:55 +0000</pubDate>
		<dc:creator>jon</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[Mac]]></category>

		<category><![CDATA[dmg]]></category>

		<category><![CDATA[os x]]></category>

		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.trampolinesystems.com/blog/machines/?p=24</guid>
		<description><![CDATA[
I&#8217;ve put together a script for creating DMG files without using OS X&#8230;it requires Linux, I&#8217;ve tested it on Kubuntu 7.10 but it should work on anything recent.
Run the following commands:
# This gets and builds a patched version of Apple's diskdev_cmds package which will work on Linux
wget http://www.mythic-beasts.com/resources/appletv/mb_boot_tv/diskdev_cmds-332.14.tar.gz
wget http://www.ecl.udel.edu/~mcgee/diskdev_cmds/diskdev_cmds-332.14.patch.bz2
tar xzf diskdev_cmds-332.14.tar.gz
bunzip2 -c diskdev_cmds-332.14.patch.bz2 &#124; patch [...]]]></description>
			<content:encoded><![CDATA[<div>
<p>I&#8217;ve put together a script for creating DMG files without using OS X&#8230;it requires Linux, I&#8217;ve tested it on Kubuntu 7.10 but it should work on anything recent.</p>
<p>Run the following commands:</p>
<pre># This gets and builds a patched version of Apple's diskdev_cmds package which will work on Linux
wget <a class="moz-txt-link-freetext" href="http://www.mythic-beasts.com/resources/appletv/mb_boot_tv/diskdev_cmds-332.14.tar.gz">http://www.mythic-beasts.com/resources/appletv/mb_boot_tv/diskdev_cmds-332.14.tar.gz</a>
wget <a class="moz-txt-link-freetext" href="http://www.ecl.udel.edu/%7Emcgee/diskdev_cmds/diskdev_cmds-332.14.patch.bz2">http://www.ecl.udel.edu/~mcgee/diskdev_cmds/diskdev_cmds-332.14.patch.bz2</a>
tar xzf diskdev_cmds-332.14.tar.gz
bunzip2 -c diskdev_cmds-332.14.patch.bz2 | patch -p0
cd diskdev_cmds-332.14
make -f Makefile.lnx

# Create symlinks to the mkfs and fsck commands for HFS+
sudo cp newfs_hfs.tproj/newfs_hfs /sbin/mkfs.hfsplus
sudo cp fsck_hfs.tproj/fsck_hfs /sbin/fsck.hfsplus

# Get and enable the hfsplus kernel module
sudo apt-get install hfsplus
sudo modprobe hfsplus

<span style="font-family: sans-serif;">Now that&#8217;s done, you can use the following handy bash script (must be run as root) I&#8217;ve written to create a DMG file which contains the contents of a directory you specify on the command line.
<span style="font-family: 'Courier New',Courier,monospace;">
</span></span>#!/bin/bash

# DMG Creation Script
# Usage: makedmg &lt;imagename&gt; &lt;imagetitle&gt; &lt;imagesize (MB)&gt; &lt;contentdir&gt;
#
# imagename: The output file name of the image, ie foo.dmg
# imagetitle: The title of the DMG File as displayed in OS X
# imagesize: The size of the DMG you&#8217;re creating in MB (Blame Linux for the fixed size limitation!!)
# contentdir: The directory containing the content you want the DMG file to contain
#
# Example: makedmg foo.dmg &#8220;Script Test&#8221; 50 /home/jon/work/scripts/content
#
# Author: Jon Cowie
# Creation Date: 02/04/2008

if [ ! $# == 4 ]; then
	echo &#8220;Usage: makedmg &lt;imagename&gt; &lt;imagetitle&gt; &lt;imagesize (MB)&gt; &lt;contentdir&gt;&#8221;
else
	OUTPUT=$1
	TITLE=$2
	FILESIZE=$3
	CONTENTDIR=$4
	USER=`whoami`
	TMPDIR=&#8221;/tmp/dmgdir&#8221;

	if [ ${USER} != &#8220;root&#8221; ]; then
		echo &#8220;makedmg must be run as root!&#8221;
	else
		echo &#8220;Creating DMG File&#8230;&#8221;
		dd if=/dev/zero of=${OUTPUT} bs=1M count=$FILESIZE
		mkfs.hfsplus -v &#8220;${TITLE}&#8221; ${OUTPUT}

		echo &#8220;Mounting DMG File&#8230;&#8221;
		mkdir -p ${TMPDIR}
		mount -t hfsplus -o loop ${OUTPUT} ${TMPDIR} 

		echo &#8220;Copying content to DMG File&#8230;&#8221;
		cp -R ${CONTENTDIR}/* ${TMPDIR}

		echo &#8220;Unmounting DMG File&#8230;&#8221;
		umount ${TMPDIR}
		rm -rf ${TMPDIR}

		echo &#8220;All Done!&#8221;
	fi
fi
<span style="font-family: sans-serif;">
</span></pre>
<p>Hope it&#8217;s useful!</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.trampolinesystems.com/blog/machines/2008/05/19/creating-dmg-files-without-macos-x/feed/</wfw:commentRss>
		</item>
		<item>
		<title>@media Ajax 2007</title>
		<link>http://www.trampolinesystems.com/blog/machines/2007/09/05/media-ajax-2007/</link>
		<comments>http://www.trampolinesystems.com/blog/machines/2007/09/05/media-ajax-2007/#comments</comments>
		<pubDate>Wed, 05 Sep 2007 07:00:02 +0000</pubDate>
		<dc:creator>mike</dc:creator>
		
		<category><![CDATA[Internet]]></category>

		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://trampoline.neue-dev.co.uk/blog/machines/?p=5</guid>
		<description><![CDATA[I have the honour and terror of presenting at @media Ajax on home turf this November. It’s a privilege to be speaking alongside the likes of Brendan Eich (creator of Javascript), Douglas Crockford (inventor of JSON), John Resig (JQuery lead) and about a dozen other top dogs.]]></description>
			<content:encoded><![CDATA[<p>I have the honour and terror of presenting at <a href="http://www.vivabit.com/atmediaAjax/">@media Ajax</a> on home turf this November. It’s a privilege to be speaking alongside the likes of <a href="http://www.vivabit.com/atmediaAjax/speakers/#brendan">Brendan Eich</a> (creator of Javascript), <a href="http://www.vivabit.com/atmediaAjax/speakers/#douglas">Douglas Crockford</a> (inventor of JSON), <a href="http://www.vivabit.com/atmediaAjax/speakers/#john">John Resig</a> (JQuery lead) and about <a href="http://www.vivabit.com/atmediaAjax/speakers/">a dozen other top dogs</a>.</p>
<p>In a lineup like that I clearly can’t talk about nuts and bolts Javascript. Instead I’m taking a slightly unusual tack for me: revelations. Since Ajax came along my job has changed in ways I wouldn’t have predicted. Technically I’m a flavour of designer yet after many years of specialising I’ve found myself having to skill up again.</p>
<ul>
<li>To keep a handle on what the rest of the team produce I’ve become a testing fanatic;</li>
<li>I’ve had to go back and relearn how to program - not to necessarily produce back-end code but to understand what the real implications of my design decisions are;</li>
<li>I’ve been converted to Agile practices as a means of effective collaboration.</li>
</ul>
<p>None of these things are traditionally within the remit of ‘design’ but they all feed into producing a successful app. To try and describe these changes and what I’ve done about them I will be presenting <a href="http://www.vivabit.com/atmediaAjax/sessions/#but">But I’m a Bloody Designer!</a> on the first day, straight after the keynote by the <a href="http://www.vivabit.com/atmediaAjax/sessions/#state">Ajaxians</a>.</p>
<p>So, the lineup’s great, it’s in London. @media Ajax: coming soon. Say hello if you decide to come…</p>
]]></content:encoded>
			<wfw:commentRss>http://www.trampolinesystems.com/blog/machines/2007/09/05/media-ajax-2007/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Springy 0.3 released</title>
		<link>http://www.trampolinesystems.com/blog/machines/2007/08/02/springy-03-released/</link>
		<comments>http://www.trampolinesystems.com/blog/machines/2007/08/02/springy-03-released/#comments</comments>
		<pubDate>Thu, 02 Aug 2007 07:01:39 +0000</pubDate>
		<dc:creator>jan</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Programming]]></category>

		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://trampoline.neue-dev.co.uk/blog/machines/?p=6</guid>
		<description><![CDATA[No big changes this time, mainly compatibility fixes for JRuby 1.0. It is now also possible to build the project using Maven, for those too afraid to use rake. Documentation and code for springy are available here.]]></description>
			<content:encoded><![CDATA[<p>No big changes this time, mainly compatibility fixes for JRuby 1.0. It is now also possible to build the project using Maven, for those too afraid to use rake. Documentation and code for springy are available <a href="http://code.trampolinesystems.com/springy">here</a>.</p>
<p>I’m also happy to announce that <a href="http://www.jroller.com/habuma/">Craig Walls</a>, the author of “Spring in Action”, is going to talk about Springy as part of his “<a href="http://www.thespringexperience.com/speaker_topic_view.jsp?topicId=303">Spring Cleaning: Tips for Managing XML Clutter</a>” talk at this year’s <a href="http://www.nofluffjuststuff.com/">No Fluff Just Stuff</a> series of events as well as the Spring Experience 2007 in Florida.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.trampolinesystems.com/blog/machines/2007/08/02/springy-03-released/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Tracing file access on Mac OSX</title>
		<link>http://www.trampolinesystems.com/blog/machines/2007/07/24/tracing-file-access-on-mac-osx/</link>
		<comments>http://www.trampolinesystems.com/blog/machines/2007/07/24/tracing-file-access-on-mac-osx/#comments</comments>
		<pubDate>Tue, 24 Jul 2007 07:05:24 +0000</pubDate>
		<dc:creator>Tomasz</dc:creator>
		
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://trampoline.neue-dev.co.uk/blog/machines/?p=7</guid>
		<description><![CDATA[I just started working at Trampoline Systems yesterday. Some of you might know my blog already (the one with kitten pics and programming rants). The first thing I did was configuring all the software on my new MacBook. Most of it went all right without any problems, but a few gems didn’t want to install, complaining about jni.h missing. jni.h was on the box, so the problem was basically that the gems were looking for it in a wrong place. Problems like that can usually be solved by strace -e trace=file gem install whatever &#124; grep 'jni.h' and a symlink. Not this time, because Macs does have strace. There’s something called ktrace, but it didn’t seem to provide information I needed.]]></description>
			<content:encoded><![CDATA[<p>I just started working at Trampoline Systems yesterday. Some of you might know <a href="http://t-a-w.blogspot.com/">my blog</a> already (the one with kitten pics and programming rants). The first thing I did was configuring all the software on my new MacBook. Most of it went all right without any problems, but a few gems didn’t want to install, complaining about <code>jni.h</code> missing. <code>jni.h</code> was on the box, so the problem was basically that the gems were looking for it in a wrong place. Problems like that can usually be solved by <code>strace -e trace=file gem install whatever | grep 'jni.h'</code> and a symlink. Not this time, because Macs does have <code>strace</code>. There’s something called <code>ktrace</code>, but it didn’t seem to provide information I needed.</p>
<p>Full <code>strace</code> may be impossible without heave kernel hacking, but it’s not hard to <a href="http://t-a-w.blogspot.com/2007/03/how-to-code-debuggers.html">write a simple file access tracing utility</a>. The one I coded uses <code>LD_PRELOAD</code>-like trick to override <code>open</code> and <code>stat</code> functions in <code>libc</code>. These two usually provide most of the usuful information about file access, and if anything more was needed the utility can be easily extended.</p>
<p>The library is very simple:</p>
<pre><code>#include &lt;unistd.h&gt;
#include &lt;stdio.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;dlfcn.h&gt;
#include &lt;errno.h&gt;
#include "errno_names.h"

/* Probably not thread-safe. I have no idea what's thread-interpretation of
dlsym(RTLD_NEXT, ...), even assuming atomic assignment to variables
*/
int (*real_open)(const char *path, int flags, mode_t mode) = 0;
int (*real_stat)(const char *path, struct stat *sb) = 0;

void report_errno(int retval)
{
if(retval == -1 &amp;&amp; errno &gt;= 0 &amp;&amp; errno &lt;= ELAST) {
fprintf(stderr, " (%s)n", errno_names_table[errno]);
} else {
fprintf(stderr, "n");
}
}

int open(const char *path, int flags, mode_t mode)
{
int retval;

if(real_open == 0)
real_open = dlsym(RTLD_NEXT, "open");
retval = real_open(path, flags, mode);

fprintf(stderr, "open("%s", ...) = %d", path, retval);
report_errno(retval);

return retval;
}

int stat(const char *path, struct stat *sb)
{
int retval;

if(real_stat == 0)
real_stat = dlsym(RTLD_NEXT, "stat");
retval = real_stat(path, sb);

fprintf(stderr, "stat("%s", ...) = %d", path, retval);
report_errno(retval);

return retval;
}
</code></pre>
<p>Fist of error names in <code>errno_names.h</code> is generated by <code>Rakefile</code>, which looks like that (stripping the testing-related parts):</p>
<pre><code>desc "Build trace_file_access library"
task :build =&gt; "libtfa.dylib"

file "libtfa.dylib" =&gt; ["errno_names.h", "libtfa.c"] do
sh "gcc", "-O6", "libtfa.c", "-dynamiclib", "-fPIC", "-o", "libtfa.dylib"
end

file "errno_names.h" do
errnos = []
File.open("/usr/include/sys/errno.h").each{|line|
errnos[$2.to_i] = $1 if line =~ /A#defines+(E[A-Z]+)s+(d+)/
}
File.open("errno_names.h", "w") {|fh|
fh.puts "/*n * This code is automatically generated by the Rakefilen * Do not modify by handn */"
fh.puts "static const char *errno_names_table [] = {"
errnos.each_with_index{|name, i|
fh.puts "  "#{name}", /* #{i} */"
}
fh.puts "};"
}
end
</code></pre>
<p>Finally <code>trace_file_access command</code> script sets up the tracing, with the results looking like this:      #!/usr/bin/env ruby</p>
<pre><code>ENV["DYLD_FORCE_FLAT_NAMESPACE"] = "1"
ENV["DYLD_INSERT_LIBRARIES"] = "./libtfa.dylib"
exec *ARGV

$ ./trace_file_access ruby -e 'require "rational"'
open("/dev/urandom", ...) = 3
stat("/opt/local/lib/ruby/site_ruby/1.8/rational.rb", ...) = -1 (ENOENT)
stat("/opt/local/lib/ruby/site_ruby/1.8/rational.bundle", ...) = -1 (ENOENT)
stat("/opt/local/lib/ruby/site_ruby/1.8/i686-darwin8.9.3/rational.rb", ...) = -1 (ENOENT)
stat("/opt/local/lib/ruby/site_ruby/1.8/i686-darwin8.9.3/rational.bundle", ...) = -1 (ENOENT)
stat("/opt/local/lib/ruby/site_ruby/rational.rb", ...) = -1 (ENOENT)
stat("/opt/local/lib/ruby/site_ruby/rational.bundle", ...) = -1 (ENOENT)
stat("/opt/local/lib/ruby/vendor_ruby/1.8/rational.rb", ...) = -1 (ENOENT)
stat("/opt/local/lib/ruby/vendor_ruby/1.8/rational.bundle", ...) = -1 (ENOENT)
stat("/opt/local/lib/ruby/vendor_ruby/1.8/i686-darwin8.9.3/rational.rb", ...) = -1 (ENOENT)
stat("/opt/local/lib/ruby/vendor_ruby/1.8/i686-darwin8.9.3/rational.bundle", ...) = -1 (ENOENT)
stat("/opt/local/lib/ruby/vendor_ruby/rational.rb", ...) = -1 (ENOENT)
stat("/opt/local/lib/ruby/vendor_ruby/rational.bundle", ...) = -1 (ENOENT)
stat("/opt/local/lib/ruby/1.8/rational.rb", ...) = 0
open("/opt/local/lib/ruby/1.8/rational.rb", ...) = 3
stat("/opt/local/lib/ruby/site_ruby/1.8/rational.rb", ...) = -1 (ENOENT)
stat("/opt/local/lib/ruby/site_ruby/1.8/i686-darwin8.9.3/rational.rb", ...) = -1 (ENOENT)
stat("/opt/local/lib/ruby/site_ruby/rational.rb", ...) = -1 (ENOENT)
stat("/opt/local/lib/ruby/vendor_ruby/1.8/rational.rb", ...) = -1 (ENOENT)
stat("/opt/local/lib/ruby/vendor_ruby/1.8/i686-darwin8.9.3/rational.rb", ...) = -1 (ENOENT)
stat("/opt/local/lib/ruby/vendor_ruby/rational.rb", ...) = -1 (ENOENT)
stat("/opt/local/lib/ruby/1.8/rational.rb", ...) = 0
open("/opt/local/lib/ruby/1.8/rational.rb", ...) = 3
open("/opt/local/lib/ruby/1.8/rational.rb", ...) = 3
open("/opt/local/lib/ruby/1.8/rational.rb", ...) = 3
open("/opt/local/lib/ruby/1.8/rational.rb", ...) = 3
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.trampolinesystems.com/blog/machines/2007/07/24/tracing-file-access-on-mac-osx/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Java and Rails integration with GoldSpike</title>
		<link>http://www.trampolinesystems.com/blog/machines/2007/07/13/java-and-rails-integration-with-goldspike/</link>
		<comments>http://www.trampolinesystems.com/blog/machines/2007/07/13/java-and-rails-integration-with-goldspike/#comments</comments>
		<pubDate>Fri, 13 Jul 2007 07:06:53 +0000</pubDate>
		<dc:creator>jan</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://trampoline.neue-dev.co.uk/blog/machines/?p=8</guid>
		<description><![CDATA[While trying to create a unified testing framework (shared between Rails and our Java backend code) I came across ActiveRecordJDBC which is an adapter to use JDBC drivers with JRuby on Rails. It works fine, although it can be a bit complicated to get a DRY database.yml configuration. The goal is to get rid of our dbunit/manually crafted database tests on the Java side by using ActiveRecord fixtures. After some research I found out about the Rails integration project (now called GoldSpike), which tries to make it easy to deploy a Rails app on a Java servlet container such as jetty. As far as I know Thoughtworks uses this approach to deploy their new product, Mingle. GoldSpike is under constant development but it is already usable, although a few patches were required. After everything was set up, a simple]]></description>
			<content:encoded><![CDATA[<p>While trying to create a unified testing framework (shared between Rails and our Java backend code) I came across <a href="http://jruby-extras.rubyforge.org/ActiveRecord-JDBC/">ActiveRecordJDBC</a> which is an adapter to use JDBC drivers with JRuby on Rails. It works fine, although it can be a bit complicated to get a DRY database.yml configuration. The goal is to get rid of our dbunit/manually crafted database tests on the Java side by using ActiveRecord fixtures. After some research I found out about the Rails integration project (now called GoldSpike), which tries to make it easy to deploy a Rails app on a Java servlet container such as jetty. As far as I know Thoughtworks uses this approach to deploy their new product, <a href="http://studios.thoughtworks.com/mingle-project-intelligence">Mingle</a>. GoldSpike is under constant development but it is already usable, although a few patches were required. After everything was set up, a simple</p>
<pre><code>
$ rake war:standalone:create
Reading user configuration
Assembling web application
Adding Java library commons-pool-1.3
Adding Java library rails-integration-1.1.1
Adding Java library activation-1.1
Adding Java library mysql-connector-java-5.0.5
Adding Java library bcprov-jdk14-124
Adding Java library jruby-complete-1.0
Adding web application
Adding Ruby gem ActiveRecord-JDBC version 0.4
Creating web archive
</code></pre>
<p>creates a .war file which can be directly deployed to a container. I’ve never been a big fan of war files, but in the context of JRuby+Rails it makes perfect sense, because Ruby and all the required gems can be packaged up in a single file. No need to worry about missing gems, C bindings or wrong versions of the installed software, all you need to deploy is Java and jetty (which is pretty lightweight).</p>
<p>Not quite sure what the implications of this are, but it seems like a good alternative to mongrel/CRuby deployments. Performance-wise it looks good, too, though we haven’t done any benchmarking. GoldSpike doesn’t have a project homepage yet, but you can find it on the <a href="http://rubyforge.org/projects/jruby-extras">jruby-extras</a> project page. Let’s wait and see what this will mean for the adoption of Rails in corporate environments (Oracle is currently <a href="http://oracleappslab.com/2007/07/06/are-you-passionate-about-ruby-on-rails-were-hiring/">looking</a> for Rails developers to join the Enterprise 2.0 team, for example).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.trampolinesystems.com/blog/machines/2007/07/13/java-and-rails-integration-with-goldspike/feed/</wfw:commentRss>
		</item>
		<item>
		<title>growl-lastfm</title>
		<link>http://www.trampolinesystems.com/blog/machines/2007/07/10/growl-lastfm/</link>
		<comments>http://www.trampolinesystems.com/blog/machines/2007/07/10/growl-lastfm/#comments</comments>
		<pubDate>Tue, 10 Jul 2007 07:08:09 +0000</pubDate>
		<dc:creator>jan</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://trampoline.neue-dev.co.uk/blog/machines/?p=9</guid>
		<description><![CDATA[We use last.fm a lot in the office - but one thing I always found annoying was that there’s no easy way to find out what’s currently playing (you need to go to the web page and hit refresh, very distracting) so I knocked up a little ruby script which uses growl to display the currently playing song.]]></description>
			<content:encoded><![CDATA[<p>We use <a href="http://last.fm/">last.fm</a> a lot in the office - but one thing I always found annoying was that there’s no easy way to find out what’s currently playing (you need to go to the web page and hit refresh, very distracting) so I knocked up a little ruby script which uses <a href="http://growl.info/">growl</a> to display the currently playing song.</p>
<pre><code class="ruby">
<span class="comment">#!/usr/bin/env ruby</span>
<span class="keywords">require</span> <span class="string">&#8216;rubygems&#8217;</span>
<span class="keywords">require</span> <span class="string">&#8216;ruby-growl&#8217;</span>
<span class="keywords">require</span> <span class="string">&#8216;hpricot&#8217;</span>
<span class="keywords">require</span> <span class="string">&#8216;cgi&#8217;</span>
<span class="keywords">require</span> <span class="string">&#8216;open-uri&#8217;</span>

<span class="keywords">raise</span> <span class="string">&#8220;#{$0} &lt;user&gt;&#8221;</span> <span class="keywords">if</span> ARGV.empty?
user = ARGV[0]
already_notified = []

<span class="keywords">while</span> true <span class="keywords">do</span>
now_listening = Hpricot<span class="brackets">(</span>open<span class="brackets">(</span><span class="string">&#8220;http://www.last.fm/user/#{user}&#8221;</span><span class="brackets">)</span><span class="brackets">)</span>/<span class="string">&#8220;.nowListening td.subject&#8221;</span>
<span class="keywords">unless</span> now_listening.empty?
currently_played = now_listening.last.inner_text.strip
<span class="keywords">unless</span> already_notified.include?<span class="brackets">(</span>currently_played<span class="brackets">)</span>
already_notified &lt;&lt; currently_played
g = Growl.new<span class="brackets">(</span><span class="string">&#8220;localhost&#8221;</span>, <span class="string">&#8220;ruby-growl&#8221;</span>, [<span class="string">&#8220;ruby-growl Notification&#8221;</span>]<span class="brackets">)</span>
g.notify<span class="brackets">(</span><span class="string">&#8220;ruby-growl Notification&#8221;</span>, <span class="string">&#8220;#{user} is listening to&#8221;</span>,
CGI::unescapeHTML<span class="brackets">(</span>currently_played<span class="brackets">)</span><span class="brackets">)</span>
<span class="keywords">end</span>
<span class="keywords">end</span>
sleep 60
<span class="keywords">end</span>
</code></pre>
<p>Make sure that you have hpricot and ruby-growl installed (<code>gem install hpricot ruby-growl -y</code>), then copy and paste the script (or <a href="http://code.trampolinesystems.com/jan/growl-lastfm.rb">download</a> it) and start it with a last.fm username as parameter. You also need to have “Listen for incoming notifications” and “Allow remote registration” checked in growl’s preferences (System Preferences | Growl | Network).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.trampolinesystems.com/blog/machines/2007/07/10/growl-lastfm/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Select distinct with XSLT</title>
		<link>http://www.trampolinesystems.com/blog/machines/2007/07/06/select-distinct-with-xslt/</link>
		<comments>http://www.trampolinesystems.com/blog/machines/2007/07/06/select-distinct-with-xslt/#comments</comments>
		<pubDate>Fri, 06 Jul 2007 07:09:07 +0000</pubDate>
		<dc:creator>mike</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[XSLT]]></category>

		<guid isPermaLink="false">http://trampoline.neue-dev.co.uk/blog/machines/?p=10</guid>
		<description><![CDATA[While working on some tweaks to our website I decided that for the archive I needed to be able to select a list of categories used. Should be easy, right? Here’s a sample of the XML:]]></description>
			<content:encoded><![CDATA[<p>While working on some tweaks to our website I decided that for the archive I  needed to be able to select a list of categories used. Should be easy, right? Here’s a sample of the XML:</p>
<pre><code>&lt;machines-archive section="weblog" section-id="3"&gt;
&lt;entry id="78" handle="installing-oracle-10g-on-64-bit-centos-5" linked-count="0"&gt;
&lt;date year="2007" month="06" date="28" weekday="4"&gt;2007-06-28&lt;/date&gt;
&lt;time hour="12" minute="35"&gt;12:35&lt;/time&gt;
&lt;author /&gt;
&lt;fields&gt;
&lt;title handle="installing-oracle-10g-on-64-bit-centos-5"&gt;installing Oracle 10g on 64 bit centos 5&lt;/title&gt;
&lt;categories&gt;
&lt;item handle="ruby"&gt;Ruby&lt;/item&gt;
&lt;item handle="java"&gt;Java&lt;/item&gt;
&lt;item handle="programming"&gt;Programming&lt;/item&gt;
&lt;item handle="code"&gt;Code&lt;/item&gt;
&lt;/categories&gt;
&lt;/fields&gt;
&lt;comments count="0" spam="0" /&gt;
&lt;/entry&gt;
&lt;entry id="75" handle="compulsory-wearing-of-facial-hair" linked-count="0"&gt;
&lt;date year="2007" month="06" date="14" weekday="4"&gt;2007-06-14&lt;/date&gt;
&lt;time hour="14" minute="15"&gt;14:15&lt;/time&gt;
&lt;author /&gt;
&lt;fields&gt;
&lt;title handle="compulsory-wearing-of-facial-hair"&gt;compulsory wearing of facial hair&lt;/title&gt;
&lt;categories&gt;
&lt;item handle="programming"&gt;Programming&lt;/item&gt;
&lt;/categories&gt;
&lt;/fields&gt;
&lt;comments count="0" spam="0" /&gt;
&lt;/entry&gt;
&lt;/machines-archive&gt;
</code></pre>
<p>I’m trying to get at machines-archive//item so this ought to would work, right?</p>
<pre><code>&lt;xsl:template match="machines-archive"&gt;
&lt;xsl:for-each select=".//item[not(@handle = preceding::item/@handle)]"&gt;
&lt;xsl:sort select="@handle" order="ascending"/&gt;
&lt;xsl:value-of select="@handle" /&gt;&lt;xsl:text&gt;, &lt;/xsl:text&gt;
&lt;/xsl:for-each&gt;
&lt;/xsl:template&gt;
</code></pre>
<p>All the forum posts and mailing list archives I searched assured me that this’d  be just fine… Except it wasn’t. It just didn’t work. Operating on all items in the document (<code>//item</code>) generated a distinct, de-duped set as expected, but as soon as I added the ‘.’ to work on a subset (<code>.//item</code>) it didn’t. Eh?!</p>
<p>Head-scratching, template-tweaking and <a href="http://www.google.co.uk/search?q=select+distinct+xsl&amp;ie=utf-8&amp;oe=utf-8&amp;aq=t&amp;rls=org.mozilla:en-US:official&amp;client=firefox-a">tedious Googling</a> ensued. I tried  everything I could think of and after several hours of a lot of searching I  eventually stumbled across a solution: <a href="http://www.exslt.org/set/set.html">EXSLT and set:distinct</a>.</p>
<p>I first needed to add: <code>xmlns:set="http://exslt.org/sets"</code> to my stylesheet’s  namespace. Then I could use set:distinct on my items:</p>
<pre><code>&lt;xsl:for-each select="set:distinct(.//item)"&gt;
&lt;xsl:sort select="@handle" order="ascending"/&gt;
&lt;xsl:value-of select="@handle" /&gt;&lt;xsl:text&gt;, &lt;/xsl:text&gt;
&lt;/xsl:for-each&gt;
</code></pre>
<p>Job done. No one was pointing out this most elegant of solutions anywhere I  found on the World Wide Web but it’s easy when you know how…</p>
]]></content:encoded>
			<wfw:commentRss>http://www.trampolinesystems.com/blog/machines/2007/07/06/select-distinct-with-xslt/feed/</wfw:commentRss>
		</item>
		<item>
		<title>installing Oracle 10g on 64 bit centos 5</title>
		<link>http://www.trampolinesystems.com/blog/machines/2007/06/28/installing-oracle-10g-on-64-bit-centos-5/</link>
		<comments>http://www.trampolinesystems.com/blog/machines/2007/06/28/installing-oracle-10g-on-64-bit-centos-5/#comments</comments>
		<pubDate>Thu, 28 Jun 2007 07:11:35 +0000</pubDate>
		<dc:creator>mccraig</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Programming]]></category>

		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://trampoline.neue-dev.co.uk/blog/machines/?p=11</guid>
		<description><![CDATA[We’ve just got ourselves a couple of new servers for running SONAR on, for internal use and demonstration. They are quite beefy, with 8GB RAM, 15k disks, and 8 x 3.2GHz threads. We decided to go with centos 5 as the operating system, since we have had pain installing Oracle on our debian platforms. Here is the install procedure I uncovered, which gets the server ready for SONAR on either MySQL or oracle. It covers installing Ruby, RubyGems, lots of useful Gems, Java, and Oracle 10g]]></description>
			<content:encoded><![CDATA[<p>We’ve just got ourselves a couple of new servers for running SONAR on, for internal use and demonstration. They are quite beefy, with 8GB RAM, 15k disks, and 8 x 3.2GHz threads. We decided to go with centos 5 as the operating system, since we have had pain installing Oracle on our debian platforms. Here is the install procedure I uncovered, which gets the server ready for SONAR on either MySQL or oracle. It covers installing Ruby, RubyGems, lots of useful Gems, Java, and Oracle 10g</p>
<pre><code>yum install -y ruby
yum install -y ruby-devel ruby-docs ruby-ri ruby-irb ruby-devel ruby-rdoc
yum install -y w3m # for text based browsing and downloading, where curl won't work

# download rubygems from rubygems.org with w3m then...
gunzip rubygems-0.9.4.tgz
tar xf rubygems-0.9.4.tar
cd rubygems-0.9.4
ruby setup.rb

# get jdk rpm from java.sun.com and install

# add an /etc/profile.d/java.sh file, containing
##
JAVA_HOME=/usr/java/default
export JAVA_HOME
##
chmod +x /etc/profile.d/java.sh
source /etc/profile.d/java.sh

yum install -y ImageMagick-devel
yum install -y perl-DBI
yum remove -y sendmail
yum install -y postfix
chkconfig postfix on
yum install -y ntp
chkconfig ntpd on
yum install -y mysql-server mysql mysql-devel

chkconfig mysqld on
/usr/bin/mysqladmin -u root password '&lt;password&gt;'
/usr/bin/mysqladmin -u root -h &lt;hostname&gt; password '&lt;password&gt;'

yum install -y gcc
gem install builder
gem install camping
gem install capistrano
gem install cgi_multipart_eof_fix
gem install cheat
gem install chronic
gem install ci_reporter
gem install daemons
gem install fastthread
gem install gem_plugin
gem install hpricot
gem install image_science
gem install jerbil --source http://code.trampolinesystems.com
gem install json
gem install markaby
gem install metaid
gem install mongrel
gem install needle
gem install net-sftp
gem install net-ssh
gem install rake
gem install rmagick  # [ ignore errors about fonts... they are just for the docs ]
yum install -y libxml2-devel
yum install -y libxslt-devel
gem install ruby-xslt
gem install rubyforge
gem install RubyInline
gem install mysql -- --build-flags --with-mysql-config
yum install -y httpd
yum install -y subversion

# install rpmforge for centos 5 as detailed here :
# http://wiki.centos.org/Repositories/RPMForge#head-d766e7aacdee6150c6705d9369aa36c9bcabc139

yum install -y firefox
yum install -y xorg-x11-xauth
yum install -y vnc-server
yum install -y emacs
yum install -y libXtst
yum install -y xorg-x11-utils
yum install -y xorg-x11-resutils
yum install -y xorg-x11-server-utils

yum install -y compat-libgcc-296 compat-libstdc++-296 compat-libstdc++-33 openmotif22
yum groupinstall -y "Development Libraries"
yum groupinstall -y "Development Tools"
yum groupinstall -y "Legacy Software Development"
yum groupinstall -y "Server Configuration Tools"
yum groupinstall -y "X Software Development"
yum groupinstall -y "Administration Tools"

# fire up a vncserver on the remote machine :
vncserver
# and enable connections to the X server from other accounts :
xhost +

# connect an ssh session from your local machine, forwarding the vnc port [ 5900 + screen # ]
# connect your local vnc client to the server
# run firefox on the server
# download oracle 10g from www.oracle.com, thus avoiding having to upload 750M at 512Kb/s
# install as shown here : http://www.dizwell.com/prod/node/681?page=0%2C3
# and add an init.d startup script as described here : http://www.dizwell.com/prod/node/50?page=0%2C4

# done ! reboot to check that your init.d scripts are functioning correctly
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.trampolinesystems.com/blog/machines/2007/06/28/installing-oracle-10g-on-64-bit-centos-5/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
