Wednesday, 27 April 2011

Handling legacy RMI using Spring remoting

For a POC, I had to work with an external system (J/XFS Device Services) which used RMI as the communication mechanism where exporting and consuming RMI services seemed little slumbering. Since Spring remoting handles it quite good, I used it to get the stuff done quickly. I have given a stripped-down version here as a simple example for RMI using Spring remoting.

The following interface InputDevice is the service interface which the clients will have access to. This is the interface which supposed to extend Remote interface in the conventional RMI implementation either directly or indirectly. It is a very simple interface here with the overhead left to Spring.

InputDevice.java

public interface InputDevice {



 public boolean open();

 

 public byte[] read();

 

 public boolean close();

 

}

A simple implementation of this InputDevice is a Scanner which is given below. This is actually the implementation which would provide the required functionality to the client which would invoke the methods in InputDevice.

Scanner.java

public class Scanner implements InputDevice {



 @Override

 public boolean open() {

  // code which opens the scannner

  return true;

 }



 @Override

 public byte[] read() {

  // code which scans the data. Only dummy data now :-(

  String message = "SCANNED_DATA_DUMMY_" + System.currentTimeMillis();

  return message.getBytes();

 }



 @Override

 public boolean close() {

  // code which closes the scanner

  return true;

 }



}


Having the remote service interface and an implementation ready, now let's focus on how to export this service through RMI. The following DeviceServer class uses the RmiServiceExporter to export the InputDevice service.

The main method in this class can be executed which would export the service at port 54321 in the localhost and ready to serve the requests.

DeviceServer.java

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.rmi.RemoteException;



import org.springframework.remoting.rmi.RmiServiceExporter;



public class DeviceServer {



 public static void main(String[] args) {

  try {

   RmiServiceExporter serviceExporter = exportService();

   System.out.println("Server started. Enter stop to stop it.");

   BufferedReader reader = (new BufferedReader(new InputStreamReader(

     System.in)));

   while (!"stop".equalsIgnoreCase(reader.readLine()))

    ;

   serviceExporter.destroy();

  } catch (IOException e) {

   throw new RuntimeException(e.getCause());

  }

 }



 private static RmiServiceExporter exportService() throws RemoteException {

  RmiServiceExporter serviceExporter = new RmiServiceExporter();

  serviceExporter.setServiceInterface(InputDevice.class);

  serviceExporter.setService(new Scanner());

  serviceExporter.setServiceName("ScannerService");

  serviceExporter.setRegistryPort(54321);

  serviceExporter.afterPropertiesSet();

  return serviceExporter;

 }

}

This simple server would run until stop is entered.

The following simple client consumes the InputDevice service through RMI. It uses RmiProxyFactoryBean to consume the service. Here is the code which can be run to see it consume the service.

DeviceClient.java

import org.springframework.remoting.rmi.RmiProxyFactoryBean;



public class DeviceClient {



 public static void main(String[] args) {

  InputDevice inputDevice = getInputDevice();

  boolean opened = inputDevice.open();

  if (opened) {

   byte[] data = inputDevice.read();

   System.out.println("Data read:" + new String(data));

   inputDevice.close();

  }

 }



 private static InputDevice getInputDevice() {

  RmiProxyFactoryBean proxyFactory = new RmiProxyFactoryBean();

  proxyFactory.setCacheStub(false);

  proxyFactory.setServiceInterface(InputDevice.class);

  proxyFactory.setServiceUrl("rmi://127.0.0.1:54321/ScannerService");

  proxyFactory.afterPropertiesSet();

  InputDevice inputDevice = (InputDevice) proxyFactory.getObject();

  return inputDevice;

 }

}

Using Spring bean configuration, the same could be achived configuring the RmiServiceExporter and RmiProxyFactoryBean beans.


Saturday, 9 April 2011

Simple Java deadlock detector

Thanks to extensive testing, Application MultithreadedMessenger from QualitySoftware Inc., has been running without any critical bugs since it's go-live last month. The customer, MrBigBank is happy faced since it is one of the important pieces of his solution architecture. One fine early morning MultithreadedMessenger stopped working. After an hour, a smart guy at the back office realised the application is busy fighting within itself and not ready to serve the incoming requests. Knowing that it is not going to return ever, he restarts the application and phones the vendor's help desk for a solution.

Though deadlocks related bugs are rare in a production quality system, when they appear, sometime there would be hours of complex investigation required. Java provides enough help in identifying threads which are deadlocked through it's management library. The following is a simple example where we create a dead lock situation and a deadlock detector to detect and report when the deadlock occurs.

Class Messenger is a mock application which provides send and receive methods to handle the messaging. This class is written (well, badly!) just to create a situation where two threads will get into waiting for each other.

Messenger.java

public class Messenger {

 private Lock senderLock = new Lock();
 private Lock receiverLock = new Lock();

 public void send(String message) {
  synchronized (senderLock) {
   synchronized (receiverLock) {
    //some code here
   }
  }
 }

 public String receive() {
  synchronized (receiverLock) {
   synchronized (senderLock) {
    // some code here
    return "SUCCESS";
   }
  }
 }
}

class Lock {
}

A DeadlockDetector uses the managed beans provided by java.lang.management package to detect the threads which are deadlocked and reports with the thread information.

DeadlockDetector.java

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;

public class DeadlockDetector implements Runnable {

 private volatile boolean _detected = false;

 public synchronized boolean detected() {
  return _detected;
 }

 @Override
 public void run() {
  while (true) {
   ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
   long[] deadlockedThreads = tmx.findDeadlockedThreads();
   if (deadlockedThreads != null) {
    ThreadInfo[] threadInfos = tmx.getThreadInfo(deadlockedThreads);
    for (ThreadInfo threadInfo : threadInfos) {
     System.out.println(threadInfo);
    }
    _detected = true;
    break;
   }
  }
 }
}

Finally, DeadlockTest class which runs the Messenger application and the DeadlockDetector to halt and report when the deadlock occurs.

DeadlockTest.java

public class DeadlockTest {

 public static void main(String[] args) {
  
  DeadlockDetector deadlockDetector = new DeadlockDetector();
  new Thread(deadlockDetector).start();

  final Messenger messenger = new Messenger();

  while (!deadlockDetector.detected()) {

   new Thread(new Runnable() {

    @Override
    public void run() {
     String message = "blah blah";
     messenger.send(message);
    }
   }, "foo").start();

   new Thread(new Runnable() {

    @Override
    public void run() {
     String message = messenger.receive();
    }
   }, "bar").start();
  }
 }
}

Much like the same way, other managed beans for memory, gc,class loading, compilation and runtime are accessible with simple test classes.

The same managed beans feed information to utilities like jconsole or jvisualvm, making it possible to completely monitor and manage the JVM.

Saturday, 26 February 2011

Eclipse TreeView generic interfaces

Tree views in Eclipse plug-ins provide much elegant ways to present the recursive data. Perhaps they handle the parent-child relationships among the nodes more intuitively than any other view representation. When I wanted to put some 'kind' of model objects as nodes in a tree view, I wanted to create a small reusable group of classes which will make the process of putting an object in a tree little simpler. Though it is not of any design pattern kind of stuff, I have benefitted rather significantly from this simple interface layer later.

This interface layer constitutes of two interfaces, TreeNode and TreeInput representing each node and the input to the tree respectively. TreeNode contract makes it possible for the tree viewer with all the data it requires such as name of the node, any associated image and whether it has any child nodes or not. The TreeInput contract represents the input to the tree viewer. Following is the complete source code of these two main contracts.

TreeNode.java

import org.eclipse.swt.graphics.Image;



public interface TreeNode {



 // Returns name of the node

 public String getText();



 // Returns image of the node

 public Image getImage();



 // Returns if this node has any child or not

 public boolean hasChildren();



 // Returns it's child nodes

 public TreeNode[] getChildren();



 // Returns it's parent node

 public TreeNode getParent();

}

TreeInput.java

import java.util.List;



public interface TreeInput {

 

 // Returns the list of top level nodes as input to the tree viewer

 public List<TreeNode> getInput(); 



}



Having set the stage, let's take a use case as we want to create a simple tree view for a file system. That essentially two types nodes: directory and file. The root of the tree is the root of the file system (or any relative location) from where the top level directories, with no parent come as nodes. Only directory type nodes can have children nodes which are again either directory nodes or file nodes. And, let's consider someone called FileViewInputProvider is what the tree view looks for input which actually provides all the top level nodes through TreeInput.

Content and display to a tree viewer can be controlled by ITreeContentProvider and LabelProvider. A generic implementation to the content provider returns nodes through the callbacks. For example, the hasChildren() method checks the TreeNode to see whether or not it has child nodes. The getChildren(Object obj) is called when a tree node is expanded at the view which actually gets the child nodes from the TreeNode#getChildren().

TreeContentProvider.java

import java.util.List;



import org.eclipse.jface.viewers.ITreeContentProvider;

import org.eclipse.jface.viewers.Viewer;



public class TreeContentProvider implements ITreeContentProvider {



 @Override

 public Object[] getChildren(Object parentElement) {

  if (parentElement instanceof TreeNode) {

   return ((TreeNode) parentElement).getChildren();

  } 

  if (parentElement instanceof TreeInput) {

   return getElements(parentElement);

  }

  return new Object[0];

 }



 @Override

 public Object getParent(Object element) {

  if (element instanceof TreeNode) {

   return ((TreeNode) element).getParent();

  }

  return null;

 }



 @Override

 public boolean hasChildren(Object element) {

  if (element instanceof TreeNode) {

   return ((TreeNode) element).hasChildren();

  }

  return false;

 }



 @Override

 public Object[] getElements(Object inputElement) {

  if (inputElement instanceof TreeInput) {

   List<TreeNode> input = ((TreeInput)inputElement).getInput();

   return input.toArray();

  }

  return new Object[0];

 }



 @Override

 public void dispose() {

  // Do nothing. Subclasses may override.

 }



 @Override

 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {

  // Do nothing. Subclasses may override.

 }



}



Label provider is called once the content is set and ready to display in the viewer. It essentially provides a name to the  node and an associated image. The generic label provider TreeLableProvider extends LabelProvider and overrides the getText(Object obj) and getImage(Object obj) methods. For these data, the label provider rely on the TreeNode contract.

TreeLabelProvider.java

import org.eclipse.jface.viewers.LabelProvider;

import org.eclipse.swt.graphics.Image;



public class TreeLabelProvider extends LabelProvider {



 /**

  * Returns the text to be displayed in the tree view

  */

 public String getText(Object obj) {

  if (obj instanceof TreeNode) {

   return ((TreeNode) obj).getText();

  }

  return (obj != null) ? obj.toString() : "???";

 }



 /**

  * Returns the image to be displayed in the tree view

  */

 public Image getImage(Object obj) {

  if (obj instanceof TreeNode) {

   return ((TreeNode) obj).getImage();

  }

  return null;

 }



}



These simple interfaces would help creating tree views quickly by providing the required contract between the Eclipse tree viewer objects and the node input objects. This reusability provides speed and less maintenance while working with Eclipse tree views.

Monday, 27 December 2010

Hello World!

I am one of the lucky lot who write software for living. This weblog entries here are from my encounter with the fascinating world of technologies which I choose to live with. It would predominantly be simple technical bits out of my experiences and I'll feel great (and obviously humble) if it is of any use to you.

Thank you for visiting.