Friday, December 12, 2014

Getting a hook on Shutting down of JVM.

Getting a hook on Shutting down of JVM

Hey, Today I going to share my experience on getting a hook on shutting down of JVM.

Let us Take an Example.

Suppose I have to use functionality from a class on which I don't have control(Some 3rd party jar), and that class throws some Runtime Exception at some point. What would happen in this case? Certainly this will terminate my program and shutdown JVM and my some background running thread may have to stop before completion. I hope you can't afford this happen.

There may be some code written in 3rd party jar which calls System.exit() (you never know). Then also same thing is going to happen.

You would say I should call that 3rd party jar in try block and give a finally block to ensure that my background thread completes before halting the JVM.

But what would you do if it has System.exit(), you finally block would not execute in this case.

Java has provided a better way to handle this crucial scenario. Java has provided a hook before JVM shutsdown. Runtime.addShutdownHook(Thread).

This method ask for a thread which can execute your task before JVM halts.

This is useful when you have some background threads running and JVM is going to halt abruptly due to some Exception or exit call. You can do some essential task or you can do some important logging.

Runtime.getRuntime().addShutdownHook(new Thread() {  
           public void run() {  
                System.out.println("Inside Shutdouwn hook");  
                Set<Thread> threads = Thread.getAllStackTraces().keySet();  
                for(Thread thread:threads){  
                     if (thread.isAlive() && thread.isDaemon()) {  
                          if ("Deamon".equals(thread.getName())) {  
                               try {  
                                    thread.join();  
                                    System.out.println("my " + thread.getName() + " Thread completed.");  
                                    break;  
                               } catch (InterruptedException e) {  
                                    // TODO Auto-generated catch block  
                                    e.printStackTrace();  
                               }  
                          }  
                     }  
                }  
           }  
      });          

In the above code we can see that I have added a Thread with run method where, I am concerned about a daemon thread which should be executed before ending JVM. So, I just took all the Threads available with JVM and looked for my concerned thread and let it execute first by joining it to current thread.

Hope, this would help you achieving some unavoidable stuffs done. You feedback is most welcomed.


CHEERS!!!

Wednesday, October 22, 2014

Playing with Uncaught Exceptions in Java


Well, Once I got a scenario when someone asked me about Runtime Exceptions.  We know that Runtime Exception should not be caught using catch block. Rather it is handled by JVM. So JVM prints the stack trace and ends the program.

Is there any way to have little control on handling of these uncaught exceptions?



As in the above diagram, we can see the hierarchy of exceptions in Java. There could be 2 scenario when an exception could be uncaught.
   

  1.     Using Try – finally block without Catch : So here exception is not caught and it  is automatically propagated to upper call hierarchy to handle it and finally reaches to JVM
  2.    Occurrence of RunTime Exceptions which are directly handled by JVM.

In both the cases above JVM exception handler will take care of this.
Java provides a beautiful API to have little control over Uncaught Exception handling before JVM does it. This is Uncaught Exception Handler API of JVM.

Think of a scenario where you want an email or sms to be sent to some concerned persons or any other application to be invoked,  etc just when a uncaught exception or runtime exception occurs and JVM terminates the program. At this point you would be needing some hook point where you can process your customization and get noticed. This can be provided by implementing Thread.UncaughtExceptionHandler.
So create a Class which would implement Thread.UncaughtExceptionHandler and then use Thread.currentThread().setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
Let’s understand this with an example.
public class TestUncaughtException {

       public static void main(String[] args) {
              Thread.currentThread().setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
              //try{
                     int i = 0;
                    
                     System.out.println(50/i);
                     System.out.println("hello");
       //     }
              /*catch(Exception e){
                     System.out.println("in catch");
              }
              finally{
                     System.out.println("divide by zero");
              }*/
       }
}

class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{

       @Override
       public void uncaughtException(Thread t, Throwable e) {
              System.out.println("in handler");
              //System.out.println(e.getMessage());
              //e.printStackTrace();
              // Custom code to do any extra processing
              Thread.currentThread().getThreadGroup().uncaughtException(t, e);
       }
      
}

Code above seems to be self-explanatoryMyUncaughtExceptionHandler is my custom hanlder which implements Thread.UncaughtExceptionHandler.
Write your customizations in uncaughtException(Thread t, Throwable e) method.
Who is invoking this method. Yes, it is JVM. JVM calls Thread.dispatchUncaughtException(Throwable e).

/**
     * Dispatch an uncaught exception to the handler. This method is
     * intended to be called only by the JVM.
     */
    private void dispatchUncaughtException(Throwable e) {
        getUncaughtExceptionHandler().uncaughtException(this, e);
    }


If this JVM does not finds any UncaughtExceptionHandler set in specific thread then it calls ThreadGroup. uncaughtException(Thread t, Throwable e). 

Java Doc of this method says : Called by the Java Virtual Machine when a thread in this thread group stops because of an uncaught exception, and the thread does not have a specific Thread.UncaughtExceptionHandler installed.

And finally if this ThreadGroup is also not able to handle this uncaught exception then it is handled by defaultUncaughtExceptionHandler. Which is set by Thread. setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh).

Java Doc for this says: Set the default handler invoked when a thread abruptly terminates due to an uncaught exception, and no other handler has been defined for that thread. Uncaught exception handling is controlled first by the thread, then by the thread's ThreadGroup object and finally by the default uncaught exception handler. If the thread does not have an explicit uncaught exception handler set, and the thread's thread group (including parent thread groups) does not specialize its uncaughtException method, then the default handler's uncaughtException method will be invoked.

If you want to have more control on handling these exceptions then you can try AOP which has got extra features to do it. But this hook provided by JVM to have little control over it makes life easier enough.

Hope you like this article. Queries and suggestions are most welcome.


CHEERS!!!

Sunday, August 10, 2014

Using reexport with Require-Bundle in Manifest.mf.

Hi,

Today I am going to give a small description on use of  'reexport' with Require-Bundle in Manifest.mf.

Require-Bundle is used to add dependencies to other bundles.

Example:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: P2
Bundle-SymbolicName: p2
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: p2.Activator
Require-Bundle: org.eclipse.ui,
 org.eclipse.core.runtime
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ActivationPolicy: lazy
Export-Package: p2

What is reexport feature in Require-Bundle.

OSGI has given a directive called 'visibility' which can be used with 'Require_bundle'.
If the value is private (Default), then all visible packages from
the required bundles are not re-exported. If the value is reexport then
bundles that require this bundle will transitively have access to these
required bundle’s exported packages.

Eg:

Require-Bundle: org.eclipse.ui,
 org.eclipse.core.runtime,
 p1;bundle-version="1.0.0";visibility:=reexport

Here P1 bundle is re-exported to other dependent plugins.
Let us understand this with a simple exmaple.

1. Create 3 plugin projects P1, P2, P3.
2. Situation is : P3 requires P2. P2 requies P1. Now add add theses dependencies.
-----------------------------------------------------------------------------------------------------
Eg:
Manifest of  P3: 
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: P3
Bundle-SymbolicName: p3
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: p3.Activator
Require-Bundle: org.eclipse.ui,
 org.eclipse.core.runtime,
 p2;bundle-version="1.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ActivationPolicy: lazy

Manifest of P2:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: P2
Bundle-SymbolicName: p2
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: p2.Activator
Require-Bundle: org.eclipse.ui,
 org.eclipse.core.runtime,
 p1;bundle-version="1.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ActivationPolicy: lazy
Export-Package: p2

Manifest of P1:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: P1
Bundle-SymbolicName: p1
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: p1.Activator
Require-Bundle: org.eclipse.ui,
 org.eclipse.core.runtime
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ActivationPolicy: lazy
Export-Package: p1
------------------------------------------------------------------------------------------------------

3. Now if you try to access any class of p1 from p3 it will say that p1 is not resolvable.
4. How can i still access P1 exported package? They way left is adding P1 as require bundle in P3.

5. There is another way of doing it. As we see that P3 requires P2.
    And P2 as access to P1, So P2 can re-export the P1 bundle to its dependents for access.
    This can be done using visibillity:reexport.

eg:

Manifest of P2:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: P2
Bundle-SymbolicName: p2
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: p2.Activator
Require-Bundle: org.eclipse.ui,
 org.eclipse.core.runtime,
 p1;bundle-version="1.0.0";visibility:=reexport
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ActivationPolicy: lazy

Export-Package: p2


So, Now I am able to access P1 from P3 as well.


----------------------------------------------------------------------------------------------------------
Another use of using visibility:reexport:

Situation: Let us suppose that we have a Plugin A and Plugin B requires Plugin A.
                 Now there is a business requirement to break Plugin A into smaller bundle due to some re factoring or so.
Now breaking break Plugin A as Plugin A, Plugin A1, Plugin A2.

So Plugin A----> requires  Plugin A1 and Plugin A2.

What changes needs to be done in Plugin B to work this application correctly?
Yes correct, No change in Plugin B would be required if we use visibility:reexport derivative.

Simply, re-export the bundles which Plugin A requires and Plugin B will be able to use it without any error.

eg:
Entry in Plugin A manifest.

Require-Bundle: A1;visibility:=reexport,
                          A2:visibility:=reexport

----------------------------------------------------------------------------------------------------------------------------------

Please do give your valuable suggestions to improve it and your queries.
Cheers. :)

Thursday, August 7, 2014

Beyond Hello World.

Hi, I got a question from someone to write program to convert Number to word.
I thought to write an simple looking algorithm, but when i started doing this it was not so simple.

Let me rephrase the question.

Convert  Number in the Range of [-999999 , 999999] to words.

Example :  Input no = 45678

output =  Forty Five Thousand Six Hundred And Seventy Eight

Input = -43675
output = Minus Forty Three Thousand Six Hundred And Seventy Five


Program:

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;

public class StringManupulation {

    private static  Map<Integer,String> valueWordMap = new HashMap<>();
   
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
       
        String number;
        while(true){
        System.out.println("Please enter the Numeric No Between -999999 and 999999 : ");
        number = scan.nextLine();
        if(checkIfNumberValid(number)){
            break;
        }
        }
        convertNumberToWords(Integer.valueOf(number));
       
    }

    private static void convertNumberToWords(Integer number) {
        TreeMap<Integer,Integer> faceValueMap = new TreeMap<>();
       
        prepareValueWordMap();
        boolean isNoNegative = false;
        if(String.valueOf(number).contains("-")){
            number = Math.abs(number);
            isNoNegative=true;
           
        }
        Integer baseNo = getBaseNo(String.valueOf(number).length());
        boolean reachedEnd=false;
        int length=0;
        while(baseNo>=1 && !reachedEnd){
            if(baseNo==1){
                reachedEnd=true;
            }
            faceValueMap.put(baseNo, number%(baseNo*10)/baseNo);
            length++;
            baseNo = getBaseNo(String.valueOf(number).substring(length).length());
           
        }
        String word="";
        Integer temp = null;
        String appender="";
        String andString=" And";
        int index=-1;
        for(Integer key : faceValueMap.descendingKeySet()){
            index++;
            if(faceValueMap.get(key)!=0 || null!=temp){
                if(key==1000000 || key == 10000 || key==10){
                    temp=faceValueMap.get(key);
                    continue;
                }
                if(key!=1){
                    appender = " " + valueWordMap.get(key);
                    andString="";
                }
                if((checkTrailingZeros(number,index) || key==1) && !word.isEmpty()){
                    andString=" And";
                }
               
                if(null!=temp){
                   
                    word =  word + andString + " " + valueWordMap.get(temp*10) + " " + valueWordMap.get(faceValueMap.get(key)) + appender;
                }
                else{
                    word =  word + andString +" " + valueWordMap.get(faceValueMap.get(key)) + appender;
                }
                temp=null;
            }
            appender="";
        }
        if(isNoNegative){
            word = "Minus" + word;
        }
        System.out.println(word);
    }

    private static boolean checkIfNumberValid(String number) {
        if(number.length()<8){
            try{
                Integer.parseInt(number);
            }
            catch(Exception ex){
                System.out.println("Invalid No");
                return false;
            }
        Integer i = Integer.valueOf(number);
        if(!(i>=-999999 && i<=999999)){
            return false;
        }
        }
        else{
            return false;
        }
        return true;
       
    }

    private static boolean checkTrailingZeros(Integer number, int index) {
        for(int i = index+1;i<String.valueOf(number).length();i++){
            if(String.valueOf(number).charAt(i)=='0'){
                continue;
            }
            else{
                return false;
            }
        }
        return true;
    }

    private static void prepareValueWordMap() {
        valueWordMap.put(100000, "Lakh");
        valueWordMap.put(10000, "Ten Thousand");
        valueWordMap.put(1000, "Thousand");
        valueWordMap.put(100, "Hundred");
        valueWordMap.put(10, "Ten");   
        valueWordMap.put(1, "One");   
        valueWordMap.put(2, "Two");   
        valueWordMap.put(3, "Three");   
        valueWordMap.put(4, "Four");   
        valueWordMap.put(5, "Five");   
        valueWordMap.put(6, "Six");   
        valueWordMap.put(7, "Seven");   
        valueWordMap.put(8, "Eight");   
        valueWordMap.put(9, "Nine");   
        valueWordMap.put(11, "Eleven");    ;
        valueWordMap.put(12, "Twelve");   
        valueWordMap.put(13, "Thirteen");   
        valueWordMap.put(14, "Fourteen");   
        valueWordMap.put(15, "Fifteen");   
        valueWordMap.put(16, "Sixteen");   
        valueWordMap.put(17, "Seventeen");   
        valueWordMap.put(18, "Eighteen");   
        valueWordMap.put(19, "Nineteen");   
        valueWordMap.put(20, "Twenty");   
        valueWordMap.put(30, "Thirty");   
        valueWordMap.put(40, "Forty");   
        valueWordMap.put(50, "Fifty");   
        valueWordMap.put(60, "Sixty");   
        valueWordMap.put(70, "Seventy");   
       
        valueWordMap.put(80, "Eighty");   
        valueWordMap.put(90, "Ninety");   
        valueWordMap.put(0, "");   
       
       
    }

    private static Integer getBaseNo(double d) {
       
        return (int) Math.pow(10, d-1);
    }

}