Getting Compojure Working On Windows 7

It’s a lot easier to do decent installation documentation on a clean computer.  Today I tried building Clojure and Compojure from scratch.  First you need to be able to run powershell scripts.  If you can’t, do the following

  • Close all powershell windows
  • Start a powershell window as administrator
  • set-executionpolicy Unrestricted

(I’m assuming that if you have more sophisticated security requirements, you’ll know enough to implement them yourself.)

Building Clojure

I’m going to assume that everything gets built into a directory I’m calling D:OSS.

First, download the following simultaneously:

  • MSysGit.  I used the net install.  Try something like D:OSSMSysGit as the installation directory
  • At the same time, download and install the latest JDK.  Windows 7 64-bit uses the x64 version.
  • Download Ant and unpack it into d:ossant

Once git is installed, create a file git-powershell.bat in the installed directory with the following content:  (Note the explicit setting of JAVA_HOME: if you don’t do this, ant will try using the JRE, which won’t work.)

    @set PLINK_PROTOCOL=ssh
    @setlocal
    @for /F “delims=” %%I in (“%~dp0”) do @set git_install_root=%%~fI
    @set path=%git_install_root%bin;%git_install_root%mingwbin;%git_install_root%cmd;%git_install_root..antbin;%%PATH%
    @if “%HOME%”==”” @set HOME=%USERPROFILE%
    @cd %HOME%
    @set JAVA_HOME=C:Program FilesJavajdk1.6.0_20
    @powershell

This file is going to be your standard way of running your dev command line.  Click on it to get running and switch to the OSS directory.  Then type

git clone git://github.com/richhickey/clojure.git
cd clojure
ant

Building Compojure

Now get the lein ps1 script from GitHub and put it on your path.  Call it lein.ps1.  Then type*

cd ..
git clone git://github.com/weavejester/compojure.git
cd compojure
lein self-install
lein deps
lein jar

Running Hello World

We’re still not finished.  We’re going to need a script to run compojure:

$compojureDirectory = (split-path $MyInvocation.MyCommand.Path)
$jars = (ls (join-path $compojureDirectory *.jar),(join-path $compojureDirectory lib*.jar))
$classPath = [String]::Join(“;”, $jars)  # Create a class path with compojure and every jar in libs on it
$script = (join-path $pwd.Path $args[0])
java -cp $classPath clojure.main -i $script -r $args

Put that in compojure.ps1.  Now we finally try getting started with Compojure.

Create a file hello.clj

(ns hello-world
  (:use compojure.core ring.adapter.jetty))

(defroutes routes
  (GET “/” []
    “<h1>Hello World</h1>”)
  (ANY “*” []
    {:status 404, :body “<h1>Page not found</h1>”}))

(run-jetty routes
    {:port 8080})

You can theoretically put this anywhere you like, but put it in the Compojure directory for now.  Now type “.compojure.ps1 hello.clj” and your web server should start.  Navigate to http://localhost:8080/ and you should see:

Hello World

If you’re thinking apt-get was easier, you’d be right.

*The instructions get Compojure working, but not against the trunk Clojure.  For that, you’ll need to copy the jar file around after lein deps.

UPDATE: The original lein.ps1 script worked as for as these instructions were concerned, but failed in a number of hard-to-debug ways.  As a consequence, I’ve updated it and merged it with lein.bat, which works but involves source hacking the whole time to get it to work.  Hopefully the new version will be the best of both worlds.

Technorati Tags: ,,

Proxy Server: Getting IronRuby Working

Quick installation instructions:

Getting the Proxy Server Running

Annoyingly, you need to change the code from the previous post, because I used a 1.9.1 idiom: the new lambda syntax and WEBrick doesn’t seem to work under IronRuby’s 1.9 mode.

require ‘webrick’
require ‘webrick/httpproxy’

server = WEBrick::HTTPProxyServer.new(
    :Port => 8080,
    :BindAddress => ‘0.0.0.0’,
    :ServerType => Thread,
    :RequestCallback => Proc.new {|request,response| puts “#{request.unparsed_uri}” }
)
server.start

puts “Hit return to quit”
STDIN.gets

Sure enough, the performance is perfectly fine, meaning it’s likely that the whole virtual machine installation is the source of the problems.  This is unfortunate, since that was the purpose of the exercise.  It’s starting to look like I may have to do a full installation onto my computer, which in turn means stopping using Notepad++.

There’s a bit more about WEBrick and proxy servers here, if you can cope with the automatic smiley generator damaging the code.  There’s an MSDN example of a web server as well.

Technorati Tags: ,

My First Ruby App

Okay, if you’ve got a working Ubuntu installation from the previous steps, this gets ruby working:

  • sudo apt-get -y install ruby1.9.1
  • sudo apt-get install rubygems1.9.1

Note that the commands installed are “ruby1.9.1” and “gem1.9.1” instead of “ruby” and “gem”.  You can now follow the Sinatra home page instructions and get Hello World running on your machine.

At this point, I’m starting to get annoyed at how long everything takes to install on windows.  But the next bit was a bit more of a shock to me.  Ruby fans will know what’s coming.

You see, my plan was to sit down, learn some Ruby and try to stick together a simple, well-specified program.  So, I thought, let’s try an HTTP Proxy Server.  It’s not hard, it’s easy to verify that it works, and it involves threads and sockets, so there’s plenty of stuff to play with.  Ruby fans will no what’s coming next: it’s also an API in the standard distribution.

So, if you want to write a proxy server in Ruby, consider the following code:

require ‘webrick’
require ‘webrick/httpproxy’

server = WEBrick::HTTPProxyServer.new(
    :Port => 8080,
    :RequestCallback => ->(request, response) { puts “Intercepted:  ” + request.request_line }
)
trap(“INT”) { server.shutdown }  # This catches Ctrl-C
server.start # start the server

It is, however, pretty slow, but I’m not sure if that’s just a reflection of the way I’ve got everything set up with VMware instances.  So next I’m going to see if I can get this working on IronRuby.

Technorati Tags: ,,

Connecting Windows and Ubuntu

The whole reason I’ve been playing with Ubuntu is that I want to work with Unix-world technologies on an actual Unix box.  The friction in getting anything to work on Windows is often just too high.  So, the next job is to set stuff up so that you can connect up the two boxes and get a development environment working.

Get SSH Working

  • sudo apt-get –y install ssh
  • Download the PuTTY installer and run it.*
  • Connect to the machine and trust the fingerprint.

From now on, you never need actually directly access the

*At the time of writing, Chiark was down.  Amazingly, Google Chrome offered to redirect me to a mirror.

Get Samba Working

Okay, you can now use the editors of your choice and compile on your Linux server.  If you are absolutely certain you’re only ever going to use this as a dev box, add the following:

[root]
   comment = The Root Directory
   path = /
   guest ok = no
   security = user

This is actually pretty useful if you are just trying to understand what’s going on because, of course, packages don’t tend to get installed in your home directory.

The correct command to run after changing the config on Lucid Lynx is “sudo restart smbd”

Technorati Tags:

Getting an Ubuntu Image working on Windows 7

There’s a bug in VMWare’s easy install that makes keyboards not work with Ubuntu.  This makes it hard to, for instance, type in your password.  It’s actually a long standing problem, but it still isn’t fixed.  The short version is that you need to not use easy install. The long version is given below.  (Interestingly, it seems to work in command line mode, but not GNOME mode.)

Creating the Image

These instructions are tested on Windows 7 64-bit, Lucid Lynx 32-bit and VMWare Workstation 7.0.1. 

  • Choose Typical
  • Choose “I will install the operating system later”
  • Choose Linux/Ubuntu
  • Just keep with the defaults until you hit finish.

Now you’ve got a 100% blank machine.  Now to load the operating system:

  • Choose “Edit virtual machine settings”
  • Choose the DVD drive
  • Choose “Use ISO Image”
  • Browse to your downloaded Ubuntu disc image.
  • Click OK
  • Power on the machine

The next bit is obvious:

  • Choose Install Ubuntu
  • Go forward to Step 3.  Type in the box and make sure the keyboard’s working.
  • Erase and use the whole disk (this is a VM disk, remember…)
  • Click through to Finish.
  • Wait a long time and then hit “Restart Now”

Now you’ll get a prompt saying “Please remove the disc and close the tray (if any) then press ENTER”

  • Right click on the powered on machine.  (I called it “Ubuntu”)
  • Choose “Settings…” at the bottom
  • Choose the DVD drive
  • Choose “Use Physical Drive”
  • Choose your actual CD drive.
  • Click OK
  • Go back to the machine and hit “Enter”

You’ve now got a working Lucid Lynx image.

Postscript: For some reason, it doesn’t seem to affect you in command line mode.  Only in GNOME.  I’m sure someone knows why that is, but it might as well be magic as far as I’m concerned.

Technorati Tags: ,

Industry Worst Practice

I talked last time about why I’m suspiscious of standardized practices.  The fundamental objection is that they lack context.  However, sometimes someone manages to come up with an idea that’s useful in no contexts whatsoever.  We’re talking anti-pattern bad.  The following story is true.  The names have been changed to protect the guilty.

GUI Design Methodology

John Developer joined a software consultancy.  They seemed pretty cool, had some interesting projects in the pipeline and used tech he’d got experience in.  Being pretty much a one man hacker at his previous firm, he wanted to improve his skills and work on bigger projects.  So it was something of a shock to discover that he was being referred to as “The Guru” after his first week.

Now, having stared at the code for a while, he couldn’t understand what code like the following was for

Const f_S017_c = 17

Yes, this was VB3.  That is absolutely no excuse for bad design.  He couldn’t understand what all of the switch statements were for, either.  It was then that, for possibly the first time in his life, he decided to read the documentation.  The documentation was pretty standard at first: you’d see a screen shot of what the UI was meant to look like.  There’d then be a quick explanation of what each control on the form did, along with the standard redundant explanations of what “OK” and “Cancel” did.

The next page was a spider’s web of a flow chart.  He asked his manager what it was: “Ah, that’s the state machine.”.

Flow Charts as Standard Practice

Here’s how you were meant to design a screen:

  • Mock up what the screen should look like (an old RAD design practice)
  • Identify the modes and transitions the screen should have. (e.g. which tab is showing, whether you’re adding or modifying data)
  • Build a flow chart that demonstrates how the screen works.
  • Implement the flow chart.

Yeah, you remember flow charts.  You probably saw some when you first learned to program.  Do you remember how to do a subroutine in them?  Of course you don’t because you can’t.  Flow charts and state machines are goto writ large.  And as soon as you gain any complexity, your state machine gets huge.  Imagine a screen with three tabs.  Imagine it can be used for adding or updating data.  That’s six states right there.  Imagine if one field is sometimes disabled.  That’s twelve.  State is a good concept and appropriate in many circumstances, but orthogonality is important.  There’s a reason classes are allowed multiple fields.

Step 3 was where the true brain damage occurred, but the implementation was, if not as bad, hilariously funny.  Bear in mind that this is all implemented on top of VB3, an environment in which event handling was the dominant idiom.  Each item in the flow chart was numbered.  Now, it’s bad to have magic numbers in code, so constants were used.  So, if you take a look at our code above, f_S017_c can be read as “field representing state 17 which is a constant”.  I hope that’s clear now…

Then, of course, when you actually need to branch, you need one of those huge switch statements.  Of course, you only put in the states which are possible.  Unfortunately, John quickly discovered that impossible states ran through the switch statements with alarming regularity.  These resulted in exactly the sort of code fragility you’d expect if you decide to ignore pretty much every serious thinker since 1968.

It wasn’t just the screens either.  Entities were designed in the exact same way.

Burn It

There are uses for flow charts, but in general terms I’d use them in informal, not formal contexts.  There are definitely uses for the goto statement (as I seem to have to explain every time I use one).  What made this particular practice exceptional was its cargo cult ability to impose out of context ideas from software engineering 101 and ruin developers lives.  But what’s really interesting about it is the way it was exactly the same as other standardized practices.

  • It seemed perfectly sensible and plausible to non-technical people.  (It used all the right words.)
  • It was inconsistently applied.  (Because sometimes you couldn’t get work done with it.)
  • Despite the phenomenal amount of documentation produced, it never exactly corresponded to the actual code.  (The only people who knew this, of course, were the coders, and they knew better than to mention it.)
  • When a production bug was found, it was inevitably found that some deviation from the system had occurred.  That violation, and the violator, got the blame.
  • Even given all of that, quite a lot of people wouldn’t hear a word suggesting that you should violate the process.

Luckily, this story has a happy ending.  Six months after this, with some fairly patient and low-key lobbying, John got asked to a meeting to discuss what they should do with their development methodology.  He said “Burn it and bury the ashes”.

They took his advice; he got a raise.  He hadn’t actually solved the problem of Big Upfront Design, but it was a start…

Technorati Tags: ,