Caution: my English is far from perfect. (Русский тоже не всегда хорош).

Friday, 28 November 2008

Clojure at Work: Interactively Control Running Java System

We are developing a system on Java. It must call another system and at some point the other system calls our system back via web service. Therefore I can not test this interaction in a stand-alone test, our code must be executed in an HTTP container (we use Tomcat).

In case if the code does not work as desired, I need to stop Tomcat, fix and rebuild Java sources and try again. And what is worse, before the code I am working on can be tested, it performs initialization that takes about a minute. These stumbles are little bit annoying for those who are used to fully dynamic development environments as Lisp.

I decided to embed Clojure into the system during development and connect to it with SLIME to create interactive testing/development environment.

First, I followed Bill Clementson's instructions for usual (not embedded) Clojure/SLIME setup.

After it worked, I started to look for a way to embed Clojure/swank into existing Java system, but didn't find any conventional way to do this. Therefore I torn out a piece of code from the clojure.lang.Repl class and instead of standard input, feed it with commands to start swank (which I found in the *inferior-lisp* buffer when Clojure/SLIME is started "normally", from Emacs).

All this is packed into simple clojure.jsp page in my web application directory. And clojure.jar is placed into WEB-INF/lib.

When the JSP is opened in browser it displays: "swank has been stared".

After that, I use M-X slime-connect from Emacs. The port number, as you can see from the code, is 7777.

What is the result?

I can inspect and control the running system, for example invoke functions I need to test or change object states.

But I must admit that the level of flexibility is lower than I hoped for. The point is that I can not interactively change Java code (which constitutes all the system). To be more flexible, the system must be written on Lisp entirely.



Javier said...

Mmm i imagine if you could use a dynamic class loader for the java core of the app it would be possible. I dont know if is possible but i remember a blog post about dynamic in memory compilation which mabe could be used for that:
I am afraid my knowledge is not enough to offer a more accurated proposal :-/

Anton Vodonosov said...

Thanks, the blog post is interesting.

Usual problem with java class is not to compile and load it first time, but to reload it.

It's impossible if you added/removed methods to class, changed it's inheritance, etc.

For example, when you are debugging application with IntelliJ, added/removed method, recompiled class and trying to reload it into the application, Intellij shows error: "schema change is not implemented". You need to stop the application, and start it again.

Blog Archive