Friday, October 07, 2005

Swing Sings with Spring (and activeMQ-ing)

Now I’m officially impressed – so much so I have to blog about it. Not long ago we had an important breakthrough at work. We actually put our thinking caps on and decided that (against all corporate neo-conventional wisdom) a web app was not the most appropriate platform architecture for our application. (I know, radical isn't it!)

Phase one had been done as a web app, with some good reason, but the reality is, we have a few specialized users at the same site who need a reliable, interactive monitoring application. There is no need for distributed no-client deployments across the net - on the contrary: a definite need for a richer client that allows control over the GUI container. A web browser controlled by javascript to me just did not fit. (For the record, I think there are a lot more applications that fit this definition that are implemented in a web browser that shouldn’t be, but that’s the subject of another blog.)

So once we’ve convinced the business users that there is a better way (even an alternative way!) the obvious answer to our client is SWING. Hooray! At last I’m writing real apps again!

Swing often talks to the back-end via RMI (unless you’re trying to shoe-horn it into some web app backend. I’ll let you picture that ugly picture in your mind before you realize for yourself what a clunky idea it is! And no, that’s not a dig at JSF. JSF is cool done right. And eventually it will be as soon as Sun takes the JSP out of their proverbial backend.)

So I start looking at how to do RMI the Spring way. Using the Spring RmiServiceExporter I was able to neatly encapsulate the RMI implementation in the Spring configuration. Life is pretty good.

The need for a reliable system architecture on the server-side is definitely on the requirements list. Usually we would look straight at an application server to fulfill these types of requirements, but while we’re being radical about front-ends, why not question the whole gamut?
So we start thinking about a more distributed service-oriented architecture. A new world where services run happily decoupled from each other advertising their wares across the ether. Not caring where they live or who they work for. A free J2EE world full of peace love and understanding.

The more we talk about it the more we like it. What if the app server goes down? All our services go down with it. Why use an app server then? Why not run the services independently, each in their own process space? Now that’s starting to sound interesting!

We’re starting to sing the song of better, lighter, and maybe even faster Java. (Ref: Bruce Tate) I haven’t read his book and wasn’t able to meet the man himself at NO Fluff Just Stuff this weekend, due to the fact that my wife will be giving birth any day now, but I’m sure he’d approve.

But hang on, party’s over: How are these happily independent services going to talk to each other? The distributed service architecture requirement is starting to sound a lot like JMS, and don’t we need an application server for that?

Before diving in, this is a prime opportunity to see what the Spring world has to offer…
A quick Google on Spring and JMS and you can’t help but stumble upon LogicBlaze’s ActiveMQ open-source message broker. A few links later and Craig Walls, author of Spring In Action, comes to the rescue with a very interesting blog on doing JMS the Spring way with the help of ActiveMQ. He dubs the technique Message-Driven POJO’s (MDP’s), modifying the Sun acronym, MDB - Message-Driven Beans (EJBs, that is).

Craig’s first Blog is great, but one thing still remains by his own admission, the need to implement the Message interface. Not to be outdone, it’s not long before he Blogs again about another great library from LogicBlaze – Lingo. This is the missing link as far as Spring is concerned. Now we can complete the decoupling from the JMS implementation.

http://jroller.com/page/habuma?entry=message_driven_pojos_2_the

So how does this all work in practice?
In a word – brilliantly.

Once I got my head around the abstractions, that is! After lots of deep thought about what is and is not necessary to implement, how things should be wired together and even how to reference the beans meaningfully, suddenly I found myself in Spring heaven. All I have to do is start up the ActiveMQ broker, start up my services one by one, and let the messages flow!

I have several services publishing to a JMS topic, all happily doing their own individual things, pumping their messages out into the world.

Why is this great?

i) Well first of all, each service is happily running in its separate process space – it has a VM all to itself. So if the service goes down, everything else stays up. And neither does it have to run on the same physical machine. No does it have to be the only one of it’s kind. I can start up several of the same services on different servers, publishing the same information to the queue and I have automatic fail-over.

ii) There is no application server in sight. But if I decide (or someone else decides!) I need one, I can use it as a container for my services with little trouble. All indications are that ActiveMQ will sit happily within a servlet container or application container. But please tell me why this is a good idea after taking i) into consideration.

iii) Because there is no indication whatsoever in the implementation classes that JMS is the transport.

The proof of this is in the testing. It took me the lesser part of a day to configure a Spring configuration to test all of my services WITHOUT JMS. No mock objects or heavy test containers required. Just plain & simple JUnit. Now that’s impressive!

Spring has Sprung. And it’s beautiful outside.

Q.E.D.

No comments: