2009-06-08

Clojure and Compojure

A while back I tried out Clojure. It was my first real foray into the land of Lisp like languages, other than copying, pasting, and slightly modifying elisp chunks for Emacs which doesn't really count. It was very... interesting. I was writing a small IM bot to try it out, but couldn't find any reliable Java libraries for protocols other than XMPP. Nevertheless, I did get a basic bot working with XMPP and learned some basic Clojure as well.

The language recently had its 1.0 release and I figure it's time to try it out again. The last time I tried it out, the docs were somewhat confusing, but the main problem was simply getting the libraries to interact with Clojure well and I ran out of time. The only major issue I had at the time was needing some small Java code to handle something... static variables or overriding private methods or something like that. This time, I'm going to try making a small web site using Clojure and Compojure.

Compojure looks like an interesting, fairly minimal web framework.

Step 1, download:
$ git clone git://github.com/weavejester/compojure.git
Initialized empty Git repository in compojure/.git/
remote: Counting objects: 3371, done.
remote: Compressing objects: 100% (1619/1619), done.
remote: Total 3371 (delta 1680), reused 2806 (delta 1335)
Receiving objects: 100% (3371/3371), 5.25 MiB | 55 KiB/s, done.
Resolving deltas: 100% (1680/1680), done.


Yay! Easy enough.

Step 2, get other packages it needs like Clojure and Jetty, and compile Compojure:
$ ant deps
Buildfile: build.xml

deps:
[get] Getting: http://cloud.github.com/downloads/weavejester/compojure/deps.zip
[get] To: compojure/deps.zip
[unzip] Expanding: compojure/deps.zip into compojure

BUILD SUCCESSFUL
Total time: 2 minutes 20 seconds
$ ls deps
clojure-contrib.jar commons-io-1.4.jar jetty-util-6.1.15.jar
clojure.jar grizzly-http-servlet-1.9.10.jar servlet-api-2.5-20081211.jar
commons-codec-1.3.jar grizzly-http-webserver-1.9.10.jar
commons-fileupload-1.2.1.jar jetty-6.1.15.jar
$ ant
....
BUILD SUCCESSFUL
Total time: 6 seconds


Step 3, Write basic helloworld and start the server:
helloworld$ cat helloworld.clj
(ns example-app
(:use compojure.http.servlet)
(:use compojure.server.jetty))

(defn hello-world [request]
{:status 200
:headers {}
:body "Hello World"})

(run-server {:port 8080}
"/*" (servlet hello-world))
helloworld$ /usr/lib/j2sdk/bin/java -cp $(for i in ../compojure/deps/*.jar; do echo -n $i: ; done)../compojure/compojure.jar clojure.lang.Script ./helloworld.clj
2009-06-08 22:43:51.799::INFO: Logging to STDERR via org.mortbay.log.StdErrLog
clojure.proxy.javax.servlet.http.HttpServlet
2009-06-08 22:43:51.859::INFO: jetty-6.1.15
2009-06-08 22:43:51.952::INFO: Started SocketConnector@0.0.0.0:8080

And in another terminal:

$ wget -O - http://localhost:8080/ 2>/dev/null
Hello World


Cool! From nothing to the simplest example in half an hour (including figuring out how to run the clj file form the command line). Next time, hopefully I'll have managed a more complicated web app.

1 comment:

Unknown said...

Used this as a setup guide - works like a charm. Thanks a lot!