Few weeks ago, I got my self a motorola xoom. From an android developer perspective that is just heaven :) . I really believe that iPad is just a giant size iphone, and having the opportunity to have the first real tablet OS is just amazing.

So, last week I’ve started playing around with it for real. I do have some ideas around for an app, that may never took off, but at least I’m having fun creating loads of mini apps and experimenting the new APIs.

Today I’m working with information visualization at Ericsson. And we’ve been trying all types of nice visual paradigms to display information. It’s been a really, really nice ride. One of my favorites is heatmaps. If you want to know how to implement a heatmap this link is your BEST bet. It’s really amazing what the author had achieved. It’s simple, it’s beautiful and it works perfectly. And since “imitation is the sincerest form of flattery” (I’ve just copied this from the best book on REST out there: REST in Practice ). I decided to port the original Javascript and canvas algorithm to the android platform. And on Honeycomb, thanks to the GPU hardware acceleration, it looks quite amazing. So let’s get our hand’s dirty

The alpha map

You should take a time and go to the original article and understand a bit of the magic behind the heatmap. To sum up, first we create a alpha map with a shade of black/white and using alpha to define the heat (intensity) of the future color. That’s really simple with canvas API on android:

RadialGradient g = new RadialGradient(x, y, radius, Color.argb(10, 0, 0, 0), Color.TRANSPARENT, TileMode.CLAMP);
Paint gp = new Paint();
gp.setShader(g);
myCanvas.drawCircle(x, y, radius, gp);

Here we are just creating a circle with a paint configured as a RadialGradient shader. The colors varies from black with a low alpha (almost transparent) to a complete transparent color. The values x,y are just the coordinates we want to add the circles.

Adding some color

Now let’s add some color to the recently created circle. Here what we do is iterate over every pixel of the square that circle is contained within, and change it’s pixel color (keeping the alpha, that’s important). The variable backbuffer is just our bitmap that the canvas we used previously draw at.

private void colorize(float x, float y, float d) {
		if (x + d > myCanvas.getWidth()) {
			x = myCanvas.getWidth() - d;
		}
		if (x < 0) {
			x = 0;
		}
		if (y < 0) {
			y = 0;
		}
		if (y + d > myCanvas.getHeight()) {
			y = myCanvas.getHeight() - d;
		}
 
		int[] pixels = new int[(int) (d * d)];
		backbuffer.getPixels(pixels, 0, (int) d, (int) x, (int) y, (int) d,
				(int) d);
		for (int i = 0; i < pixels.length; i++) {
			int r = 0, g = 0, b = 0, tmp = 0;
			int alpha = pixels[i] >>> 24;
			if (alpha <= 255 && alpha >= 240) {
				tmp = 255 - alpha;
				r = 255 - tmp;
				g = tmp * 12;
			} else if (alpha <= 239 && alpha >= 200) {
				tmp = 234 - alpha;
				r = 255 - (tmp * 8);
				g = 255;
			} else if (alpha <= 199 && alpha >= 150) {
				tmp = 199 - alpha;
				g = 255;
				b = tmp * 5;
			} else if (alpha <= 149 && alpha >= 100) {
				tmp = 149 - alpha;
				g = 255 - (tmp * 5);
				b = 255;
			} else
				b = 255;
			pixels[i] = Color.argb(alpha, r, g, b);
		}
		backbuffer.setPixels(pixels, 0, (int) d, (int) x, (int) y, (int) d,
				(int) d);
	}

What’s worth mentioning on the above code is the extraction of the alpha value from a ARGB integer:

int alpha = pixels[i] >>> 24;

Tracking movement, refreshing the screen

Now the final touch (literally). In android you can track user movement by overriding the onTouchEvent method. So in our View we just override this method, and inside it, we call the method addPoint (which in turn draws the circle, colorize it and refreshes the screen by calling invalidate()) :

public boolean onTouchEvent(MotionEvent event) {
addPoint(event.getX(),event.getY());
return true;
}
public void addPoint(float x, float y){
RadialGradient g = new RadialGradient(x, y, radius, Color.argb(10, 0, 0, 0), Color.TRANSPARENT, TileMode.CLAMP);
Paint gp = new Paint();
gp.setShader(g);
myCanvas.drawCircle(x, y, radius, gp);
colorize(x - radius, y - radius, radius * 2);
invalidate();
}
protected void onDraw(Canvas canvas) {
if (backbuffer == null) {
	init();
}
canvas.drawBitmap(backbuffer, 0, 0, new Paint(Paint.ANTI_ALIAS_FLAG));
}

That’s pretty much it. After adding a point we make a call to invalidate, which will force your view to redraw itself, calling the onDraw method, where you should copy your backBuffer bitmap (which contains your heatmap to your view’s canvas). Besides some initialization code, that’s all that’s needed to create a heatmap on your android. Pretty simple for something so fancy right?

Wait a second, what about multi touch?

Yeah, you are right. There’s no fun doing all this on a device that can track 255 simultaneous fingers right? So the final code below you can see the version with multi touch support.

I really hope you enjoyed this, please let me know if you decide to use this somewhere, it would be quite nice to see that we have smart people and companies out there that would like to benefit from this.

package com.furiousbob.trackme;
 
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.Shader.TileMode;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
 
public class HeatView extends View {
	private Canvas myCanvas;
	private Bitmap backbuffer;
	private float radius;
 
	public HeatView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}
 
	public HeatView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}
 
	public HeatView(Context context) {
		super(context);
	}
 
	private void init() {
		this.radius = 20f;
		backbuffer = Bitmap.createBitmap(getWidth(), getHeight(),
				Bitmap.Config.ARGB_8888);
		myCanvas = new Canvas(backbuffer);
		Paint p = new Paint();
		p.setStyle(Paint.Style.FILL);
		p.setColor(Color.TRANSPARENT);
		myCanvas.drawRect(0, 0, getWidth(), getHeight(), p);
 
	}
 
	@Override
	protected void onDraw(Canvas canvas) {
 
		if (backbuffer == null) {
			init();
		}
		canvas.drawBitmap(backbuffer, 0, 0, new Paint(Paint.ANTI_ALIAS_FLAG));
 
	}
 
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		int fingers = event.getPointerCount();
		float points[][] = new float[fingers][2];
		for (int i = 0; i < fingers; i++) {
			points[i][0] = event.getX(event.getPointerId(i));
			points[i][1] = event.getY(event.getPointerId(i));
		}
		addPoint(points);
		return true;
	}
 
	public void addPoint(float[][] points) {
		for (int i = 0; i < points.length; i++) {
			float x = points[i][0];
			float y = points[i][1];
			RadialGradient g = new RadialGradient(x, y, radius, Color.argb(10,
					0, 0, 0), Color.TRANSPARENT, TileMode.CLAMP);
			Paint gp = new Paint();
			gp.setShader(g);
			myCanvas.drawCircle(x, y, radius, gp);
			colorize(x - radius, y - radius, radius * 2);
		}
		invalidate();
	}
 
	private void colorize(float x, float y, float d) {
		if (x + d > myCanvas.getWidth()) {
			x = myCanvas.getWidth() - d;
		}
		if (x < 0) {
			x = 0;
		}
		if (y < 0) {
			y = 0;
		}
		if (y + d > myCanvas.getHeight()) {
			y = myCanvas.getHeight() - d;
		}
 
		int[] pixels = new int[(int) (d * d)];
		backbuffer.getPixels(pixels, 0, (int) d, (int) x, (int) y, (int) d,
				(int) d);
		for (int i = 0; i < pixels.length; i++) {
			int r = 0, g = 0, b = 0, tmp = 0;
			int alpha = pixels[i] >>> 24;
			if (alpha <= 255 && alpha >= 240) {
				tmp = 255 - alpha;
				r = 255 - tmp;
				g = tmp * 12;
			} else if (alpha <= 239 && alpha >= 200) {
				tmp = 234 - alpha;
				r = 255 - (tmp * 8);
				g = 255;
			} else if (alpha <= 199 && alpha >= 150) {
				tmp = 199 - alpha;
				g = 255;
				b = tmp * 5;
			} else if (alpha <= 149 && alpha >= 100) {
				tmp = 149 - alpha;
				g = 255 - (tmp * 5);
				b = 255;
			} else
				b = 255;
			pixels[i] = Color.argb(alpha, r, g, b);
		}
		backbuffer.setPixels(pixels, 0, (int) d, (int) x, (int) y, (int) d,
				(int) d);
	}
 
}

To give you an idea of this app running, I’ve decided to post a movie :)


So you are starting a new web project. You’ve picked GWT as your framework. GWT is really great when it comes to the client part, the DOM manipulation and etc. But the server implementation is a strange beast. I say this because it abstracts the whole protocol interaction for you (which is good) but it does that in a proprietary way, using it’s own protocol called GWT-RPC.

I have never worried too much about that, my previous GWT projects were all done using GWT-RPC, and mostly because I could not find an easy way out. But we always bumped into the integration problem. Besides GWT no one understands it’s protocol. When using RESTful services in the other hand, you could expose your services to the whole world. So we ended up with this:

How I used to combine REST with GWT

Let’s start with a very simple service: An UserService. Everyone has one of this on it’s project right? Here’s a simple interface definition, with only a couple of methods:

public interface UserService {
	public List<User> list();
	public User getUser( Integer id);
}

Now we need to put this service as a GWT service. A good Framework for that is spring4gwt, I’ve worked with it before and really enjoyed, it makes simple to expose your service. You have to make your interface extend a RemoteInterface and that’s it :) Simple right? Let’s see how to expose our service as a GWT-RPC Service:

@RemoteServiceRelativePath("springGwtServices/userService")
public interface UserService extends RemoteService{
	public List<User> list();
	public User getUser( Integer id);
}
public class UserServiceImpl implemens UserService {...}

But wait a minute! What the hell is that RemoteService doing there? I’m really ok on adding annotations to my interfaces, that’s the beauty of annotations, you can add them, and if there’s nothing to process it, the behavior of your class is preserved (that was one of the foundations of EJB 3.0), but extending another interface? So it means now that your code is coupled to a certain technology. I DON’T LIKE IT AT ALL

So, to circumvent that, I did some hacking to keep my interfaces clean, and here’s the recipe for that:

1 – Keep your original interface



I’ve kept my interface original with no extensions:

public interface UserService {
	public List<User> list();
	public User getUser( Integer id);
}


2 – Create a new interface extending your interface and the RemoteService


@RemoteServiceRelativePath("springGwtServices/userServiceRPC")
public interface UserServiceRPC extends RemoteService, UserService{
}


3 – Make your implementation implement the original interface


public class UserServiceImpl implements UserService {...}


4 – Time for some hacking … ProxyFactoryBean FTW



The problem with that approach, is that although you keep your code clean and purebred, spring4gwt will no longer work, as it requires the bean to be exposed to implement the RemoteService, and our bean is a purebred race. So I used proxies for that:

<bean id="userService" class="com.furiousbob.gwt.server.user.services.UserServiceImpl"/> <!-- Our purebred service -->
<bean id="userServiceRPC" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="proxyInterfaces" value="com.furiousbob.gwt.server.user.services.UserServiceRPC"></property>
		<property name="target" ref="userService"></property>
	</bean>



Problem solved. Spring4gwt will now look for a bean named userServiceRPC (as used on the @RemoteRelativePath) and find a proxy that delegates all the calls to the actual implementation. The proxy itself implements the RemoteService interface and hence it’s ok to be exposed. I was able to keep my code clean, but at a price, I had to create an extra interface and use proxies.

Don’t take me wrong, sometimes this will be the best approach. The one thing I learned over the years is that the world is not black nor white it’s grey. So be prepared to face some trade-offs as you go :)

In my case, I did all this only to expose the service as RPC and REST at the same time, and preserve my interfaces. All that could be avoided if we could use REST in a simple way …


How I combine REST and GWT today



Ok, that was how I used to get things running. So, what about now? Well, after a very inspiring reading at this blog. I decided to give a try on several rest+gwt frameworks out there. The motivation behind are pretty much the same exposed by the blog author:

  • I don’t want to use a proprietary protocol
  • I want to be able to test my services using tools like the amazing Poster
  • I want to be able to see what’s being sent over the wire with developer tools from chrome and firebug



So I knew I want to integrate GWT with REST, but there was just one single requirement for this:

IT HAS TO BE SIMPLE

And when I say simple, I mean, transparent to the development team. So we now have our expectations, let’s meet our choices:

  1. Restlet extensions for GWT
  2. Use jQuery
  3. Use of GWT RequestBuilder
  4. Use resty-gwt


Restlet extensions for GWT

This one was discarded because at the time I was developing the system, there was no support for GWT 2.2, and that was a main requirement for us, so although it seemed promising we dropped it because of the lack of support

Use jQuery

Another one that was dropped straight away, the blog that mentions it at the end recommends the use of RequestBuilder, so we did not even tried this one.

Use RequestBuilder

RequestBuilder seemed to be a good choice, but it adds a burden of marshaling and unmarshaling to the developer. Every call we had to serialize our objects to json and back on the responses. So we drop this one as it would increase development time.

Use resty-gwt

Ladies and Gentlemen, here’s the winner. This amazing library can be found here, really did the trick. Our main requirement was the integration to be simple right? So let me demonstrate how simple it is:

The exposed service

@Path("/services/users")
public interface UserService {
 
	@GET
	@Produces("application/json")
	@Path("/list")
	public List<User> list();
 
	@GET
	@Produces("application/json")
	@Path("{id}")
	public User getUser(@PathParam("id") Integer id);
}

And to consume this service all you have to do is create a client proxy for it. Please remember that on original GWT-RPC you will also need an Async version of your service, this is the exact mapping, so no extra class is being added here, just replaced:

public interface UserServiceRest extends RestService {
	@GET
	public void list(MethodCallback<List<User>> callback);
 
	@GET
	public void get(Integer id, MethodCallback<User> callback);
}

And to use it:

Resource resource = new Resource("/services/users/1");
final UserServiceRest service = GWT.create(UserServiceRest.class);
((RestServiceProxy)service).setResource(resource);

The beauty behind this library, is that it mimics the same programming style used by GWT. You have an asynch interface on the client side that will call the methods on the server. It is REALLY easy for GWT developers to understand, and comparing to the GWT RPC invocation, it takes only 2 extras lines of code (just the Resource declaration part).

Conclusions

RestyGWT was clearly the winner here! If you are considering starting a new GWT project, you should really consider having most of your services as RESTful only services, you will eventually need a RPC based service once in a while, but you should try to keep as most as you can a single protocol and interfaces on your application. The next thing I’m interested in is integrating the RESTful links and GWT Places and Activities.


Happy coding!

  • Introduction

One of the many challenges web developers face when building new applications, is to get notifications from the server, in a real push way. This has been a problem since the beginning of HTML. Not being able to push messages from the server to the client led us to create some alternatives (polling, comet, pigback) you name it, there are dozens of them out there. None of those unfortunately are real server push. This led the MVC pattern to be kinda awkward on the web, and for many years we said that was a one way MVC :)

With the advent of HTML 5 and the new websockets API a promise of change is on the horizon. The only problem is that so far, only Jetty 7 supports Websockets, and you have to write a special type of Servlet to handle this type of communication. So implementing it is not as simple as you would expect.

But there’s still hope out there. The two best JMS brokers out there (HornetQ and ActiveMQ) both support websockets connections. And if you stop to think a while, it makes way more sense in an architectural style to have your messages being pushed to your client using a JMS solution. Isn’t that one of the motivations behind JMS (loose coupling, distribution etc, etc, etc).
There’s already an excellent JS client out there you can find it here, a good explanation on how to use it can also be find here, in fact, the idea behind this post is just to create a GWT wrapper on top of this amazing library. So let’s get our hands dirty.

You will need:

  • An application server, get the best one here
  • A JMS broker, get HornetQ or ActiveMQ from the links above
  • GWT 2.2
  • This post’s code can be found at : google-code


  • Configuring the brokers

Setting up the brokers to support Websocket is pretty simple, please refer to each broker docs for in depth explanation.

ActiveMQ:

Edit your conf/activemq.xml and add a connector:

<transportConnector name="websocket" uri="ws://0.0.0.0:61614"/>

HornetQ:

Edit your hornet-configuration.xml

<acceptor name="stomp-ws-acceptor">
         <factory-class>org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class>
         <param key="protocol" value="stomp_ws"/>
         <param key="port" value="61614"/>
      </acceptor>

  • Implementation

As I said before, we are only gonna create an wrapper on top of Jeff Mesnil’s great JS library for Stomp. So let’s first create an overlay type for our message object. This is pretty straight forward. I’ve created two classes for this:

package com.furiousbob.jms.client;
 
import com.google.gwt.core.client.JavaScriptObject;
/**
 * 
 * @author Vinicius Carvalho
 * 
 * An overlay on top of the StompJS message object. Messages can be created by using the
 * static method
 *
 */
public class Message extends JavaScriptObject {
	protected Message(){}
 
 
	public final native String getBody()/*-{  
		return this.body;
	}-*/;
 
	public final native Header getHeaders()/*-{
		return this.headers;
	}-*/;
 
	public static final native Message create(String json)/*-{
		return eval('(' + json + ')');
	}-*/;
 
}
 
 
package com.furiousbob.jms.client;
 
import com.google.gwt.core.client.JavaScriptObject;
/**
 * 
 * @author Vinicius Carvalho
 * 
 *
 */
public class Header extends JavaScriptObject {
	protected Header(){}
 
	public final native String getDestination()/*-{
		return this.destination;
	}-*/;
 
	public final native Integer getExpires()/*-{
		return this.expires;
	}-*/;
 
	public final native String getSubscription()/*-{
		return this.subscription;
	}-*/;
 
	public final native String getId()/*-{
		return this["message-id"];
	}-*/;
 
	public final native Integer getPriority()/*-{
		return this.priority;
	}-*/;
 
	public final native Long getTimestamp()/*-{
		return this.timestamp;
	}-*/;
 
 
 
 
}

GWT Overlays allows us to use JS Objects as regular java objects on our code. Most of the contents of those objects are native code anyways. No worries so far …

Since we are going to use the JS Stomp library, you’ll have to install it on your GWT code. I’m sure there are hundreds of ways of doing that, I’ve just picked the one I found the best ok?

Pack the stomp.js file inside your project in a public folder, refer to this page to have an idea. So, in our case I’ll just put it under the main package folder.

Next, we’ll have to install it on our application. So the following class will do the trick once it’s install() method gets called:

package com.furiousbob.jms.client;
 
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.ScriptElement;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.TextResource;
 
public class StompJS {
	protected interface Resources extends ClientBundle {
		@Source("com/furiousbob/jms/stomp.js")
		TextResource stompjs();
	}
 
	private static final Resources RESOURCES = GWT.create(Resources.class);
	private static boolean installed = false;
 
	public static synchronized void install() {
		if (!installed) {
			ScriptElement e = Document.get().createScriptElement();
			e.setText(RESOURCES.stompjs().getText());
			Document.get().getBody().appendChild(e);
			installed = true;
		}
	}
 
	private StompJS() {
	}
}

This code will get the JS file as an resource, and them manipulate the DOM structure of your page installing it, so you could use the classes of this project. I’d recommend installing this on your onLoad method of your entry-point:

public void onModuleLoad() {
		StompJS.install();
}

Before getting to the class itself I’ve just want to show a callback interface you may use within it. This interface will allow you to get notifications from the JS client upon some events. I believe the interface is pretty simple and easy to understand:

package com.furiousbob.jms.client;
/**
 * 
 * @author Vinicius Carvalho
 *
 */
public interface ConnectionCallback {
	/**
	 * Called on connection to the JMS broker
	 */
	void onConnect();
	/**
	 * Called on an error or disconnection from the broker
	 * @param cause - the reason behind the error
	 */
	void onError(String cause);
 
	/**
	 * Called on a disconnection initiated from the client
	 */
	void onDisconnect();
}
 
package com.furiousbob.jms.client;

In order to receive the message you should also implement an interface: MessageListener (just like you would with regular JMS), that interface is going to be called when a message is received:

package com.furiousbob.jms.client;
 
/**
 * 
 * @author Vinicius Carvalho
 * Marker interface that receives messages from the broker
 */
public interface MessageListener {
	public void onMessage(Message message);
}

Now to the main class that is going to handle all the plumbing:

Now before you continue… This is a working in progress, there’s a lots to improve, no exceptions, no way to provide the login/pwd so far.

I’ll do my best to update the project files and make this at least an usable project. But the whole intention here was just to prove a concept more than providing an 3PP library.


 package com.furiousbob.jms.client;
/**
 * 
 * @author Vinicius Carvalho
 * Wraps the Stomp JS client.
 * 
 * This class connects to a remote broker and maintains a list of subscriptions.
 * Each subscription is associated if a MessageListener. Only one instance of this class
 * should exist per server, and subscriptions to different channels (Queue/Topic) should be
 * created as required.
 * 
 */
public class StompClient {
 
	String url;
	ConnectionCallback callback;
 
	public StompClient(String url){
		this(url,null);
	}
 
	public StompClient(String url, ConnectionCallback callback){
		this.url = url;
		this.callback = callback;
		init();
	}
 
	private native final void init()/*-{
		$wnd.subscriptions = new Array();
		$wnd.stompClient = $wnd.Stomp.client(this.@com.furiousbob.jms.client.StompClient::url);
	}-*/;
 
 
	/**
	 * Connects to the JMS broker and invokes the callback interface if one was provided
	 */
	public native final void connect() /*-{
		var that = this;
		var onsuccess = function(){
			that.@com.furiousbob.jms.client.StompClient::onConnect()();
		}
		var onfail = function(cause){
			that.@com.furiousbob.jms.client.StompClient::onError(Ljava/lang/String;)(cause);
		}
		$wnd.stompClient.connect('guest','guest',onsuccess,onfail);
	}-*/;
 
	/**
	 * Disconnects from the server and removes any subscriptions that are still active
	 */
	public native final void disconnect() /*-{
		var that = this;
		if($wnd.subscriptions.length > 0){
			for(var i=0;i<$wnd.subscriptions.length;i++){
				$wnd.stompClient.unsubscribe($wnd.subscriptions[i]);
			}
		}
		var ondisconnect = function(){
			that.@com.furiousbob.jms.client.StompClient::onDisconnect()();
		}
		$wnd.stompClient.disconnect(ondisconnect);
}-*/;
	/**
	 * Subscribes the given listener to a certain destination. An identifier from the subscription is returned
	 * that id should be used to unsubscribe from the channel
	 * @param channel - The name of the Queue/Topic
	 * @param listener - Implementation of your message Listener
	 * @return Subscription Identifier
	 */
	public native final String subscribe(String channel, MessageListener listener)/*-{
		var onmessage = function(message){
			listener.@com.furiousbob.jms.client.MessageListener::onMessage(Lcom/furiousbob/jms/client/Message;)(message);
		}
		var id = $wnd.stompClient.subscribe(channel,onmessage);
		$wnd.subscriptions.push(id);
		return id;
	}-*/;	
	/**
	 * Unsubscribe from the channel.
	 * @param subscriptionId The id of the subscription to be unsubscribed
	 */
	public native final void unsubscribe(String subscriptionId)/*-{
		var idx = $wnd.subscriptions.indexOf(subscriptionId);
		$wnd.subscriptions.splice(idx,1);
		$wnd.stompClient.unsubscribe(subscriptionId);
	}-*/;
	/**
	 * Sends a message with the headers to a destination
	 * @param destination - The id of the Channel
	 * @param message - The Message with the headers
	 */
	public native final void send(String destination, Message message)/*-{
		$wnd.stompClient.send(destination, message.headers, message.body);
	}-*/;
	/**
	 * Sends a text to a destination.
	 * @param destination - The id of the Channel
	 * @param body - The message contents as a String
	 */
	public native final void send(String destination, String body) /*-{
		$wnd.stompClient.send(destination,{},body);
	}-*/;
 
	void onConnect(){
		if(callback != null){
			callback.onConnect();
		}
	}
 
	void onError(String cause){
		if(callback != null){
			callback.onError(cause);
		}
	}
 
	void onDisconnect(){
		if(callback != null){
			callback.onDisconnect();
		}
	}
 
}

  • Using

Now the easy and fun part :) .To use the project, register this module on your gwt.xml file:

<inherits name="com.furiousbob.jms.StompJMS"></inherits>

Don’t forget to call the install on the StompJS class. To receive messages on your code:

ConnectionCallback cbk = new ConnectionCallback() {
 
			@Override
			public void onError(String message) {
				Window.alert(message);
			}
 
			@Override
			public void onDisconnect() {
				Window.alert("Disconnected from server");
 
			}
 
			@Override
			public void onConnect() {
				Window.alert("Connected");			
			}
		};
 
		final StompClient client = new StompClient("ws://localhost:61614/stomp",cbk);
		client.connect();
		final MessageListener listener = new MessageListener() {
 
			@Override
			public void onMessage(Message message) {
				//Do something cool with your  message
			}
		};
client.subscribe("jms.queue.ExampleQueue", listener);

You can skip the MessageCallback if you don’t want to be notified of events.

Sending messages is even simpler:

client.send("jms.queue.ExampleQueue", "Hello World");
//or
client.send("jms.queue.ExampleQueue", Message.create("{'body':'This is a test', 'headers':{'priority':1}}"));

As you can see, sending is even simpler :)

There’s still room for lots of improvements but, the general idea is having a pure “Java” code in your project to send/receive JMS Messages :D

The initial code is located at google-code. I’m sorry about the project mess, I’ll clean it with the time, mavenize it ;) and improve the classes and interfaces. But at least it’s there for you if you want to start playing with it.

  • Conclusions

This is just a start, there’s lots to improve here. One aspect is the connection control, due the nature of GWT projects, when you move to a different Place (aka Page) a better control on what should be done with the connection is desired. There’s improvements on the exception handling and the class methods of course.


This was more a Proof Of Concept than a real project use. I’m still experimenting those things. Websocket support is really under a threat right now, as Firefox dropped the support on the final relase of Firefox 4.


The best alternative for a push model is to use Errai, it does not use websockets, and hence you have a better support on browsers. But again, the idea of this post is just to prove an idea :)

I guess that is it, enjoy the code, and don’t forget to comment, post bugs on the project site, I hope to get a stable version of it in a few weeks.

Happy Coding