Friday, January 30, 2015

Java API override Mechanism with java Endorsed Standards

Java API override Mechanism with java Endorsed Standards

This Topic is about a very rarely used feature of java to override some of the java API with newer version of those  APIs. I java world it is called ‘Java Endorsed Standards Override Mechanism’.
I got to know about this when I got stuck in one of the scenario where I had some java version problem.

I was using Apache CXF 3.x runtime for Webservice. By default, it generates Jaxb 2.2 api implementation classes, which is according to java 7 standards. But, I was using java 6.x for generating client stub from my ‘wsdl’. While doing so I was getting some exceptions:
For Example:

Caused by: java.lang.NoSuchMethodException:    
           javax.xml.bind.annotation.XmlElementRef.required()
                                      at java.lang.Class.getDeclaredMethod(Class.java:1937)
                            at com.sun.codemodel.TypedAnnotationWriter.invoke(TypedAnnotationWriter.java:112)….

As you can see above exception shows that it is unable to find required method in javax.xml.bind.annotation.XmlElementRef class, because there is a change in java 6 to java 7 version. Java 7 has this required method in javax.xml.bind.annotation.XmlElementRef, but not in Java 6, which I was using.

Now, What to do in this scenario. After doing little research I got to know about ‘Java Endorsed Standards Override Mechanism’.  This provides a means whereby later versions of classes and interfaces that implement Endorsed Standards or Standalone Technologies may be incorporated into the Java Platform.

All you need to do is deploy updated packages, by placing the packages in jar and pointing those jar using system property java.endorsed.dirs.

Eg: 
-Djava.endorsed.dirs=/some/path/directory containing packaged jars.

Or,

Put those packaged jars in jdk’s jre/lib/endorsed folder

One you are done with this, your updated API will come into effect.
This overriding mechanism can be done only with Endorsed Standards APIs and Standalone Technologies  till now. More details of these can be found at Java 7 endorsed-standard-apis.

Let us understand this feature by an example

You can access code of this example at my git location:  Test Java Overriding Mechanism.
In this example I just wanted to show how I have written some code which is supported by java 7 which has JAXB 2.2 API  but I am trying to compile and run using Java 6, which has JAXB 2.1 .

For this I create a JAXB Application , and for this created 3 model classes.

ContactInfo.java
public abstract class ContactInfo {

}

Address.java

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="address")
public class Address extends ContactInfo {

    @XmlElement(required=false)
    private String street;

    public void setStreet(String street) {
        this.street = street;
    }

}

PhoneNumber.java
@XmlRootElement(name="phoneNumber")
public class PhoneNumber extends ContactInfo {
}

Customer.java
@XmlRootElement
public class Customer {

   @XmlElementRefs({
                @XmlElementRef(name="address",type=Address.class,required=true),
                @XmlElementRef(name="phoneNumber",type=PhoneNumber.class,required=true)
                })
    private ContactInfo contactInfo;

    public void setContactInfo(ContactInfo contactInfo) {
        this.contactInfo = contactInfo;
    }

}
Here, You can see I have used ‘required’ attribute in @XmlElementRef(name="address",type=Address.class,required=true), which is there since Java7 with JAXB 2.1. So when you try to compile it using Java 6 it would give compilation error, because it comes with JAXB 2.1.

cannot find symbol
                symbol  : method required()
                location: @interface javax.xml.bind.annotation.XmlElementRef
                @XmlElementRef(name="phoneNumber",type=PhoneNumber.class,required=true)
                                                                                                                               ^
Approach using ‘Java Endorsed Standards Override Mechanism’, we can provide JAXB 2.2 jars in jdk’s jre/lib/endorsed folder or -Djava.endorsed.dirs=/some/path/directory containing JAXB 2.1 jars. It should compile and run successfully.
-----------------------------------------------------------------------------------------------------------------------
import java.io.File;
import java.io.IOException;

import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.SchemaOutputResolver;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import com.test.model.Address;
import com.test.model.Customer;
import com.test.model.PhoneNumber;

public class TestEndorsed {

    public static void main(String[] args) throws Exception {
        Customer customer = new Customer();
        Address address = new Address();
        address.setStreet("1 A Street");
        customer.setContactInfo(address);
        JAXBContext jc = JAXBContext.newInstance(Customer.class, Address.class, PhoneNumber.class);
       jc.generateSchema(new SchemaOutputResolver() {
                               
                                @Override
                                public Result createOutput(String namespaceUri, String suggestedFileName)
                                                                throws IOException {
                                                suggestedFileName = "schema.xsd";
                                                File file = new File(suggestedFileName);
                        StreamResult result = new StreamResult(file);
                        result.setSystemId(file.toURI().toURL().toString());
                        return result;
                                }
                });
        Marshaller marshaller = jc.createMarshaller();
        SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
       System.out.println(marshaller.getSchema());
        Schema schema = sf.newSchema(new File("schema.xsd"));
        marshaller.setSchema(schema);
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(customer, System.out);
    }

}

This is the Main program which you can test for marshalling and generating schema out of customer object.

You can also use it in build scripts like ANT and Maven. For Example,

<target name="compile">
  <mkdir dir="build/classes"/>
   <javac srcdir="src" destdir="build/classes">
   <compilerarg value="
-Djava.endorsed.dirs=C:\software\jdk1.6.0_21\jdk1.6.0_21\jre\lib\endorsed1"/>
        </javac>
    </target>

I Hope this helps many who are struggling with API compatibility and its usage.

Suggestions and Comments are most welcome.

CHEERS!!!

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);
    }

}

Saturday, August 28, 2010

Greatest Personalities

The World has given unlimited number of great people,who have played significant roles for the welfare of mankind.Do we really know them? I must say,do we really realise that they have done something for us? I am not sure. Today life is so fast , we don't have time to think about these valuable 'GEMS'. In this edition of my blog i have thought of writing something about them,just tried to focus on them.Do find some time from your busy life to know about them. Cheers........


Albert Einstein


This legend is Albert Einstein. Somehow-somewhere,we all have heard this name.One of the most famous personalities. The legend has always been my inspiration.That's why i have choosen him as my first personality.My favourite.

Exactly,I really don't remember when i heard this name,may be in third standard,in General Knowledge books i guess.Later in higher classes I read about him.As time passed,I realised what he has given us.

He was born on 14th march 1879, at Ulm, in Württemberg, Germany.
During the journey of his life, he emigrated to America to take the position of Professor of Theoretical Physics at Princeton.You might be thinking why he moved there.Its because of political reasons.It happened during the period of IInd world war.That period was very crucial for him. He became a United States citizen in 1940 and retired from his post in 1945.