Migrating Clojure from 1.2 to 1.3
I use Clojure for my skunkworks projects at work. I used to use Python, but when we dropped the product's native TCP/IP interface in favour of JMS, it became difficult to use Python any more, as the hoops you have to jump through to access JMS from Python were beyond my patience level.
However, it gave me a perfect excuse to use Clojure as, since it runs on top of the JVM, it makes access to JMS pretty easy. This was around Cloure 1.0, and I've migrated forward whenever a new release became available.
However, I put off the migration to 1.3 because the break-up of the
clojure-contrib
library meant it would probably take a little bit
of work. When I did find the time, it wasn't that
onerous. Here's a summary of the changes I had to make:
-
I had put
(clojure.contrib.repl-utils/add-break-thread!)
inuser.clj
to allow the interruption of a long running function in the REPL (I use emacs with Jeffrey Chu's clojure-mode. This has been replaced with(clojure.repl/set-break-handler!)
. You'll need to include(require 'clojure.repl)
inuser.clj
as well. See the changelog, point 2.28. -
The funtions to access function documentation
doc
andfind-doc
have moved intoclojure.repl
, in case you wondered where they had gone. See the changelog, point 2.26. -
Access to the server data was through
clojure.contrib.sql
, which has been replaced byclojure.java.jdbc
. It was a bit tricky to track down the ready-made jar, but the link will take you there. This, for me, was a drop-in replacement. Other namespace changes for the clojure-contrib libraries are documented at clojure.org. -
I found I had to
(require 'clojure.xml)
and(require 'clojure.zip)
, which was not needed under 1.2. See the changelog, point 1.4. -
The function
clojure.xml/emit
, for outputting xml in a string format from a zip structure, is no longer public (but still available) in 1.3. It will probably disappear in a later version but, hopefully, some other mechanism will be available by then. -
Dynamic vars must be explicity tagged with
^:dynamic
when they are defined. Earmuffs, i.e.*var*
, are no longer sufficient. See the changelog, point 1.1. -
One thing caught me by surprise when I was testing the converted programs: the XML messages I was sending the server produced errors. This was because every token was terminated by "\r\n". I generated the xml by something like this, removing the newlines inserted by
clojure.xml/emit
:(.replace (with-out-str (clojure.xml/emit (clojure.zip/node xml-zip))) "\n" "")
A bug in 1.2 had been fixed, as now
with-out-str
emits the line separator for the platform, rather than "\n". To reflect this, I changed the snippet to:(.replace (with-out-str (clojure.xml/emit (clojure.zip/node xml-zip))) (System/getProperty "line.separator") "")
See the changelog, point 2.24.