Tuesday, December 14, 2010

Thread Working For Fixed Time Even In Case Of Exceptions (UncaughtExceptionHandler)

Somebody asked me how to keep running a thread for a fixed interval even there is some exception.
At that point of time i had no answer.

But now i think, i have the answer.

And this can be done using the interface Thread.UncaughtExceptionHandler.

UncaughtExceptionHandler is an inner interface of Thread class.

We can implement it and set it using the method setUncaughtExceptionHandler() of Thread class.

Here is an example.

class MyThread extends Thread {
 
private boolean flag; 
protected int counter=0;
MyThread(int counterInitialValue) {
   this.counter = 0;
}

public MyThread(Runnable r,int counterInitialValue) {
   super(r);
   this.counter = counterInitialValue;
   this.flag = true;
}

@Override
public void run() {
 if (!flag) {
 flag = true;
 System.out.println("Thread Exec Started");
 } else {
 System.out.println("Thread Running Again");
 }
 while (counter <20) {
  counter++;
  try {
   Thread.sleep(1000);
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
// do some work here....
  if(counter % 3 == 0){
    System.out.println(" Thread working , 
          counter value is : "+ counter);
  }
  if (counter == 10) {
   throw new RuntimeException("I am throwing exception");
  }
   
  }
 }
}

class MyThreadExceptionHandler implements 
        Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, 
                              Throwable e) {
  MyThread oldThread = (MyThread) t;
  System.out.println("Received exception "+ 
                           e.getMessage());
  if (oldThread.counter < 20) 
  {
   System.out.println("Value of counter 
       (restart required) : " + oldThread.counter);
   
   MyThread newThread = new MyThread(oldThread,11);
   
   newThread.start();
  } 
  else 
  {
   System.out.println("Thread work done");
   System.out.println("Value of counter : " +
                       oldThread.counter);
  }
 }
}



public class ThreadRunningForFixedTime {
public static void main(String[] args) {
  MyThread th = new MyThread(0);
  MyThreadExceptionHandler handler = 
          new MyThreadExceptionHandler();
  th.setUncaughtExceptionHandler(handler);
  th.start();
 }
}

Monday, December 6, 2010

How to make a non-serializable class serializable

I have a class which is not serializable. If i will try to serialize the object of it than i am going to get exception "java.io.NotSerializableException"

And now if this class is not not modifiable/available to modify (may be its a third party), and so we do not have any control.

for e.g following is the non serializable class
class MyNonSerializableClass {
 String str = new String("mystring");
 MyNonSerializableClass(){
  
 }
 MyNonSerializableClass(String s) {
  this.str = s;
 }

 public String getStr() {
  return str;
 }

 public void setStr(String str) {
  this.str = str;
 }

}



In order to serialize the object we can write a wrapper class over MyNonSerializableClass and which is implementing Serializable interface.
And the most important thing, we control the readObject and writeObject methods so that we can decide what need to be written with the wrapper class.

something like this:

class MyNonSerializableClassWrapper extends MyNonSerializableClass implements Serializable {
 MyNonSerializableClassWrapper(){
  super();
 }
 MyNonSerializableClassWrapper(String s) {
  super(s);
 }

 private void writeObject(ObjectOutputStream out) throws IOException {
  // not required the default write object
  // ----> out.defaultWriteObject();
  out.writeObject(super.getStr());
 }

 private void readObject(ObjectInputStream in) throws IOException {
  // not required the default read object
  // ----> in.defaultReadObject();
  try {
   super.setStr((String) in.readObject());
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  }
 }
}


As the wrapper class itself does not have any properties/attributes so defaultread and write is not required.
By getting the super class value and setting it during the write and read to serialized object we can achieve the serialization and deserialization even if a class is not implementing Serializable interface.


private void WriteObjectToFile() {
try {
  FileOutputStream fo = new FileOutputStream("c:\\test.ser");
  ObjectOutputStream os = new ObjectOutputStream(fo);
  os.writeObject(new MyNonSerializableClassWrapper("This is a test of 
                                           serialization"));
  fo.close();

  } 
  catch (FileNotFoundException e) {
    e.printStackTrace();
  } 
  catch (IOException e) {
    e.printStackTrace();
  }
}


private void ReadObjectFromFile() {
try {
  FileInputStream fi = new FileInputStream("c:\\test.ser");
  ObjectInputStream in = new ObjectInputStream(fi);
  MyNonSerializableClassWrapper mw = (MyNonSerializableClassWrapper) 
  in.readObject();
  fi.close();
  System.out.println("serialized object value is: " + mw.getStr());
  } 
  catch (FileNotFoundException e) {
      e.printStackTrace();
  } 
  catch (IOException e) {
    e.printStackTrace();
  } 
  catch (ClassNotFoundException e) {
    e.printStackTrace();
  }
}