John has posted 1 posts at DZone. You can read more from them at their website. View Full User Profile

Lightweight meets Heavyweight: Spring, Groovy and the enterprise

01.31.2008
| 15121 views |
  • submit to reddit

As I am preparing for the 2G conference next month, one of the things I am most struck with is again how seamlessly Groovy and Spring can play together. These two technologies give development teams the flexibility to seamlessly transition from lightweight to heavyweight "Enterprise" solutions.


Anyone who has spent any time around me has heard me rant about how unnecessary a full-blown J2EE stack is for most application development needs. While many companies would like to believe their applications are J2EE "necessary" the reality is that most applications do not have the throughput or transactional requirements required for a full-blown J2EE stack. Most organizations base the decision to build applications on a J2EE stack not on actual technical requirements, but on the need to hug the giant (often blue) J2EE teddy bear and hope it will protect them from the scary night.


Groovy and Spring let us quickly build J2EE applications without the overhead. More importantly, combining these two technologies gives us a smooth transition to an enterprise solution. This is a critical point:


Most architecture groups look to finding a single one size development stack rather then looking for a development stack that allows them to move from light to heavyweight implementations with little migratory pain. Enforcing a one size fits all technical stack significantly drives the final cost of delivering a solution.

The Humble Message Driven Bean

I love the EJB Message Drive Bean. I think they are a very elegant solution for building simple asynchronous invocations. However, they can be a big pain to setup in a J2EE container. Often times I want a solution and I want it fast. So lets take a look at how we can write a Spring/Groovy solution that provides the same capability as a J2EE MDB. To do this we need to take the following actions:
  1. Write a Groovy-based class that is going to act as our MDB.
  2. Configure Spring to setup a queue (In this case I am using ActiveMQ)
  3. Configure Spring to link the queue and our MDB class.
  4. Write a piece of client code to dump a message onto the queue .

Writing the MDB Class

For our MDB class, I am going to use one of the examples from my talks. This MDB will take data passed onto the queue and then use a DAO to update a record. The example I am showing belows takes the primary key of the record to be updated (e.g. employee id) and then updates the employee's address with a lat/long value.

package com.netchange.racerhino.map


import javax.jms.Message
import javax.jms.MessageListener

class UpdateFieldRepMDB implements MessageListener{

def fieldRepService
public void onMessage(Message pMessage){
def holderLocation = new Location(
latitude: new Double(pMessage.getString("latitude")).doubleValue(),
longitude:new Double(pMessage.getString("longitude")). doubleValue())

def fieldRep = new FieldRepresentative(employeeId:pMessage.getString("employeeId"),
location:holderLocation)
fieldRepService.updateFieldRepsLatLong( fieldRep)
}
}

The key thing to note in the above code example is that I have to make sure my Groovy class implements the MessageListener interface. Once I have my MDB written above I need to register it in a Spring configuration file. The entry for this bean will look something like:

  <lang:groovy id="UpdateFieldRepMDB" 
script-source="classpath:/com/netchange/racerhino/map/UpdateFieldRepMDB.groovy">
<lang:property name="fieldRepService" ref="FieldRepService"/>
</lang:groovy>

 

Now this one of the beauties of Spring. I have just registered my Groovy class as a bean within Spring. Spring treats my Groovy class like any other Spring bean. My Groovy class can now fully participate in all of the services offered by Spring. This includes using the class as a listener for a Message Queue.

Configuring Spring to Use a Queue

For my example here, I am going to use the Apache ActiveMQ project. This project provides a fully functional, JMS compliant message queue that is incredibly easy to setup. To use ActiveMQ, I literally have to download the distribution and fire up the activemq script in the bin directory and away I go. (Obviously there is far more I want to do here to operationalize my queue, but that is outside the scope of what I am doing here.)

So lets configure Spring to use ActiveMQ and setup a queue. To do this I am going to need to add two tags to my Spring configuration file.

<bean id="mqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://JCC.local:61616"/>
</bean>

<bean id="fieldRepDest" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0" value="fieldrepresentative.updatelatlong.queue"/>
</bean>

The first tag defines the connection factory and URL Spring is going to use when sending a message. The second tag defines an actual queue that will be available when Spring attempts to communicate with ActiveMQ. In our example above, we have one MQ called "fieldrepresentative.updatelatlong.queue" This queue will be automatically created if it does not already exist. The next thing we are going to want to do is "hook" our MDB up to our queue.

Making the Hookup

Hooking up our MDQ to our queue requires an additional tag in our Spring configuration file.
<bean class="org.springframework.jms.listener.SimpleMessageListenerContainer">
<property name="connectionFactory" ref="mqConnectionFactory"/>
<property name="destination" ref="fieldRepDest"/>
<property name="messageListener" ref="UpdateFieldRepMDB"/>
</bean>


Spring uses the concept of a ListenerContainer to bring together an MQ connection, a target queue and the Spring-enabled class that will process messages off of the queue. In the example above the "connectionFactory" property defines a reference to the connection we will use to communicate to our ActiveMQ instance. The "destination" property points to what queue is going to be listened to and the "messageListener" defines the Spring bean (in this case our Groovy class) that will be process the record.

Spring offers a number of different ListenerContainers that can be configured. The example shown above is the most basic type and is not transactional. However, Spring does offer a full-blown JTA-compliant ListenerContainer that can participate in transactions.

Finally the Client Code

To actually write to the queue is incredibly easy. The code snippet below is using straight JMS calls from within a Groovy-based unit test. I could use a Spring JMS template, but I chose to explicitly use the JMS calls to dump a message on a queue.

def connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616")
def connection =connectionFactory.createConnection()

def session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE)
def dest = new ActiveMQQueue("fieldrepresentative.updatelatlong.queue")
def producer = session.createProducer(dest)
connection.start()

def MapMessage message = session.createMapMessage()
message.setString("employeeId", "TS12345")
message.setString("latitude", "12345")
message.setString("longitude", "97874")

producer.send(message)

session.close()
connection.close()

One of the key take aways above is that we were able to build a solution that offered J2EE like capability and a smooth enterprise migration path. All of the code is written in Groovy which means if necessary it could be compiled down to Java bytecode and mixed and matched with Java classes. In addition, we can always rip the Spring-based MDB out and put in a J2EE based MDB solution. Our applications will never know the difference.

Spring acts as an intermediation layer that abstracts away the implementation details of how things are called. Groovy provides us with the language velocity needed to deliver solutions quickly without having to deal with the normal "gunk" associated with building a statically-based Java/J2EE solutions.
Published at DZone with permission of its author, John Carnell.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

John Denver replied on Fri, 2008/02/01 - 2:11am

Spring Rocks, No doubt, I can't live without Spring, actually I can't code Java without Spring. But the thing I don't understand is people keep bothering with Groovy it is a verbose, very slow, ugly scripting language. The syntax is similar to Java but weird and with the dynamic typing so why bother with it, you loose the static typing benefits, I prefer to code in Java and if really I would like to use a dynamic language I will go with Python or Ruby something diferent, not the same thing but make it up. Please wait for Java7 you will have closures and another goodies and you and me can keep the language we love. 

John Carnell replied on Fri, 2008/02/01 - 10:37am in response to: Martin Vaněk

Actually, Anthavio I would disagree with you. I understand the client code seems a little obtuse, but the advantage here is more on the server side. Writing an MDB can be a pain especially if I want to implement simple change. Using Spring and Groovy in this case allows me to easily use MDB like functionality in a web-app container or even a standalone JVM.

We have used this with our rapid prototyping teams to quickly string together applications. This is where I see a lot of the power of Groovy. I get a lot of velocity in being able to put together an application. It is also gives me a migration path to a heavier solution if I need to.

John Carnell replied on Fri, 2008/02/01 - 10:47am in response to: John Denver

I agree with you on Spring.  The key thing to keep in mind is that in most organizations they are looking at the question of development frameworks from an either or perspective.  They either go light-weight (ROR/Grails) or heavyweight (J2EE).  Thats a bit of  false dichtomy.  There are a lot of problems that can be solved without having to using a J2EE-based solution.  However, when organizations only focus on one specific framework they end up incurring a significant amount of cost on projects that they do not need.  

 The thing I like about Spring (and Groovy) is that it provides a migration path.  I can get something out there quickly and if need be fail quickly.  As my application needs evolve, I have a way of moving forward without having to completely re-write my code.

Ugly scripting languages :).  I can write cruddy Ruby code just as much as cruddy Groovy code.  I love Java and have done a lot of work with it.  I still write a greal deal of my applications in Java.  However, there is a very real need for languages like Groovy.  It allows to solve problems quickly.  I can pop open the Groovy console and start tinkering with an idea.  In Java, I have to an IDE, a workspace an app server, etc.....

Think about what it takes to execute a simple SQL statement in Java.   It usually takes 10-15 lines of code.  I have to get a database connection, get a preparedstatement, bind my parameters to it, walk through the resultset.  I can usually turn it around in 3-5 in Groovy.

 I think the key thing to realize is that Groovy is still just a technology.  You still need to follow good coding practices in writing your code. 

 

     Cheers,

          John 

Gerd Klevesaat replied on Fri, 2008/02/01 - 5:39pm in response to: John Denver

To alpha512:

I agree with you on spring. I also don't want to miss it.

But you schould have a deeper look at Groovy again. Do you really think it's verbose? Have a look at http://java.dzone.com/news/java-groovy-few-easy-steps or get a look into "Groovy in action". Coding in Groovy can be more compact. It sure also depends on coding style and best practices.

In Groovy you have the choice. You can code as you would in Java and still use static typing. It supports both static and dynamic typing. It is up to you.

Using static typing and not needing to updates on code at runtime, you may compile it to java byte code. You will feel no difference. However, using relaodable code comes at a price to parse and compile again. Compared to Ruby, you can't say it is slow.

I am looking forward to Java7, too. But a lot of people out there are just arriving at Java5. And they can use a lot of beneficial features with Groovy on this platform now.

I like coding in Java, but I also enjoy coding in Groovy.  And I appreciate using them together.

 

Martin Vaněk replied on Fri, 2008/02/15 - 2:25pm in response to: John Carnell

And how do you control transactions in such case? When using JMS, you should be very aware of them. As far as i know, Groovy classes cannot be annotated with spring transaction control annotations, because Groovy syntax itself does not support annotations. I dont know how about declarnig transactions in spring xml. Works?

So basically you use exploded war inside web container, to allow groovy classes reload? Packed war or ear kills this.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.