Mar 31, 2011

Web Application - Automatically Show Login Page After Session Timeout


Show Login Page After Session Timeout

One can define the session timeout time in the web.xml of a web application and can also set it programmatically by using the Session API.

The server automatically takes care of the session invalidation once the timeout has occurred with user don’t doing any activity.

But to make an application more user friendly, one should prompt user about the session being going to expire and proper message once the session has expired. Some applications will prefer to redirect the user to login page once the session has timed out.

All these features of session timeout detection are not supported by J2EE API’s. One needs to use JavaScript to show warning messages and redirect users.

There are many ways by using which the session timeout can be made more graceful. The two most used approaches are to use the timer functions in JavaScript or to use cookies.

With timer functions, an initial timer equal to the session timeout is set and the JavaScript function decrements the seconds and shows warning and directs user at appropriate time.

With cookies, two cookies with expiration time of warning time and session timeout time are created and a JavaScript function constantly polls for the existence of the cookies. If the cookies are not found, the corresponding actions are performed.
The sample code for both the approaches is shown below. The code is for showing warning messages only. You can create similar functions for handling the session timeout scenario. Also, please note that the code shown below is not of production quality is intended to give you the start only.

function alertUser(){
    var a_p = "";
    var d = new Date();
    var curr_hour = d.getHours();
    if (curr_hour < 12) {
        a_p = "AM";
    }
    else {
        a_p = "PM";
    }

    if (curr_hour == 0) {
        curr_hour = 12;
    }

    if (curr_hour > 12) {
        curr_hour = curr_hour - 12;
    }

    var curr_min = d.getMinutes();

    curr_min = curr_min + "";

    if (curr_min.length == 1) {
        curr_min = "0" + curr_min;
    }

    var curT=curr_hour+':'+curr_min+' '+a_p;
    document.getElementById('sessionExpirySpace').style.display='block';
    alert(You have been inactive and have not saved your work for last 10    Minutes.\n Please save your work in next 5 minutes to avoid  any Data Loss due to  Session timeout.');
}


Similarly for cookies based approach, the code should look something like:

function createCookie(name,value) {
    argv=arguments;
    argc=arguments.length;
    var today = new Date(); 
    today.setTime( today.getTime() );
    var expires=argv[2];
    expires = expires * 1000 * 60;
    var expires_date = new Date( today.getTime() + (expires) ); 
    path=(argc>3) ? argv[3] : null;
    domain=(argc>4) ? argv[4] : null;
    secure=(argc>5) ? argv[5] : false;
    document.cookie = name + "=" +escape( value ) + ( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) + ';path=/;';
    checkCookie('MyAPP','Test');
}
function checkCookie(name,value) {
    var today = new Date(); 
    var curr_hour = today.getHours();
    var curr_min = today.getMinutes();
    if (curr_min < 9) 
        curr_min = '0' + curr_min;

    var n=name;
    var i = document.cookie.indexOf(name);
    if(i==-1)
       alert('Dear User,Your session has been inactive and you have not saved your  work for the last 25 Minutes.\nPlease save your work within next 5 minutes.\n \t\t\t\t' +  ' (Message at'+ ' ' + curr_hour + ':' + curr_min + ' Hrs)');
    else
        setTimeout("checkCookie('MyAPP','Test')",10000);
}


There are other things to keep in mind like:
1) What if user opens a new tab and opens the website
2) What if the user manually logouts

Mar 29, 2011

Get Rid of http://x.action URL

Change Struts URL extension suffix .do .action

If you notice, many web applications deployed over the web have .do or .action at the end of URL’s. One can deliberately use these kinds of url’s.

But usually it is the default behavior of the framework/tool being used then a deliberate attempt by the developer.

Struts based web applications are the widest of them to have .do or .action suffixes with URL’s.

That is because of the numerous tutorials and books have adopted .do as a convention for Struts 1 based applications. The same applied to Struts 2. The good news is that one can easily change or get rid of extension suffixes in Struts 1 and Struts2. A question then arises as to how come the suffixed come into the URL’s.

Struts 1

If we look at a form being written using Struts 1 tag libraries, it doesn’t have any .do or .action. Here is a sample form in a JSP page of a Struts based application.


        
        
    

As we can see that we are using the form tag of the struts-html tag library. So let us dig more into that tag by having a look at the struts-taglib.jar. Inside this library, look for org.apache.struts.taglib.html.FormTag.java

In the FormTag.java we can see the code for the attribute action:
After analyzing the code for FormTag.java, the URL pattern being used for mapping ActionServlet, is being used as the URL suffix by the custom tags.
In the web.xml we generally have something like this:


        actionServlet
        *.do
    

TO make all the URL to have suffix of .who instead of .do, change the mapping to:


        actionServlet
        *.who
    

Struts 2

But if we look at the web.xml for struts 2 based application, we have


        struts2D
        org.apache.struts2.dispatcher.FilterDispatcher
    
    
        struts2D
        /*
    

So from where .action does come from?
In case of Struts 2, the extension suffix comes from the property struts.action.extension.

The value for this property can be changed to any suitable value by setting this property in the struts.xml
An example for changing the URL's in case of Struts 2 to .do is given below:


 
      
 
     
       
         login.jsp
       
     
 
   


With the above structure in the struts.xml, all the URL's will have .do as the extension suffix. Similarly, to get rid of the extension suffix at all, use the following xml code in struts.xml


 
      
 
     
       
          login.jsp
       
     
 
   

Hope this tutorial will help people in customizing their applications while using the Struts framework.

15 Must Know Java Interview Questions After 2 Years of Experience

Interview Questions that every developer should have the answer

Enterprise Java Application development is growing every day and new features being introduced but the the beginners have always start from the basics. The questions listed below are what in general a Java developer should be able to answer after 2 years of experience. (Assuming no prior exposure to Java)


UPDATE: The answers can be found at http://bateru.com/news/2011/03/484/

Core Java
1) What is the purpose of serialization?
2) What is the difference between JDK and JRE?
3) What is the difference between equals and ==?
4) When will you use Comparator and Comparable interfaces?
5) What is the wait/notify mechanism?
6) What is the difference between checked and unchecked exceptions?
7) What is the difference between final, finally and finalize?
JEE
8) What is the difference between web server and app server?
9) Explain the Struts1/Struts2/MVC application architecture?
10) What is the difference between forward and sendredirect?
General
11) How does a 3 tier application differ from a 2 tier one?
12) How does the version control process works?
13) What is the difference between JAR and WAR files?
Databases
14) What is a Left outer join?
15) What is the difference between UNION and UNION ALL?

Mar 24, 2011

How Many String Objects Are Created

How Many String Objects Are Created

Consider the code fragment shown below:

String s1="abc";
String s2="def"
System.out.println(s1 + " " + s2);


The question is how many String objects are created after the last line is compiled by Java.

To solve questions like this one can use Eclipse decompiler (JAD) to see how the Java compiler actually interpreted that third line.

1) For  any java developer it will be very easy to tell that first two lines create one object each and hence two objects in first two line.
2) The third line in the above code is interpreted by JDK 1.5 compiler as:
system.out.println((new StringBuilder(string.valueOf(s1))).append(" ").append(s2).toString());

This clearly tells us that 2 more string objects (" " and "abc def") are created in the last line.
3) Hence we can say that 4 String and 1 String Builder objects are created by that piece of code.

The complete decompiled code is listed below:
string s1 = "abc";
string s2 = "def";
system.out.println((new StringBuilder(string.valueOf(s1))).append(" ").append(s2).toString());

Mar 23, 2011

Object Oriented Exercise Solutions

Object Oriented Exercise Solutions

The following is the solution to the exercises published for object oriented concepts earlier.
The solution is provided step by step so that one can cross check the progress at each step. Proper description has also been added.

Please use this solution as a reference only.


After Step-1



package example;

public class GenericBank {}

package example;

public class HdfcBank extends GenericBank{}


package example;

public class Test {    public static void main(String[] args) {
        GenericBank hb = new HdfcBank();
        GenericBank hb1 = new GenericBank();
    }
}

=================================================================================

After Step-2


package example;

public class Test {
    public static void main(String[] args) {
        GenericBank hb = new HdfcBank();
        GenericBank hb1 = new GenericBank();
  
        hb.welcome();
        hb1.welcome();
    }
}

package example;

public class GenericBank {
    public void welcome() {
        System.out.println("Welcome");
    }
}

package example;

public class HdfcBank extends GenericBank{}


hb1 refers an instance of GenericBank class and hence the method welcome gets invoked directly. hb refers to HdfcBank which also has welcome method which was inherited by HdfcBank class from the GenericBanl class.
=================================================================================

After Step-3


  
package example;

public class Test {
    public static void main(String[] args) {
        GenericBank hb = new HdfcBank();
        GenericBank hb1 = new GenericBank();

        hb.welcome();
        hb1.welcome();
    }
}


package example;

public class GenericBank {
    public void welcome() {
        System.out.println("Welcome");
    }
}


package example;

public class HdfcBank extends GenericBank{
    public void welcome() {
        System.out.println("Welcome to HDFC Bank");
    }
}

This time we have overridden the welcome method in the sub class HdfcBank. The method that is visible to hb is welcome of GenericBank class at compile time but at runtime, the type of object being referred to by hb resulted in the welcome method of HdfcBank being invoked.

=================================================================================

After Step-4
No class in Java can extend more than one base classes

=================================================================================

After Step-5

  
package example;

public class HdfcBank extends GenericBank implements WithdrawContract,DepositContract{
    public void welcome() {
        System.out.println("Welcome to HDFC Bank");
    }
}


package example;

public class GenericBank {
    public void welcome() {
        System.out.println("Welcome");
    }
}


package example;

public class Test {

    public static void main(String[] args) {
        GenericBank hb = new HdfcBank();
        GenericBank hb1 = new GenericBank();

        hb.welcome();
        hb1.welcome();
    }
}


package example;

public class SocialBank extends GenericBank{}


package example;

public interface WithdrawContract {}


package example;

public interface DepositContract {}

=================================================================================



After Step-6

  

package example;

public class GenericBank {
    private double bankbalance;

    public void welcome() {
        System.out.println("Welcome");
    }
}


package example;

public class HdfcBank extends GenericBank implements WithdrawContract,DepositContract{
    public void welcome() {
        System.out.println("Welcome to HDFC Bank");
    }
}


package example;

public class Test {
    public static void main(String[] args) {
        GenericBank hb = new HdfcBank();
        GenericBank hb1 = new GenericBank();

        hb.welcome();
        hb1.welcome();
    }
}


package example;

public class SocialBank extends GenericBank{}

package example;

public interface WithdrawContract {}

package example;

public interface DepositContract {}
The variable bankbalance can not be exposed to the outside world for modification and hence the variable should be declared as private. ================================================================================= After Step-7,8,9
package example;

public class HdfcBank extends GenericBank implements WithdrawContract,DepositContract{
    private double bankbalance;

    public void welcome() {
        System.out.println("Welcome to HDFC Bank");
    }
}


package example;

public class GenericBank {

    private double bankbalance;

    public void welcome() {
        System.out.println("Welcome");
    }

    public void deposit(int amount) {
        bankbalance += amount;
    }

    public void withdraw (int amount) {
        bankbalance -= amount;
    }

    public void checkbalance () {
        System.out.println(bankbalance);
    }
}


package example;

public class Test {

    public static void main(String[] args) {
         GenericBank hb = new HdfcBank();
        GenericBank hb1 = new GenericBank();

        hb.welcome();
        hb1.welcome();

        hb.deposit(1000);
        hb.withdraw(500);
        hb.checkbalance();
    }
}


package example;

public interface WithdrawContract {}


package example;
public interface DepositContract {}

=================================================================================

After Step-10

  
package example;

public class HdfcBank extends GenericBank implements WithdrawContract,DepositContract{

    private double bankbalance;

    public void welcome() {
         System.out.println("Welcome to HDFC Bank");
    }
}


package example;

public class GenericBank {

    private double bankbalance;

    public void welcome() {
         System.out.println("Welcome");
    }

    public void deposit(int amount) {
         bankbalance += amount;
    }

    public void withdraw (int amount) {
        bankbalance -= amount;
    }

    public void checkbalance () {
        System.out.println(bankbalance);
    }

    public void deposit (double amount) {
        bankbalance += amount;
    }

    public void withdraw (double amount) {
         bankbalance -= amount;
    }

     public void checkbalance (double amount) {
         System.out.println(bankbalance);
    }

}


package example;

public class Test {
    public static void main(String[] args) {
        GenericBank hb = new HdfcBank();
        GenericBank hb1 = new GenericBank();

        hb.welcome();
        hb1.welcome();

        hb.deposit(1000);
        hb.withdraw(500);
        hb.checkbalance();

        hb.deposit(100.12);
        hb.withdraw(50.50);
        hb.checkbalance();
    }
}


package example;

public interface WithdrawContract {}


package example;

public interface DepositContract {}
=================================================================================

After Step-11

The data inside any application should be protected from the outside world and the access specifiers provide the appropriate visibility to the data as seen from other classes.
=================================================================================

After Step-12

The entities are simulated using classes in Java. We can write all of the code in a single class but Object oriented programming allows us to simulate the real world and hence provide a better understanding of the problem.

Mar 18, 2011

Bad Enterprise Java Application Design

What all is Possible in JSP Bad Design

Recently, I came across a web based application with Struts, EJB and Stored Procedures. The project was outsourced from South Africa and client was a insurance department of Govt. of South Africa.

A part of the code was already written as the project had been running since 2001. At that time, Stored Procedures were written to write the business logic and MVC 1 model was used in the web application. This meant that the JSP's had all the processing and UI code written in scriptlets, declarations etc. I had a hard time to understand the existing code and then make changes as per the latest enhancements requested by the customer.

A single JSP page had CSS, JavaScript, HTML and of course Java code. Each JSP was running to 1500-2000 lines. Other clleagues who had visited client side in South Africa told me that writing such a code is a great achievement for developers in SA. The onsite co-ordinator told us that they like the work to be outsourced once it had been written by developers sitting at the client side.

Even worse, they were wanting to write the UML diagrams using Rational Rose for the code which is already running in the production environment. This was required to be shown during the internal/external project audits.

In the meantime, they also decided to introduce EJB's and I don't know why..The business logic was already written in Stored Procedures. The developer at that time (around July 2007) used session EJB's to call the stored procedures. The introduction of EJB's resulted in the use of JBOSS application server.

First I was happy that I have learnt how bad design works. I was also getting the opportunity to understand the application and write UML diagrams for the same but I was so frustrated with the application that I considered changing my employer at that time.

Mar 10, 2011

Why Care About Exception Chaining in Java

Why Should You Care About Chained Exceptions

Note: If you don't have the time and energy to read the details, execute the two programs in the post and learn what exception chaining is all about.

The exception chaining terminology may be new to a few Java developers of Enterprise Java Applications but we all have seen chained exceptions at some point of time. 

I have seen many sources on the internet before posting this article and no article brings out the main point to remember about exception chaining. 
The most important thing to remember about Exception chaining is that we need to use the constructor of the exception classes which accepts a parameter of type Throwable so that it can keep a reference to the exception which was the cause of this exception.

Definition of Exception Chaining:
The definition of chained exceptions is that when the occurrence of one exception raises another exception then the stack trace of second exception should also include the root exception in the application logs.

Few points to remember about Chained Exceptions are:
1) Java does magic in order to support Exception Chaining but it is also the responsibility of the developer to have proper exception chaining mechanism in place in any Java based application. The application needs to be coded so as to support exception chaining.

2) If the developer doesn't take any action to have chained exception in his program, the root exceptions are lost. No exception chaining code, no chained exceptions seen.

3) Chained exceptions are different from the stack trace that we see when an exception occurs which prints the method names which we were invoked before the exception was thrown (in other words, the method stack trace)

4) Exception Chaining is internally supported by Java by storing a reference to the root exception has a member field cause which was added in JDK 1.4 and looks like:
private Throwable cause = this; (inside Throwable.java class)

5) The methods which are provided by Java in order to only support exception chaining are
Throwable getCause()
Throwable initCause(Throwable)
Throwable(String, Throwable)
Throwable(Throwable)
Throwable printStackTrace(); 
The basic and important point to keep in mind about chained exception is that we need to write a custom exception
class which can accept an argument of type Throwable in is constructor and can invoke the super class's constructor
with the parameters passed to its constructor. This will become more clear with two examples:

Without any Exception Chaining mechanism in place:

package com.example;

class MyException extends Exception {  //Custom Exception class
    public MyException (String msg) {
        super(msg);
    } 
}

public class Test {
 
    static int a[] = {1,2,3};

    public static void main(String[] args) {

        try {
            System.out.println(a[4]);   //Deliberate ArrayIndexOutOfBoundsException
 } catch (ArrayIndexOutOfBoundsException ae) {
     try {
         throw new MyException("Exception Occured");  //throw custom exception
     } catch (MyException me) {
         me.printStackTrace();
     }
        }
    }
}

Output:
com.example.MyException: Exception Occured
 at com.example.Test.main(Test.java:20)
With Exception Chaining mechanism in place:

package com.example;

class MyException extends Exception {  //Custom Exception class
    public MyException (String msg, Throwable ex) {
        super(msg, ex);
    } 
}

public class Test {

    static int a[] = {1,2,3};

    public static void main(String[] args) {

        try {
            System.out.println(a[4]);   //Deliberate ArrayIndexOutOfBoundsException
        } catch (ArrayIndexOutOfBoundsException ae) {
            try {
                throw new MyException("Exception Occured",ae);  //throw custom exception
            } catch (MyException me) {
                me.printStackTrace();
            }
        }
    }
}

Output:

com.example.MyException: Exception Occured
 at com.example.Test.main(Test.java:19)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 4
 at com.example.Test.main(Test.java:16)

Please note that the use of custom exception in above examples is for demonstration only. It could be any JDK exception class like IllegalArgumentException, ClassNotFoundException or IllegalStateException.

Hope you enjoyed this blog post.

Mar 9, 2011

Java Custom Exception Classes


Why use Custom Exception Classes in Java

Quite frequently, we read in Java books that we can inherit from Exception/RuntimeExcetion classes or implement the Throwable interface in order to create application specific exception classes. 

There are scenarios where the exception hierarchy present in the Java JDK is not sufficient to capture the essence of the erroneous condition in an application. These custom exceptions can be thrown using the throw keyword whenever the corresponding condition occurs.


The exception handler catch blocks can be present in the same method or can be present in the caller code.
But most of the applications don't not have custom exceptions unless a lot of thinking has been done over the design of the application. This is probably because of the time constraints in a project or the lack of knowledge.


Anyways, here is an example from my experience where we used custom exceptions. The application had a JSP page where we will forward the user to in case of any irrecoverable exception. The need of custom exception was to show more meaningful message to the user. A user does not know what is a NullPointerException or ArrayIndexOutofBoundsException. What he understands is any fallacy in the application with regard to the functional aspects of the application.


We have a sample custom exception scenario with various classes in this example being:


ValueTooLarge : Exception to be thrown when the result of a business calculation is not permissible.
BaseException : Provides logging of exceptions so that not every class has to log the exception
CoolingEfficiencyCalculator : Calculates the efficiency of a fridge and raises the exception if the value of efficiency is greater than 999
RequestProcessor: Receives the request from the user with all the values of the form and calls the calculate method and handles the ValueTooLarge exception to display the message corresponding to the code Error123 as read from the config file.


public class ValueTooLarge extends BaseException {

      public ValueTooLarge() {
           super(); 
      }

      public ValueTooLarge(String msg) {
           super(msg) 
      }
}
==================================================
public class BaseException extends Exception{
  
      public BaseException() {
        super();

        // Log this exception in the
error log
       
LogUtil.writeException(LogUtil.OTHER_ERROR, this);
    }

    public BaseException(String msg) {
        super(msg);

        // Log this exception in the
error log
        LogUtil.writeException(LogUtil.OTHER_ERROR,
this);
    }

} 
===================================================
//This class is the point where value too large exception will be raised
public class CoolingEfficiencyCalculator {

    public  int calculate( int weight, int temperature) throws ValueTooLarge{
        int efficiency = (weight/temperature)*100;

        throw new ValueTooLarge();
    }
} 
==================================================
public class RequestProcessor {

     public void processRequest {
    
        CoolingEfficiencyCalculator
coolingEfficiencyCalculator = new CoolingEfficiencyCalculator();
        try{
             
coolingEfficiencyCalculator.calculate(Record serviceRecord);
        } catch (ValueTooLarge vtle) {
               
addException("Error123"); 
        }
    }
}

So next time someone asks you about custom exception just use this example and you are done :)

Mar 8, 2011

I am Thinking of Changing Employer

I have been working with YYY (India) from the start of my carrier in July 2006 till Feb 2010. 

I joined ZZZ (India) in March 2010 and for the last 5-6 months, I have not got any good assignments.

Moreover, I want to be relocate to some other city.

Do you think its good to have something like this in my CV/profile:


YYY             July2006-----Feb2010  (3.6 years)
ZZZ              Feb2010------March2011 (1 year)

or should I wait for 4-5 months more to look it like:

YYY             July2006-----Feb2010  (3.6 years)
ZZZ              Feb2010------July2011 (1.5 years)

Do leave your opinions....

Mar 5, 2011

Throwing Exception From Finally in Java

Ways to Handle Exception in Finally Block in Java

The finally block is used to execute any clean up code before returning the control back to the caller. And finally block gets executed irrespective of whether any exception occurs or not.

But what if the clean up code throws another exception. Probably the database connection or file handler we were trying to close was already null. In that case, the originial exception is lost. Let us see some sample code:



public class Test{

    public static void main(String[] args) {
        try{
            throw new ArrayIndexOutOfBoundsException();
        } finally {
            throw new NullPointerException();
        }
    }
}

Output:

Exception in thread "main" java.lang.NullPointerException
  at Test.main(Test.java:7)

So in the example code above, we don't have any information about the ArrayIndexOutOfBoundsException which was the root cause to reported. Moreover, the program ended abruptly because of the exception being thrown in the finally block. By adding a catch block we can log the exception.

public class Test{

    public static void main(String[] args) {
        try{
            throw new ArrayIndexOutOfBoundsException();
        } catch (ArrayIndexOutOfBoundsException aie) {
            aie.printStackTrace();
        }finally {
            throw new NullPointerException();
        }
    }
}

Output:

java.lang.ArrayIndexOutOfBoundsException
  at Test.main(Test.java:5)
Exception in thread "main" java.lang.NullPointerException
  at Test.main(Test.java:9)
A common solution is to use try/catch inside the finally block also so that the program doesn't abruptly terminate because of the exception being raised in the finally block. The sample code will look like:
public class Test{

    public static void main(String[] args) {
        try{
            throw new ArrayIndexOutOfBoundsException();
        } catch (ArrayIndexOutOfBoundsException aie) {
            aie.printStackTrace();
        }finally {
            try {
                System.out.println("Some cleanup");
                throw new NullPointerException();
            } catch (Exception e) {
                System.out.println("Exception in finally");
            }
            
        }
    }
}

Output:
java.lang.ArrayIndexOutOfBoundsException
Some cleanup
    at Test.main(Test.java:5)
Exception in finally
You may add the clean up code in a separate method and call that method from the finally block. This may be helpful when running same clean up code from multiple finally blocks in an application.

As per Core Java Fundamentals -Volume 1, whatever be the approach to handle the exceptions raised from finally block, it is not a good thing to throw any exception to the caller. In other words, the clean up methods provided by the various classes like InputStream or Connection should not cause any exception to be passed on to the caller.

Mar 3, 2011

About Daemon Threads in Java

About Daemon Threads in Java


There can be two types of threads in Java viz User Thread and Daemon Thread. All the threads created by a user are user threads. A thread becomes Daemon thread when the user says so. User threads are meant for the program code.

On the other hand Daemon threads are service provider threads. They should not be used to run your program code but some system code. The run() method for a daemon thread is typically an infinite loop that waits for a service request. These threads run in parallel to your code but survive on the mercy of the JVM. When JVM finds no user threads it stops and all daemon threads are terminated instantly. Thus one should never rely on daemon code to perform any program code.

For better understanding consider a well known example of Daemon thread : Java garbage collector. The Garbage collector runs as a low priority daemon thread to reclaim any unused memory. When all user threads terminates, JVM may stop and garbage collector also terminates instantly. 

Daemon threads are typically used to perform services for your application/applet. The core difference between user threads and daemon threads is that the JVM will only shut down a program when all user threads have terminated. Daemon threads are terminated by the JVM when there are no longer any user threads running, including the main thread of execution. Use daemons as the minions they are. This makes sense because when only daemon threads remain, there is no other thread for which a daemon thread can provide a service.
To specify that a thread is a daemon thread, call the setDaemon() method with the argument true. To determine if a thread is a daemon thread, use the accessor method isDaemon().


Annotations - Behind the Scenes

Annotations -  Behind the Scenes
We see annotations being used in almost all applications being developed. These Java applications could be that sample program to show a concept or an enterprise Java application. The flexibility and maintainability provided by the use of annotations is great. One big advantage of having annotations is that it can reduce the amount of code and configuration/properties/xml files required in any Java enterprise application.

Every annotation in JDK 1.5 onwards has a corresponding class. For example, the @override annotation which tells that a method is an overridden version of the method inherited from the super class, has a corresponding Override.class.  

Similarly we have the Deprecated.class for the @deprecated annotation. We can see the contents of the corresponding source file to check what all attributes/parameters are being supported by the @override annotation. The Override.class has the following contents:

/  (version 1.5 : 49.0, no super bit)
@java.lang.annotation.Target(value={java.lang.annotation.ElementType.METHOD})
@java.lang.annotation.Retention(value=java.lang.annotation.RetentionPolicy.SOURCE)
public abstract @interface java.lang.Override extends java.lang.annotation.Annotation {

}

This suggests us that the annotation @Override can have two attributes viz Target and Retention. The value accepted by Target attribute is of type METHOD and of Retention is SOURCE.

The decompiled code of the Override.class is:

package java.lang;
import java.lang.annotation.Annotation;
// Referenced classes of package java.lang:
//            Object

    public interface Override extends Annotation {
    } 

This is applicable to all annotations that you may come across in various frameworks/tools. All annotations in Spring, Hibernate, JPA are backed by corresponding classes. If you decompile the code which makes use of annotations, you will not see any reference to annotation classes as the dependency with annotations is resolved at compile time only. Thus annotations are Meta-data for the compiler which it makes use of to perform common functions for developers thus easing the life of a Java application developer.