Sunday 21 June 2009

Other Uses for the FreeBSD Daemon?

A friend of mine has been visiting from the Czech Republic over the weekend, an infrequent thing that inevitably results in visits to East Kilbride's pubs and nightclubs that we'll later regret. Some special strangeness last night came in the form of a sex-toy vending machine in the male toilets in Shenanigans in East Kilbride's town centre. Who would have thought that the FreeBSD daemon (right) was moonlighting as a purveyor of kinky goods?

vendie.pngbsd.jpg

Saturday 20 June 2009

A Minimal Java Applet in Clojure

Clojure's ahead-of-time compilation features allow it to operate seamlessly with Java classes, but one quirk that I noticed when writing a Java applet was that the security environment in applets tends not to be too happy with reflective method calls. Overriding an applet's paint method like this is therefore a no-go:


(defn -paint [instance g]
(.drawString g "Hello from Clojure!" 50 50))


The problem here is that the .drawString method is reflectively invoked against the given Graphics object.

This can be overcome with type-hints, letting the compiler know what the given 'g' is so that it can generate the code for a direct call, keeping the applet security manager happy.

A minimal applet might therefore look something like this:


(ns djw
(:import (java.awt Graphics2D))
(:gen-class
:name DJW
:extends java.applet.Applet))
(defn -paint [instance #^Graphics2D g]
(.drawString g "Hello from Clojure!" 50 50))


Note the type-hint, #^Graphics2D in the signature of the paint function.

If you're interested, the associated HTML file to run this in appletviewer or in a browser looks like this:


<object classid="java:DJW.class" type="application/x-java-applet" archive="applet.jar,clojure.jar" width="200" height="100" codebase=".">
</object>


Notice that clojure.jar is in the archive field of the object tag, along with applet.jar (containing the precompiled class files for the Clojure applet).

Tuesday 16 June 2009

UK to get 'World Class' Broadband?

I had to laugh at this article on the BBC: a new 50p tax on fixed lines in the UK to enable 'digital Britain' providing, among other things (up to) 50Mbps by 2017. A special highlight from our wonderfully inept Prime Minister:


"Britain is going to lead the world. This is us taking the next step into the future to being the digital capital of the world. -- Gordon Brown


Step back a bit... having 50Mbps broadband by 2017 is going to make us the 'the digital capital of the world'? Is he aware that South Korea is aiming for 1Gbps by 2012?!? (in case you're wondering, that's 20 times faster, five years earlier). Japan has 100Mbps now.

I sometimes wonder exactly which planet Gordon Brown is living on.

Monday 8 June 2009

Clojure: First Steps into Compilation and Class Generation

I've never quite understood class generation in Clojure. The documentation is a little terse, and working examples seem to be hard to come by. So here's my walkthrough.

First, I'm assuming that we'll be creating Clojure objects from Java, calling methods on those Clojure objects from bog-standard Java code. This, I think, is the most likely scenario for the budding Clojure hacker who wants to write part of an existing Java system in Clojure.

Environment



First, you'll need to have obtained your clojure.jar, either from the snapshots here, or from the Subversion repository and building yourself.

Next, in whatever environment you're using, add the full path to clojure.jar to your CLASSPATH. Also add "." and "classes" (both relative paths, not absolute). You'll see why later.

The Clojure Code



In the directory you're building from, create the directory structure for your package, Java-style. I'm going to be putting my Clojure code in org/djw/sample.clj, so org/djw will have to exist beforehand.

In sample.clj, most of the magic's in the namespace declaration.


(ns org.djw.sample ;; 1
(:import (javax.swing JFrame)) ;; 2
(:gen-class ;; 3
:name org.djw.DJW ;; 4
:extends javax.swing.JFrame ;; 5
:constructors {[String] [String]} ;; 6
:init initialise ;; 7
:implements [Runnable] ;; 8
:state fiddlyBits)) ;; 9



  • 1. This is your Clojure namespace. It doesn't mean much from Java-land.

  • 2. You can import any classes used by your Clojure file here.

  • 3. :gen-class allows the compiler to generate Java bytecode files.

  • 4. This is the fully-qualified name of the Java class you want to emit. The Clojure compile directive generates quite a few class files that your Java code doesn't need to know about: the one in :name is an exception: it's what your Java code will import

  • 5. If your class subclasses something other than Object, name it here, as normal

  • 6. I want to have a String constructor that calls the String constructor in JFrame.

  • 7. The initialiser function for new instances. I lack imagination, so have called it initialise here.

  • 8. Horribly, my new class is both a GUI element (a JFrame) and a Runnable. Since you can implement many interfaces, this appears in a literal vector.

  • 9. The initialise function gets to attach some Clojure-side state to the object being created (you'll see that in a bit). The :state specifier creates a final instance method to access that state from Java.



This leaves two functions to implement in the Clojure code: initialise and run (the latter required by Runnable).


(defn -initialise [message]
[[message] (ref {:message message})])

(defn -run [instance]
(let [message (:message @(.fiddlyBits instance))]
(println message)))


Note the dash in front of the function names (this is the default :prefix from :gen-class). Also, note that the function specified by :init in :gen-class didn't get an instance to play with, whereas run (an instance method), does. This instance is the object that the method was invoked against, effectively this from Java.

initialise has to return a vector of two elements: the first consists of the arguments to pass to the superclass constructor. The second is the state that should be attached on a per-instance basis.

run is a Runnable.run implementation, and just prints out the message that the instance was created with. Note that the state is accessed with (.fiddlyBits instance), returning the ref-wrapped Clojure map, dereferenced with '@' as normal and with the :message key used to look up the associated value.

Compiling the Clojure Code to .class Files



Create a directory called classes/[package-name], in my case classes/org/djw. Why classes? Well, that's what Clojure's global *compile-path* variable is by default, so is the root where the compile command emits .class files. That's why you added it to your CLASSPATH above (you did do that, didn't you..?)

Since clojure.jar is on your CLASSPATH, you can start a Clojure REPL with just 'java clojure.main'. You can now compile the ./org/djw/sample.clj like this:


danny@mirror Desktop [10] % java clojure.main
Clojure 1.1.0-alpha-SNAPSHOT
user=> (compile 'org.djw.sample)
org.djw.sample
user=>


And that's it. classes/org/djw will now contain org.djw.DJW (as per gen-class's :name field). It'll also contain a bunch of other .class files: don't delete these, they are required! Clojure creates a .class file per function (including unnamed functions), as well as another for initialisation.

The Java Code



This has been a lot of effort so far. But the good news that this allows Java to talk to Clojure-generated class files without having any idea that Clojure was the source language. The Java code in Test.java to use it might look like this:


import org.djw.DJW;

public class Test
{
public static void main(String [] args)
{
DJW djw = new DJW("Hello");
new Thread(djw).start();
}
}


And that's it. DJW is the class name, and a new instance is obtained just as with any other class. It faithfully implements Runnable, as specified in the Clojure code, and it can be duly run from a Thread created from Java.

Compiling and Running the Java Code



The Java can be compiled just as with any other. Remember that the classes folder must be in your CLASSPATH for javac to see the definition of DJW.

With clojure.jar, '.' and classes in your CLASSPATH, you can just run as you'd expect:


danny@mirror Desktop [30] % javac Test.java
danny@mirror Desktop [31] % java Test
Hello
danny@mirror Desktop [32] %


By now, you've defined a class definition in Clojure, prompted instance creation from Java, initialised the object in Clojure, handed it to a thread in Java, and printed out a message in Clojure. That's a fair amount of bouncing around, especially for such a trivial example, but hopefully you've found it useful for what you need.