Tuesday, December 8, 2009

Message Driven POJO with Java Content and Dependency Injection API (Weld) a.k.a Look ma! No XML!

I am supposed to be presenting 'Something new and exiting in Java' to staff of Experian Malaysia. Looking around, it seems that I am frekin lucky since we have a few new and exciting things in the Java world. Java EE 6 is finally here! (Phew!~), Netbeans 6.8 RC 1 is out! (with support for Java EE 6 - you can create a session bean right in your war file - I kid you not!) and finally Java CDI (I think, JSR-299) is finally here too!.

I decide to play around with CDI implementation by JBoss (called Weld). There are other implementations out there notably CanDI by Caucho and OpenWebBeans by Apache.

Anyway, CDI allows you to do strong typing dependency injection without XML (of course, XML is still there just in case you need it). Weld can be downloaded here [http://seamframework.org/Download]. A full tutorial by JBoss teamcan be found here [http://docs.jboss.org/webbeans/reference/current/en-US/html/index.html]. Note that the tutorial was created about a year ago [on the internet scale, that is the equivalent of the time between the Triasic era and the French Revolution], so some things are not up to date. A better approach is to learn stuff off the examples in weld zip file.

Here's an example of CDI:

With CDI, we can create Java Beans with a particular scope. In this example we have a Singleton scope. This means that there will be a single instance of SomeService for the whole application.


@Singleton
public class SomeService{
public String doSomething(String parameters){
//do something here
return result;
}
}


To access the service, we can just inject it to a class


public class Client{
@Inject SomeService someService;

public void run(){
//use someService
}
}



Note that we do not need to invoke any constructor or factory of SomeService in Client. The lifeCycle of SomeService is managed directly by Weld.

Anyone who uses Spring before knows that Spring can also do much of the same thing. Its just that Weld can do all this while being strongly typed and xml-less (Maybe Spring does make XML optional these days, I have not checked)

Now the big finale, one use case of Spring that I find fascinating is Message Driven POJO (MDP). So, I wanted to create one using Weld.

OK, since I don't have much time, I 'cheated' a bit by using ActiveMQ libraries and by making my MDP works only with ActiveMQ... but hey, it works >:) [Maybe I should call it Message Driven ActiveMQ Producer/Consumer instead ;) ]

I based my implemetation on this [http://developers-blog.org/blog/default/2008/10/28/A-simple-ActiveMQ-example] (Thanks Gisbert) .

After much toiling (my first implemetation uses Spring libraries... a pile of fun that turn out to be), I manage to create an MDP using Weld.

An MDP looks like this:


@Consumer
public class Processor {

public void processRequest(RunnableMessage runnable){
runnable.run();
}

public void doSomething(String string){
System.out.println("Received string="+string);
}
}


The Consumer annotation indicates that this object is ready to receive messages. The messages are in fact POJOs themselves, so when a message arrives, depending on the type of the message (or rather the type of the payload of the message), a method within the Processor object is chosen.

To send a message, I just do this:


RunnableMessage r = new RunnableMessage(); //r here is just another POJO
activeMQService.sendMessage(r);


And processRequest will be invoked.
If I do:


activeMQService.sendMessage("If you type google into google, you will break the internet");


Then I will invoke the method doSomething instead.
Cool eh :)

Anyway, the source code with all its dependencies are here [http://www.freedrive.com/file/1045164,weldmessage.zip]. To run this, you need to download ActiiveMQ
[http://activemq.apache.org/download.html] and run it. (Unzip the file and run the executable in the bin directory). Next, just run the example.

Have fun!

4 comments:

red1 said...

way to go bro!

(praise from the warlord chieftain of the empire of darkness in cyberspace)

r e d 1

Bernie said...

Nice example to show how DI is *finally* implemented in the standard JEE stack. I've been having issues with injecting a parameterized type via Guice (and I've yet to try it in Spring). I wonder if this Java DI API allows such an injection?

Azrul said...

What problems exactly, mind sharing it?

Bernie said...

Well, when using a custom @provider, I can't figure out how to bind a parameterized type. There is a way to bind when not using @providers, but I need to use one. I'd wrote am example, but blogger disallows the java generics syntax :(

Since @provider is specific to guice, it's really a guice specific issue.