MacPorts, Clojure and ClassNotFoundException

After installing Clojure with MacPorts I got the following exception when running a basic Clojure script:

Exception in thread "main" java.lang.NoClassDefFoundError: Pad:/opt/local/share/java/clojure/bin////lib/clojure/jar
Caused by: java.lang.ClassNotFoundException: Pad:.opt.local.share.java.clojure.bin....lib.clojure.jar
	at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:247)

As it turned out, I had run the script from a folder with a space in it’s name, “Scratch Pad”. After moving the script to an other folder, the script ran just fine.

Grails, CoffeeScript and Eclipse

I’m using the Grails CoffeeScript plugin, but when running my Grails application from Eclipse, with run-app, I got the following error:

Compiling CoffeeScript Files ...ERROR Launching CoffeeScript compiler: Cannot run program "coffee": error=2, No such file or directory

Now, in order to fix this you need to tell the CoffeeScript Grails plugin where to find the coffee command. You can do this in BuildConfig.groovy by adding this line:

grails.coffeescript.compiler.location="/opt/local/bin/coffee"

But, this is not enough, because now I get the following error:

Compiling CoffeeScript Files ...env: node: No such file or directory

The solution I found to this problem was editing /opt/local/bin/coffee, changing

#!/usr/bin/env node to #!/opt/local/bin/node

please let me know if you have found a better solution.

Now I’m able to do run-app from within Eclipse.

Keep in mind that I’m on a Mac having installed CoffeeScript with npm, and node and npm with MacPorts. You might have your CoffeeScript installation in a different location.

How to sync MacPorts without rsync

If port 873 is blocked on your network and you need to sync MacPorts do this:

In /opt/local/etc/macports/sources.conf replace
rsync://rsync.macports.org/release/ports/ [default]
with
http://www.macports.org/files/ports.tar.gz [default]
and run
sudo port sync
instead of
sudo port selfupdate

MacPorts is now synching using http over port 80 instead of rsync over port 873.

Tuckey rewrite rule has new default value

After upgrading from Tuckey UrlRewrite 3.0 to 3.1 I noticed that the default value for the last attribute has changed from true to false, so I had to do some small changes to the xml configuration.

Old rules:

<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.0//EN"
		"http://www.tuckey.org/res/dtds/urlrewrite3.1.dtd">
<urlrewrite default-match-type="wildcard">
	<rule>
		<from>/images/**</from>
		<to>/images/$1</to>
	</rule>
	<rule>
		<from>/scripts/**</from>
		<to>/scripts/$1</to>
	</rule>
	<rule>
		<from>/styles/**</from>
		<to>/styles/$1</to>
	</rule>
 	<rule>
		<from>/**</from>
		<to>/app/$1</to>
	</rule>
	<outbound-rule>
		<from>/app/**</from>
		<to>/$1</to>
	</outbound-rule>
</urlrewrite>

New rules:

<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.1//EN"
		"http://www.tuckey.org/res/dtds/urlrewrite3.1.dtd">
<urlrewrite default-match-type="wildcard">
	<rule>
		<from>/images/**</from>
		<to last="true">/images/$1</to>
	</rule>
	<rule>
		<from>/scripts/**</from>
		<to last="true">/scripts/$1</to>
	</rule>
	<rule>
		<from>/styles/**</from>
		<to last="true">/styles/$1</to>
	</rule>
 	<rule>
		<from>/**</from>
		<to>/app/$1</to>
	</rule>
	<outbound-rule>
		<from>/app/**</from>
		<to>/$1</to>
	</outbound-rule>
</urlrewrite>

JavaScript speed test

I had to implement what I call a “row selector” for a web application.

It looks something like this (try it out by clicking the checkboxes in the first column):

Now, the tricky part is that this should work for large documents, say 500 rows.

I have implemented this with jQuery, Prototype, MooTools and pure JavaScript, and these are the results I get when toggling all 500 rows in IE8 on a Windows box with 512MB RAM:

  • jQuery 1.6.1: 2000ms
  • Prototype 1.7.0: 2450ms
  • MooTools 1.3.2: 6300ms (first toggle) / 1100ms
  • JavaScript: 250ms

These are some numbers for Firefox 5, running on the same machine:

  • jQuery 1.6.1: 150ms
  • Prototype 1.7.0: 120ms
  • MooTools 1.3.2: 230ms
  • JavaScript: 100ms

We have to support IE, so choosing the pure JavaScript version was a no-brainer.

Here are the results for the jQuery version on an iMac with 2GB RAM:

  • Google Chrome 12: 380ms
  • Safari 5: 150ms
  • Firefox 5: 140ms

It looks like Chrome is falling behind…

Try it out for yourself: jQuery, Prototype, MooTools and JavaScript.

CSS only drop-down menus (with submenus)

Who needs JavaScript to do drop-down menus on a HTML web-page? Anyway, I gave it a try.

This does not work in IE6, which we should stop supporting anyway (if you ask me).

With the following HTML:

<ul class="navbar">
	<li><div class="item">Meat</div></li>
	<li><div class="item">Vegetables</div></li>
	<li>
		<div class="item">Fruit and lots of fruit</div>
		<ul>
			<li><div class="item">Organge</div></li>
			<li>
				<div class="item">Apple</div>
				<ul>
					<li><div class="item">Fuji</div></li>
					<li><div class="item">Gala</div></li>
					<li>
						<div class="item">Granny Smith</div>
						<ul>
							<li><div class="item">Red</div></li>
							<li><div class="item">Green</div></li>
						</ul>
					</li>
				</ul>
			</li>
			<li><div class="item">Pomgranade</div></li>
		</ul>
	</li>
</ul>

just add this CSS:

.navbar, .navbar ul {
	list-style-type: none;
	margin: 0;
	padding: 0;
}

.navbar li {
	position: relative;
}

.navbar > li {
	display: inline-block;
}

.navbar ul {
	display: none;
	position: absolute;
}

.navbar li:hover > ul {
	display: block;
}

.navbar ul ul {
	left: 100%;
	top: 0;
}

Or if you want to support IE7 and IE8, use this less elegant CSS, using floating elements and clearfix:

.navbar {
	zoom: 1;
}

.navbar:after {
    content: ".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
}

.navbar, .navbar ul {
	list-style-type: none;
	margin: 0;
	padding: 0;
}

.navbar li {
	position: relative;
}

.navbar > li {
	float: left;
}

.navbar ul {
	display: none;
	position: absolute;
}

.navbar li:hover > ul {
	display: block;
}

.navbar ul ul {
	left: 100%;
	top: 0;
}

If you put it all together, this is what it looks like (with a tiny theme added):

Rotate backups with Bash script

Here is a simple script to rotate your backups:

#!/usr/bin/env bash

backup_location=/mnt/data/backups
max_number_of_backups=5

function number_of_backups() {
    echo `ls -1 $backup_location | wc -l`
}

function oldest_backup() {
	echo -n `ls -1 $BACKUP_LOCATION | head -1`
}

while [ $(number_of_backups) -gt $max_number_of_backups ]
do
    rm -rf "$backup_location/$(oldest_backup)"
done

You should of course change backup_location and max_number_of_backups to fit you environment and needs.

Event delegation with Prototype and MooTools

With jQuery you’ll have event delegation out of the box, but if you are using Prototype or MooTools you are less fortunate – that’s until now!

I have implemented a generic event delegation JavaScript library. It works for change, submit, focus and blur events – along with all bubbling events.

I’m successfully using the library in a large Web Application with over 6,000 lines of JavaScript code (and 60,000 lines of Java code). Some screens are displaying huge amounts of data (over 20,000 INPUTs).

It’s used like this:

<html>
    <head>
        <title>Event Delegation with Prototype</title>
        <script type="text/javascript" src='prototype.js'></script>
        <script type="text/javascript" src='delegate-generic.js'></script>
        <script type="text/javascript" src='delegate-prototype.js'></script>
        <script type="text/javascript">
            document.observe('dom:loaded', function() {
                $('someDIV').delegate('submit', '.dont-submit', function(e) {
                    e.stop();
                    alert('The form was not submitted!');
                });
            });
        </script>
    </head>
    <body>
        <div id="someDIV">
            <form class="dont-submit">
                <input type="submit" value="Submit">
            </form>
            <form class="dont-submit">
                <input type="submit" value="Submit">
            </form>
        </div>
    </body>
</html>

Try it out!