Sunday, May 18, 2014

AXIS 2 - Client and Password Call Back Handler - For a secured (using Rampart) webservice

Password Call Back Handler - This class is invoked by container when the webservice receives a secured  request.

package crishantha.rampart;




public class PWCBHandler implements CallbackHandler {

public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
System.out.println("handle->(Callback[]:"+ callbacks);
for (int i = 0; i < callbacks.length; i++) {
System.out.println("(Callback["+i+"]:"+ callbacks[i]);
//When the server side need to authenticate the user
WSPasswordCallback pwcb = (WSPasswordCallback)callbacks[i];


if(pwcb.getIdentifier().equals("apache") /*&& pwcb.getPassword().equals("password")*/) {
//If authentication successful, simply return
pwcb.setPassword("password"); // this value should be same as password supplied in SOAP Envelop.
//See the client program below for password
System.out.println("user authenticated->"+pwcb.getIdentifier());

} else {
throw new UnsupportedCallbackException(callbacks[i], "check failed");

Tag in services.xml ( need to be embed in services.xml for integrating Password Call Back Handler.

Client Program to call secured webservice

package ramp.client;

import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;

public class Client {
public static void main(String[] args)throws Exception {

System.setProperty("", "D:\\apache-tomcat-7.0.53\\bin\\sslkey\\sslkey.jks");
System.setProperty("", "password");

ConfigurationContext ctx = ConfigurationContextFactory.createConfigurationContextFromFileSystem("D:\\AXIS2_DUMP\\axis2-1.6.2\\repository", null);

TemperatureConversionServiceStub stub =  new TemperatureConversionServiceStub(ctx, "https://localhost:8443/ram/services/TemperatureConversionService");

ServiceClient sc = stub._getServiceClient();
Options options = sc.getOptions();


TemperatureConversionServiceStub.Celcius2Farenhit celc = new TemperatureConversionServiceStub.Celcius2Farenhit();
TemperatureConversionServiceStub.Celcius2FarenhitResponse cfr = stub.celcius2Farenhit(celc);
float f = cfr.get_return();
System.out.println("5. result->"+f);



SOAP Envelop sent by client program:

<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="">
<wsu:Timestamp wsu:Id="TS-1">
<wsse:UsernameToken wsu:Id="UsernameToken-2">
<ns1:celcius2farenhit xmlns:ns1="">

Saturday, May 17, 2014

AXIS 2 - SOAP Webservice - Adding Security layer to webservice using Rampart

Tools and Libraries used 

  1. apache-tomcat-7.0.53
  2. axis2-1.6.2
  3. rampart-1.6.2
  4. jdk 1.6
Exploring ram.war - The war file name is ram.war. The directory structure of the war file is below.

    │   ├───com
    │   │   └───polaris
    │   │       └───iph
    │   │           └───ws
    │   └───crishantha
    │       └───rampart

Below folders contain classes for webservice.
- classes/ 
- classes/crishantha.rampart

Integrating rampart with Axis 2 webservice
WEB-INF/conf - contains axis2.xml
WEB-INF/lib - contains all jars from  Axis2_HOME/lib/ and RAMPART_HOME/lib directory. 

Very important Note 
- The version of Axis2 and Rampart should be same. I faced issues because previously I was using axis2-1.6.2 and rampart-1.3.2. Then I changed the version of rampart to rampart-1.6.2 and it worked. This is very important point.
- The axis2 libs should not be mixed with various versions of other libs of Rampart and other extensions. It creates compatibility issues.

WEB-INF/modules - copy rahas-1.6.2.mar and rampart-1.6.2.mar files from  rampart-1.6.2\modules folder  in  WEB-INF/modules folder.

Declare webservice and engaging Rampart 

Adding Webservice in WAR file  and engaging Rampart with Axis2. Follow this link to see the META-INF/services/TemperatureConversionService/META-INF/services.xml.

Making server ready for HTTPS
Creating SSL Key to make tomcat server HTTPS /SSL Enabled. Execute below command from Tomcat_home\bin folder
keytool -genkey -alias tomcat -keyalg RSA -keystore  c:\sslkey\sslkey.jks

c:\sslkey\sslkey.jks will be created with the key. This key will be used to enable SSL.

Open the server.xml of tomcat from TOMCAT_HOME\conf\server.xml and enable /change/add below lines  around tags.

     <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS"
      keystorePass="password" />
Note: keystorePass="password", "password" value is entered while creating sslkey.jks using keytool (see few lines above)

Open WEB-INF/conf/axis2.xml and add below lines below tag  <transportReceiver>
<transportReceiver name="https" class="org.apache.axis2.transport.http.AxisServletListener">

<parameter name="port">8443</parameter>
Note : The port in axis2.xml and server.xml should be same, here its kept 8443.

Generating Client Code - Stub to call this service.

Save the WSDL  -TemperatureConversionService.xml
Execute below command

D:\AXIS2_DUMP\axis2-1.6.2\bin\clientcode>..\WSDL2Java.bat -uri D:\2010SANT\27_0_0\WS-POC\RAMPART\WebContent\WEB-INF\wsdl\TemperatureConversionService.xml -p ramp.client -d adb -s

NOTE: Get the jar from, before executing above command of WSDL2Java.bat. Issues will come without this jar.

Follow below link to develop Webservice Client for secured Webservice

AXIS 2 - services.xml - engaging rampart

<service name="TemperatureConversionService" targetNamespace="">

<module ref="rampart" /> <!-- Engaging Rampart -->
This service is to get the running Axis version
<schema schemaNamespace="" />
<parameter name="ServiceClass">crishantha.rampart.TemperatureConversionService
<operation name="celcius2farenhit">
<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
<operation name="farenhit2celcius">
<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />

<!-- Rampart specific tags  - start -->
<wsp:Policy wsu:Id="UsernameTokenOverHTTPS"
<sp:HttpsToken RequireClientCertificate="false" />
<sp:Basic256 />
<sp:Lax />
<sp:IncludeTimestamp />
sp:IncludeToken="" />
<ramp:RampartConfig xmlns:ramp="">
<ramp:passwordCallbackClass>crishantha.rampart.PWCBHandler</ramp:passwordCallbackClass> <!-- crishantha.rampart.PWCBHandler is user defined class to handle user name password -->
<!-- Rampart specific tags  - End-->

Thursday, May 1, 2014

SOAP Webservice - JAX-WS


  1. Create a sample SOAP Webservice using JAX-WS
  2. Deploy in Tomcat 7.0
  3. Invoke WSDL
  4. Create Client
  5. Use Client to invoke Webservice

  1. Create a sample SOAP Webservice using JAX-WS
    1. Create a dynamic Web Project in Eclipse
    2. Create Service Endpoint Interface (SEI) HelloWorld 
    3. Create Service Inplementation Bean (SIB), HelloWorldImpl which implement SEI.
    4. Change web.xml, add entries if Servlet giving service to Webservice HelloWorldImpl 
    5. Add sun-jaxws.xml in WEB-INF folder. This file will publish and start the webservice runtime in Tomcat.
  2. Deploy in Tomcat 7.0
    1. Add a new server in Eclipse, pointing to Tomcat 7 installation directory.
    2. Add below jars in WEB-INF/lib folder
      1. gmbal-api-only.jar
      2. ha-api.jar
      3. jaxb-api.jar
      4. jaxb-impl-2.2.6.jar
      5. jaxb-impl.jar
      6. jaxws-rt.jar
      7. management-api.jar
      8. policy.jar
      9. stax-ex.jar
      10. streambuffer.jar
    3. Add the webservice project (created in 1) in server.
    4. Start the server.
  3. Invoke WSDL
    1. http://localhost:8080/SOAP_JAX/hello?wsdl
  4. Create Client
    1. Create a new java project in eclipse.
    2. Go to src directory in doc command prompt.
    3. Invoke command "wsimport -keep -verbose http://localhost:8080/SOAP_JAX/hello?wsdl"
    4. Two classes will be created in src folder. These are stubs to invoke webservice. 
    5. Write the client file using the stubs created in 4 above.
  5. Invoke main method to access webservice. (SEI)


import javax.jws.WebMethod;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

 * This class was generated by the JAX-WS RI.
 * JAX-WS RI 2.2.4-b01
 * Generated source version: 2.2
@WebService(name = "HelloWorld", targetNamespace = "http://com.soap.sanjeev/")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface HelloWorld {

     * @return
     *     returns java.lang.String
    @WebResult(partName = "return")
    public String getHelloWorldAsString();

} (SIB)


import javax.jws.WebService;

@WebService(endpointInterface = "")
public class HelloWorldImpl implements HelloWorld {
public String getHelloWorldAsString() {
// TODO Auto-generated method stub
return "hello world";

WEB-INF/sun-jaxws.xml  - will publish the webservice and start the webservice runtime

<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns=""
<endpoint name="HelloWorld" implementation=""
url-pattern="/hello" />


WEB-INF/web.xml - setup servlet and url for webservice
<?xml version="1.0" encoding="UTF-8"?>


<display-name>Archetype Created Web Application</display-name>

<url-pattern>/hello</url-pattern>  <!-- service the webservice -->



<?xml version="1.0" encoding="UTF-8"?><!-- Published by JAX-WS RI at RI's version is JAX-WS RI 2.2.8 svn-revision#13980. --><!-- Generated by JAX-WS RI at RI's version is JAX-WS RI 2.2.8 svn-revision#13980. --><definitions xmlns:wsu="" xmlns:wsp="" xmlns:wsp1_2="" xmlns:wsam="" xmlns:soap="" xmlns:tns="" xmlns:xsd="" xmlns="" targetNamespace="" name="HelloWorldImplService">
<import namespace="http://com.soap.sanjeev/" location="http://localhost:8080/SOAP_JAX/hello?wsdl=1"></import>
<binding xmlns:ns1="http://com.soap.sanjeev/" name="HelloWorldImplPortBinding" type="ns1:HelloWorld">
<soap:binding transport="" style="rpc"></soap:binding>
<operation name="getHelloWorldAsString">
<soap:operation soapAction=""></soap:operation>
<soap:body use="literal" namespace="http://com.soap.sanjeev/"></soap:body>
<soap:body use="literal" namespace="http://com.soap.sanjeev/"></soap:body>
<service name="HelloWorldImplService">
<port name="HelloWorldImplPort" binding="tns:HelloWorldImplPortBinding">
<soap:address location="http://localhost:8080/SOAP_JAX/hello"></soap:address>

</definitions>   -  Webservice Client 

package com.client.soap.jaxws.sanjeev;



public class HelloClient {
    static HelloWorldImplService service;

    public static void main(String[] args) {
        try {
            HelloClient client = new HelloClient();
        } catch(Exception e) {

    public void doTest(String[] args) {
        try {
   service = new HelloWorldImplService();        
            System.out.println("Retrieving the port from    the following service: " + service);
            HelloWorld port = service.getHelloWorldImplPort();
            System.out.println("Invoking the sayHello operation                 on the port.");

            String name;
            if (args.length > 0) {
                name = args[0];
            } else {
                name = "No Name";

            String response = port.getHelloWorldAsString();
        } catch(Exception e) {


Friday, February 8, 2013

Java 6 Basics of Generics

//Below program is self explanatory. Please go through line by line and you will know basics of Generics

package com.sanjeev.generics;

import java.util.ArrayList;
import java.util.List;

public class Dog {

public static List getDogList(){
List list = new ArrayList();
list.add("hello dog"); //allowed as simple list can add any object
checkList(list); //allowed. For backward compatibility, normal list can be sent
                // as parameter to method with generic list
return list;     //same as above. Normal list can be returned in form of Generic List

public static List getDogList1(){
List list = new ArrayList(); //Defining Generic List.
list.add(new Dog());   //Allowed only Dog object, for which the list is made generic
checkList(list);       //Allowed method param, only Generic List for Dog Object
return list;

public static List getDogList2(){
List list = new ArrayList();
list.add("not allowed"); //Not allowed. Dog Object Generic List will not accept String to be added
checkList(list); //Allowed method param, only Generic List for Dog Object
return list; //Allowed. Genric list can be returned in Normal List

public static List doMyList(){
List < Object > myList = new ArrayList< Object >(); //Generic List for Object. Same as List myList = new ArrayList();
myList.add(new Dog()); //Can be added Dog object in Generic List of Object
checkList(myList);  //Not allowed. Generic List of < Object > cannot be sent as param in List
checkList1(myList); //Generic List< Object > can be sent in method param of List< Object >
checkList2(myList); //Generic List< Object > can be sent in method param of normal List

List  myList1 = new ArrayList();
myList1.add(new Dog()); //Allowed
checkList(myList1); //Normal list can be sent as param in any Genric List e.g. List
checkList1(myList1); //Normal list can be sent as param in any Genric List e.g. List< Object >
checkList2(myList1); //Normal List can be sent as param in any Normal List

List myList2 = new ArrayList();
myList.add(new Dog()); //Valid. Dog object can be added in Generic List
myList.add(new Object());//Valid. 'Object' can be added in Generic List
checkList(myList2);   //Valid. As Generic List being sent in parameter List
checkList1(myList2); //Not allowed. List cannot be sent as param in List< Object >
checkList2(myList2); //Allowed. List can be sent as param in normal List

return null;

public static void checkList(List mylist){

public static void checkList1(List< Object > mylist){

public static void checkList2(List mylist){

Tuesday, February 5, 2013

Freedom from darkness

Difference between Stack vs Heap in Java
Here are few differences between stack and heap memory in Java:
1) Main difference between heap and stack is that stack memory is used to store local variables and function call, while heap memory is used to store objects in Java. No matter, where object is created in code e.g. as member variable, local variable or class variable,  they are always created inside heap space in Java.
2) Each Thread in Java has there own stack which can be specified using -Xss JVM parameter, similarly you can also specify heap size of Java program using JVM option -Xms and -Xmx where -Xms is starting size of heap and -Xmx is maximum size of java heap. to learn more about JVM options see my post 10 JVM option Java programmer should know.
3) If there is no memory left in stack for storing function call or local variable, JVM will throw java.lang.StackOverFlowError, while if there is no more heap space for creating object, JVM will throw java.lang.OutOfMemoryError: Java Heap Space. Read more about how to deal with java.lang.OutOfMemoryError  in my post 2 ways to solve OutOfMemoryError in Java.
4) If you are using Recursion, on which method calls itself, You can quickly fill up stack memory. Another difference between stack and heap is that size of stack memory is lot lesser than size of  heap memory in Java.
5) Variables stored in stacks are only visible to the owner Thread, while objects created in heap are visible to all thread. In other words stack memory is kind of private memory of Java Threads, while heap memory is shared among all threads.

Difference between IdentityHashMap and HashMap
Though both HashMap and IdentityHashMap implements Map interface, have fail-fast Iterator and non synchronized collections, following are some key differences between HashMap and IdentityHashMap in Java.
1) Main difference between HashMap vs IdentityHashMap is that IdentityHashMap uses equality operator "==" for comparing keys and values inside Map while HashMap uses equals method for comparing keys and values.
2) Unlike HashMap, who uses hashcode to find bucket location, IdentityHashMap also doesn't use hashCode() instead it uses System.identityHashCode(object).
3) Another key difference between IdentityHashMap and HashMap in Java is Speed. Since IdentityHashMap doesn't use equals() its comparatively faster than HashMap for object with expensive equals() and hashCode().
4) One more difference between HashMap and IdentityHashMap is Immutability of key. One of the basic requirement to safely store Objects in HashMap is keys needs to be immutable, IdentityHashMap doesn't require keys to be immutable as it is not relied on equals and hashCode.
There is also a class called IdentityHashtable which is analogous to Hashtable in Java but it’s not part of standard JDK and available in com.sun... package.

Example of IdentityHashMap in Java
Here is an example of IdentityHashMap in Java which shows key difference between HashMap and IdentityHashMap in comparing Objects.  IdentityHashMap uses equality operator for comparison i instead of equals method in Java :

import java.util.IdentityHashMap;

 * Java program to show difference between HashMap and IdentityHashMap in Java
 * @author Javin Paul
public abstract class Testing {

    public static void main(String args[]) {
        IdentityHashMap identityMap = new IdentityHashMap();
        identityMap.put("sony", "bravia");
        identityMap.put(new String("sony"), "mobile");
        //size of identityMap should be 2 here because two strings are different objects
        System.out.println("Size of IdentityHashMap: " + identityMap.size());
        System.out.println("IdentityHashMap: " + identityMap);
        identityMap.put("sony", "videogame");
         //size of identityMap still should be 2 because "sony" and "sony" is same object
        System.out.println("Size of IdentityHashMap: " + identityMap.size());
        System.out.println("IdentityHashMap: " + identityMap);

Size of IdentityHashMap: 2
IdentityHashMap: {sony=bravia, sony=mobile}
Size of IdentityHashMap: 2
IdentityHashMap: {sony=videogame, sony=mobile}

When you assign an array to a previously declared array reference, the array you're assigning must be the same dimension as the reference you're assigning it to.
When you assign one primitive(a) variable to another(b), the contents of the right-hand variable are copied and but if we change the contents of either a or b, the other variable won't be affected.
static method cannot access an instance (non-static) variable or a non-static method.
Instance variables and objects live on the heap. Local variables live on the stack.
--> The default constructor has the same access modifier as the class.
--> The default constructor has no arguments.
--> The default constructor includes a no-arg call to the super constructor.

Constructors are never inherited. They aren't methods. They can't be overridden.
transient and volatile modifiers only applies to instance variables.
In a class, Calling a constructor from a method is illegal. Constructor can only be called from another constructor.
There are no final objects, only final references. A final reference still allows you to modify the state of the object it refers to, but you can't modify the reference variable to make it refer to a different object.
Classes can have only public or default access. Class declared private will not compile.
There are no final objects, only final references. A final reference still allows you to modify the state of the object it refers to, but you can't modify the reference variable to make it refer to a different object.
declaring final a List variable as 
private final List l = new ArrayList(); 
Can I do l.add("a"); in constructor?
Correlated and NonCorrelated Subquery- 
1.In case of correlated subquery inner query depends on outer query while in case of noncorrelated query inner query or subquery doesn't depends on outer query and run by its own.
No-Correlated Query
Correlated Query
2.In case of correlated subquery, outer query executed before inner query or subquery while in case of NonCorrelated subquery inner query executes before outer query.
3.Correlated Sub-queries are slower than non correlated subquery and should be avoided in favor of sql joins.
4.Common example of correlated subquery is using exits and not exists keyword while non correlated query mostly use IN or NOT IN keywords.

Can we synchronize constructors?
HashCode Collision in HashMap: In case of hashCode collision, equals method is applied in same bucket with existing elements, if equals method return true, new value is applied on the old key value combination, if equals return false new entry is made with new key value in same bucket. Sample code below. I have created a custom object to be used as key in hashMap. Its hasCode will be the length of member variable name, i.e. tow different objects having different values but same length will be having same hashCode but their equals will return false.

import java.util.*;

public class HashTest{
public static void main(String[] args) {
Map map = new HashMap();
MyObj newOne1 = new MyObj("one");
MyObj newOne3 = new MyObj("tre1");

MyObj newOne2 = new MyObj("two");

map.put(newOne1, "one");

map.put(newOne2, "newOne");

map.put(newOne3, "tre");

System.out.println("Map is :"+map);

class MyObj{
String name = null;
public MyObj(String s){
name = s;

public int hashCode(){
System.out.println("Adding hash of -->"+name);
return name.length();//so that strings having same length but different value will return same hashCode

public boolean equals(Object o){

MyObj m = (MyObj)o;
System.out.println("equals called-->"+name+"=";

if(name.equals( true;

return false;

============Output =======================
Adding hash of -->one
Adding hash of -->two
equals called-->two=one
Adding hash of -->tre1
Adding hash of -->two
Adding hash of -->one
Adding hash of -->tre1
Map is :{MyObj@3=newOne, MyObj@3=one, MyObj@4=tre}
EJB 3.0. Choosing Between a Local or Remote Client View
The following considerations should be taken into account in determining whether a local or remote access should be used for an enterprise bean.
• The remote programming model provides location independence and flexibility with regard to the distribution of components in the deployment environment. It provides a loose coupling between the client and the bean.
• Remote calls involve pass-by-value. This copy semantics provides a layer of isolation between caller and callee, and protects against the inadvertant modification of data. The client and the bean may be programmed to assume this parameter copying.
• Remote calls are potentially expensive. They involve network latency, overhead of the client and server software stacks, argument copying, etc. Remote calls are typically programmed in a coarse-grained manner with few interactions between the client and bean.
• The objects that are passed as parameters on remote calls must be serializable.
• When the EJB 2.1 and earlier remote home and remote component interfaces are used, the narrowing of remote types requires the use of javax.rmi.PortableRemoteObject.narrow rather than Java language casts.
• Remote calls may involve error cases due to communication, resource usage on other servers, etc., which are not expected in local calls. When the EJB 2.1 and earlier remote home and remote component interfaces are used, the client has to explicitly program handlers for handling the java.rmi.RemoteException.
• Because of the overhead of the remote programming model, it is typically used for relatively coarse-grained component access.
• Local calls involve pass-by-reference. The client and the bean may be programmed to rely on pass-by-reference semantics. For example, a client may have a large document which it wants to pass on to the bean to modify, and the bean further passes on. In the local programming model the sharing of state is possible. On the other hand, when the bean wants to return a data structure to the client but the bean does not want the client to modify it, the bean explicitly copies the data structure before returning it, while in the remote programming model the bean does not copy the data structure because it assumes that the system will do the copy.
• Because local calls involve pass-by-reference, the local client and the enterprise bean providing the local client view are collocated.
• The collocation entailed by the local programming model means that the enterprise bean cannot be deployed on a node different from that of its client—thus restricting the distribution of components.
• Because the local programming model provides more lightweight access to a component, it better supports more fine-grained component access.
Taken from EJB3.0 Specs

Primitive, Serializavble, Array or Colllection of primitive or serializables and Remote Objects are ship-able across the network for EJB calls.
Object's serialized copy is shipped over network while calling a method of EJB, while in case of local method call, objects reference is copied as method parameter.
javax.ejb.RemoteException is a checked exception.
Using Thread join() method
The join() method of a Thread instance can be used to "join" the start of a thread's execution to the end of another thread's execution so that a thread will not start running until another thread has ended. If join() is called on a Thread instance, the currently running thread will block until the Thread instance has finished executing.
We can illustrate this with an example. The RunnableJob class implements Runnable. Its run() method displays the current thread's name and the time at which the run() method is executed. It then sleeps for 1 second.

public class RunnableJob implements Runnable {

public void run() {
Thread thread = Thread.currentThread();
System.out.println("RunnableJob is being run by " + thread.getName() + " at " + new Date());
try {
} catch (InterruptedException e) {


The ThreadExample class creates a RunnableJob object. It creates 4 threads named "T1", "T2", "T3", and "T4" with the RunnableJob object. It calls start() and then join() on each thread, in order. This blocks the execution of the current (main) thread from proceeding until the thread has completed. This means that the main thread will block for 1 second at each join(), since the RunnableJob sleeps for 1 second. Following this, ThreadExample creates 4 more threads, "T5", "T6", "T7", and "T8". This time, no joins are called on these threads, so the main thread will not block.

public class ThreadExample {

public static void main(String[] args) throws InterruptedException {

RunnableJob runnableJob = new RunnableJob();

Thread thread1 = new Thread(runnableJob, "T1");
Thread thread2 = new Thread(runnableJob, "T2");
Thread thread3 = new Thread(runnableJob, "T3");
Thread thread4 = new Thread(runnableJob, "T4");


Thread thread5 = new Thread(runnableJob, "T5");
Thread thread6 = new Thread(runnableJob, "T6");
Thread thread7 = new Thread(runnableJob, "T7");
Thread thread8 = new Thread(runnableJob, "T8");




The console output of the execution of ThreadExample is shown here. Notice from the times displayed that we indeed see that T1, T2, T3, and T4 are all separated by 1 second delays. Also, notice that there are no delays for T5, T6, T7, and T8. Also, notice that T7 executes RunnableJob's run() method before T6. This occurred since there is no guarantee as to the order that T5, T6, T7, and T8 will execute the job code.

RunnableJob is being run by T1 at Wed Nov 28 19:38:39 IST 2012
RunnableJob is being run by T2 at Wed Nov 28 19:38:40 IST 2012
RunnableJob is being run by T3 at Wed Nov 28 19:38:41 IST 2012
RunnableJob is being run by T4 at Wed Nov 28 19:38:42 IST 2012
RunnableJob is being run by T5 at Wed Nov 28 19:38:43 IST 2012
Hello World!-->main
RunnableJob is being run by T6 at Wed Nov 28 19:38:43 IST 2012
RunnableJob is being run by T7 at Wed Nov 28 19:38:43 IST 2012
RunnableJob is being run by T8 at Wed Nov 28 19:38:43 IST 2012

Use list.size() for browsing an ArrayList instead of using list.iterator(). Treating ArrayList like an array gives better performance than treating it as LinkedList.