Sunday, 21 August 2011

Test non-determinism, software design and agile...

Unit tests make it possible to write clean units of code and helps in maintaining such units of code with enough confidence as they evolve. Much like any other code, unit testing code too will become unmanageable and untrustworthy if not written properly. One of the symptoms of a badly written unit test is it's non-determinism. In a wonderful talk (see below), Martin Fowler points out the causes for test non-determinism and provides his solution to tackle them.

In the same talk, he takes on the need for Software Design. He emphasis how internal quality of a clean software would come to help in reduced cost while adding new features, his Design Stamina Hypothesis and different ways in which design is compromised.

He also touches Agile, identifying where are we now in the agile movement and where are we heading and what to expect. Overall, a nice presentation to watch and learn from.

Some highlighting points:

  • Non-deterministic test is WORSE than useless

  • Badly designed software is a sin

  • Global variables are created by satan as a trap for developers

  • Never name a method badly

  • Never compromise on design

  • Design is a continuous learning


Here is the full talk. Enjoy.

Sunday, 31 July 2011

Joined JUG Chennai!

This weekend I have formally(well, there is no formality though) joined the JUG Chennai group, attended my first session in OrangeScape office at Tidel Park. It was an interesting experience with a bunch of guys discussing Java and something beyond. This group is very young and I can see it is well placed to grow as an important forum for Java enthusiasts. Communities are vital for any open technologies such as Java and there is lot of free knowledge available for everyone within communities like JUG.

Interested? Join the group at http://groups.google.com/group/jug-c and watch for events at http://jug-c.wikispaces.com/.

Good luck!


Tuesday, 21 June 2011

Java Instance Initialiser

I have almost always taken the Java object creation process for granted, mainly because there is nothing much to do for me and if I write my constructor properly, it will do it. When I have an integer field, let's say pages in a class called Book, I never cared to see if explicitly initialising this with a value such as 0 makes any sense in my constructed object since the default integer (when used primitive int) itself is 0. It may not be good as an example but something similar in an age old code made me to realise that though the values are the same, since the explicit initialisation of a field happens after the object construction in the parent classes, they could produce different results.

The following simple code would probably make you to think a while whether it would print 0 or 100.


public abstract class Book {
 public Book() {
  setPages(100);
 }
 public abstract void setPages(int pages);
 public abstract int getPages();
}

public class MyBook extends Book {
 private int pages = 0;

 public void setPages(int pages) {
  this.pages = pages;
 }

 public int getPages() {
  return pages;
 }

 public static void main(String[] args) {
  Book myBook = new MyBook();
  System.out.println(myBook.getPages());
 }
}

It may be obvious for some but the point is that why not 100? Simply because the initialisation of a field happens after the construction of parent objects and prior to the code within it's own constructor, whatever value the field got to have during the parent objects construction is simply vanished. I think it is more of a philosophy of a language based on it's principles than any hard and fast rules. For instance, the same piece of code in C# which is considered to be a close one to Java in many ways would behave just the opposite.

Tuesday, 7 June 2011

Inexperienced Linus!

I was totally taken aback when I heard from Linus Torvalds that he did not know C Programming and not heard of Unix till the previous year (1990) of his project Linux!. While what makes something like that possible is only Linus can explain, I wonder how many of us would have counted for an inexperienced guy in Linus for a project of Linux kind in the conventional software development environment?


Saturday, 4 June 2011

Immutable objects. Really?

One of the important characteristics of the object world is favour immutability. It's a simple and efficient way of protecting data and functionality of an object from misuse by the users for years to come. When an object is composed of Java library classes (such as java.util.Date or java.sql.Time) or other third party classes which are themselves mutable, then the immutability is broken thus there is a possibility for the change of state of the object by other objects.

The following class, RequestBatch looks pretty much like immutable given that it does not allow inheritance and provides no mutators. But it's field _requestsBatch breaks all of it.

import java.util.ArrayList;

import java.util.List;



public class RequestBuilder {



 public static void main(String[] args) {



  List<requestbatch> requestBatchList = new ArrayList<requestbatch>();

  List<String> requests = new ArrayList<String>();

  for (int reqBatchCount = 0; reqBatchCount < 5; reqBatchCount++) {

   for (int reqCount = 0; reqCount < 10; reqCount++) {

    requests.add("Request_" + reqBatchCount + "_" + reqCount);

   }

   RequestBatch requestBatch = new RequestBatch(requests);

   requestBatchList.add(requestBatch);

   requests.clear();

  }



  for (RequestBatch requestBatch : requestBatchList) {

   for (String request : requestBatch.getRequests()) {

    System.out.println(request);

   }

  }

 }

}
If we attempt to print the requests in the batches, we see no requests get printed as there were none stored. All the five batches have no requests but empty list. Though this might be obvious given that the constructor is passed with a copy of the reference value of the same List (pass-by-value) all the time, the clear() method clears the _requestBatch member of the supposed to be immutable objects without their knowledge.
So, care must be taken when creating an object composing of mutable objects. With the defensive copying of the in and out parameters, the following RequestBatch class would make it possible to create immutable objects.
import java.util.ArrayList;

import java.util.List;



public final class RequestBatch {



 private List<String> _requestBatch;



 public RequestBatch(List<String> requests) {

  _requestBatch = new ArrayList<String>(requests);

 }



 public int batchSize() {

  return _requestBatch.size();

 }



 public List<String> getRequests() {

  return Collections.unmodifiableList(_requestBatch);

 }

}

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.