The Weak Reference

The Weak Reference

Kurser i Domain-Driven Design - VĂ¥ren 2012




Sunday, October 21, 2012

Reflection in Clojure

I recently got a question about dynamically loading and instantiating Java classes in Clojure. The goal was to check if a certain library was available on the classpath. If it was available it should be loaded and used, if not, a simpler default version would be used instead.

Given Clojure's dynamic nature, it would be reasonable to believe that this is a simple thing. Perhaps it is but, I didn't find an obvious solution to this problem in pure Clojure. Luckily, since Clojure runs on the JVM and interops nicely with Java, there is a pretty straight-forward way of solving this; finding and instantiating the classes needed aren't too hard to accomplish using Java and some good old reflection.

In the code example below the class we are looking for has a useful default constructor. If that's not the case, instantiating the class requires a little bit more work. But once you have a reference to that instance, using it from Clojure is just like using any other Java class from Clojure!

In the example below we prefer to call on Joda Time to provide us with the current date and time, but if the library is not in our classpath, we fall back to using java.util.Date.

(defn exists? [c]
  (let [loader (.getContextClassLoader (Thread/currentThread))]
    (try
      (Class/forName c false loader)
      true
      (catch ClassNotFoundException cnfe false))))

(defn print-java-date-now []
  (println (java.util.Date.)))

(defn print-joda-date-now []
  (let [clazz (Class/forName "org.joda.time.DateTime")]
    (println (.newInstance clazz))))

(if (exists? "org.joda.time.DateTime")
  (print-joda-date-now)
  (print-java-date-now))

Update 2012-10-22:

My colleague Mattias came up with this much nicer version of the exists? function using clojure.reflect/resolve-class:

(defn exists? [c] 
  (resolve-class (.getContextClassLoader (Thread/currentThread)) c))

Tuesday, March 27, 2012

Spring Break!

Last week the Citerus team spent a few fantastic days in Morocco. We try to take these trips somewhat regularly and over the years we have been to Italy, Czech Republic, and France among other places, but this trip was the first time we left Europe.

Citerus has been bringing quite a few new people on board over the last months, so this was a great opportunity to hang out with all our people for an extended time. Some for the first time as members of the Citerus team.

I must say I am amazed with the talents that have joined us for quite some time now. In fact, it blows me away. Spending time with my colleagues makes me feel old, slow and a bit stupid, and when building a great business, this is not a bad thing. I am very proud of being a part of this awesome group of people, you constantly learn new things, you are constantly challenged, and you always have fun.

Even though we bring our entire team together one day per month to share ideas and spend time together, doing this in new environments for an extended period really opens up a lot of great opportunities. The amazing views of the Atlas mountains as well as pool side work in Marrakech turned out to be perfect for creativity and focus. Look out for the new products we will be launching and exciting articles we will be publishing during the spring as a direct result of these last few days.

Feel like joining us? We’re hiring!

Monday, February 20, 2012

How Sad

How sad, no posts in over a year. Should we do something about that perhaps?

Sunday, January 16, 2011

Jfokus 2011

Jfokus 2011 is getting closer and this year looks fantastic! New venue, an additional day, and, as always, many interesting speakers. Tuesday February 15 has a DDD track with lots of great speakers, including Eric Evans.

Citerus is of course represented as a Jfokus partner also this year. We will be in the exhibition both conference days, come and see us!

Sunday, August 15, 2010

DDD classes survey

Eric Evans is doing a survey to guide future developments of the DDD classes that Citerus and other partners around the world offer together with Domain Language. If you are interested in DDD training, please take a moment to complete the survey. Thanks!

http://domainlanguage.com/survey/2010-08/

Friday, May 28, 2010

Meltingspot #4

Meltingspot #4 is now available. This time we start off with Daft Punk and end with Coldplay, while visiting both The Knife and Kraftwerk on our way.

Meltingspot #4 - This was meant to be, enjoy!

Follow us on Twitter @meltingspot, and stay tuned for our upcoming lists with music for the summer!

Tuesday, May 04, 2010

Your Build, Lava Lamps and Clojure

Long time without a post, here's one that's long overdue!

After a Javaform JUG meet-up this fall I happened to talk with @matkar (of Javaforum and Jfokus fame) at the pub following the meeting. He very convincingly described how great it is to use lava lamps as a visual tool for showing current build status. Actually, he pretty much insisted that I'd set it up immediately in my current project.

Well, it did sound like fun, so I got started. This blog post will layout what you need and how to create your own lava lamp powered visual workspace!

The build
First, you need a continuous integration (CI) server, also known as a build server. Your project needs one of these anyway, so if you don't have one in place, this is definitely the first thing to take care of!

In my current project we use Jetbrains TeamCity, but there are a number of free open-source products available as well.

You also need a way to extract the relevant build status data from the CI server. Depending on product there are typically a number of different ways of doing this. I used the RSS feed facility of TeamCity and polled the project's Atom feed for build status with certain intervals. For more immediate notifications one could probably fairly easy use TeamCity's Jabber support instead. But this was the easiest thing to setup and use, so I went with that, configuring a RSS feed with status information for the relevant code branch.

The Hardware
Secondly, you will need some hardware. By tradition, lava lamps is the number one choice for signaling here, but one can easily think of other options as well. If you decide to go down the lava lamp light road, try to get something that has a short start-up time. The ones I used take about 1.5 h to warm up (i.e. until they start "bubbling"), which is kind of long. If you have a disciplined team, the broken build will be fixed long before that. I got my lights from the gadget shop Teknikmagasinet here in Sweden, perhaps more expensive gear from a vendor like Mathmos would work better, but I don't know.

Then, you need some way of controlling the lamps. I did this by using an USB controllable power strip. In particular I used the SIS-PM Silver Shield Programmable Power Outlet Strip which comes with a simple but surprisingly nice GUI for use with Windows computers to control which sockets are on and which are off. It also comes with a Windows command line utility, which was the integration point I decided to use. I do my development on a Mac but the lava lamp solution was deployed on a Windows machine, so this worked out nicely.

For non-Windows deployment there are Linux drivers available for download from the page above, though I have not tried them out. There is also a SourceForge project with software for the power strip.

The Software
The final piece of the puzzle is the software that regularly polls the CI server's RSS feed and controls the power sockets according to current build status – successful or failed, in order to turn on and turn off the lights.

The code is written in Clojure. It uses functionality from clojure.contrib to parse the RSS XML and call the command line utility to control the power strip. The lightweight scheduling component cron4j is also used, which integrates very nicely with Clojure.

The code and Leiningen project definition file can be found a this GitHub Gist. I use the Leiningen command uberjar to create a runnable JAR, making deployment extremely simple. The code assumes that the two sockets used are named green and red, the strip itself must be named lava. These names can be assigned using the GUI tool shipped with the power strip.

As far as examples of functional programming goes this code is a particularly bad example. Functional programming is much about side-effect free pure functions and this use case is pretty much all about side-effects. But I think it shows rather nicely that Clojure can be used for all sorts of things, including problems like this, perhaps more suitable for script-type languages. Also, an obvious simplification that could be made is to avoid storing internal build state, and instead always update the lights according to the latest polled build-result, even in the case when nothing has changed.

The program is configured through a settings file. This is a standard Java properties file specifying the path to the command tool and two cron expressions. The first cron expression describes when and how often to poll the build server, and the second specifies a time to shut it all down for the day so the lamps get the chance to recover a bit during night when the office is empty.

Bill Of Materials