Monday, October 10, 2011

increasing the JBoss server start-up time in eclipse


For increasing the JBoss server start-up  time in eclipse:-

1.Click the Servers tab. Its located at the lower area of Eclipse workarea. Just beside Properties tab or near the Console tab.




2.Then double click the server(don't right click) which you are trying to start. It will open a dialog box. Expand the “Timeouts”. There you can find the option to increase the server start time. The default value is 50 seconds you can change it to an appropriate value(it is highlighted by green rectangle in image


I hope this solve your server time out issue.

:)

Monday, September 19, 2011

How to create Singleton design pattern using Java


Singleton pattern is a design solution where an application wants to have one and only one instance of any class, in all possible scenarios without any exceptional condition

Before seeing  Some of the techniques which are commonly used to make a class Singleton, first let's familiarize with some common steps that each of these techniques uses:

   1.Make the constructor private-

 Other classes can instantiate any object of the class by using the new keyword. Therefore default constructor of the class needs to be made private.The new keyword can then be used from within the class only.

public class SingletonDemo{
 private SingletonDemo() {}
}

   2. One method to get the instance- Though we've made the constructor private so that other classes can’t instantiate but we should have one method to get the only one instance.
public class SingletonDemo
{
    private static SingletonDemo instance;
 
    private SingletonDemo() {}
 
    public static SingletonDemo getInstance() 
    {
      if instance == null)
      {
          instance = new SingletonDemo();
      }
      return instance;
    }
}
In the above example, we have the method getInstance() which is providing the one and only one instance of the class. First it is checking if the object is instantiated or not(by checking if it is null or not). If it is not done yet then it creates a new instance. The instance is made static because only one class level instance variable will be there. 

     3. Make it Thread safe- This can be  achieved  either by:

                    1. Making getInstance() method synchronized 

public static synchronized SingletonDemo getInstance() {
        // code goes here
    }
                       2. Using Synchronized block

    public static SingletonDemo getInstance() {
      if (instance == null) {
       synchronized (SingletonDemo .class) {
        instance = new SingletonDemo ();
       }
      }
      return instance;
     }

    this method has one drawback. Suppose there are two threads T1 and T2. Both comes to create instance and execute “instance==null”, now both threads have identified instance variable to null thus assume they must create an instance. They sequentially goes to synchronized block and create the instances. At the end, we have two instances in our application.
    To  solve this double-checked locking can be used.

    public static SingletonDemo getInstance() {
      if (instance == null) {
       synchronized (SingletonDemo .class) {
    
         // Double check
     if (instance == null) {
           instance = new SingletonDemo ();
     }
       }
    }

    Let's have a look at few commonly used techniques to Create Singleton Class

    Eager initialization

    In his approach instance of a class is created much before it is actually required.lets see its code


    public class EaggerInitialzeSingletonDemo {
       private static EaggerInitialzeSingletonDemo instance 
                                      = new EaggerInitialzeSingletonDemo();
     
       private EaggerInitialzeSingletonDemo() {}
     
       public static synchronized EaggerInitialzeSingletonDemo getInstance() {
             return instance;
        }
    }

    Lazy initialization
    In computer programming, lazy initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed. This is typically accomplished by maintaining a flag indicating whether the process has taken place.Lets see it in code


    public class SingletonDemo{
     
        private static SingletonDemo instance;
     
        /** A private Constructor prevents any other class from instantiating. */
        private SingletonDemo() {}
     
        public static synchronized SingletonDemo getInstance() {
          if instance == null){
              instance = new SingletonDemo();
          }
          return instance;
        }
    }
    Static block initialization
    We know static blocks are executed during the loading of class and even before the constructor is called. We can use this feature

    public class StaticBlockSingleton {
     private static final StaticBlockSingleton INSTANCE;
    
     static {
      try {
       INSTANCE = new StaticBlockSingleton();
      } catch (Exception e) {
       throw new RuntimeException("Error", e);
      }
     }
    
     public static StaticBlockSingleton getInstance() {
      return INSTANCE;
     }
    
     private StaticBlockSingleton() {
            }
    }
    Above code has one drawback. Suppose there are 5 static fields in class and application code needs to access only 2 or 3, for which instance creation is not required at all. So, if we use this static initialization. we will have one instance created though we require it or not.

    Bill pugh solution

    Bill pugh suggest to use static inner class.
    public class BillPughSingleton {
       private BillPughSingleton() {
       }
    
       private static class LazyHolder {
           private static final BillPughSingleton INSTANCE = new BillPughSingleton();
       }
    
       public static BillPughSingleton getInstance() {
           return LazyHolder.INSTANCE;
       }
    }
    Using Enum
    public enum EnumSingleton {
     INSTANCE;
     public void someMethod(String param) {
      // some class member
     }
    }
    We can still create instances of the class by cloning the class. So we have to override the clone() method of the Object class so that if any attempt is made to clone the class it will throw a CloneNotSupportedException.
    public class SingletonDemo{
     
        private static volatile SingletonDemo instance;
     
        /** A private Constructor prevents any other class from instantiating. */
        private SingletonDemo() {}
     
        public static synchronized SingletonDemo getInstance() {
          if (instance == null) {
               synchronized (SingletonDemo .class) {
    
         // Double check
             if (instance == null) {
               instance = new SingletonDemo ();
           }
          return instance;
        }
        public Object clone() throws CloneNotSupportedException {
            throw new CloneNotSupportedException();
        }
    }

    Still  we can create instances of the class by Serialization and de-serialization. So we need to override the readResolve() method also:
    The complete code is:

    public class SingletonDemo{
          private static volatile SingletonDemo instance;
     
    /** A private Constructor prevents any other class from instantiating. */
        private SingletonDemo() {}
     
        public static synchronized SingletonDemo getInstance() {
          if instance == null){
              instance = new SingletonDemo();
          }
          return instance;
        }
        protected Object readResolve() {
           return instance;
        }
       public Object clone() throws CloneNotSupportedException{
            throw new CloneNotSupportedException();
       }
    
    }
    FAQ's
    1. Why to use volatile with instance variable?
                  We should use “volatile” keyword with instance variable if we are using double checked locking otherwise we might see out of order write error scenario, where reference of instance is returned before actually the object is constructed i.e. JVM has only allocated the memory and constructor code is still not executed. In this case, our other thread, which refer to uninitialized object may throw null pointer exception and can even crash the whole application.
    For example: Thread A may assign a memory space for instance before it is finished constructing instance. Thread B will see that assignment and try to use it. This results in Thread B failing because it is using a partially constructed version of instance

    2.How Serialization and de- serialization can brake the code if readReolve() is not used?
                De-serialization always creates a new instance. Lets understand using an example:

    Our Singleton class without readResolve method


    public class SingletonDemo{
           private static volatile SingletonDemo instance;
           private int digit = 1;
    /** A private Constructor prevents any other class from instantiating. */ private SingletonDemo() {} public static synchronized SingletonDemo getInstance() { if instance == null){ instance = new SingletonDemo(); } return instance; }  
        public int getDigit() {
     return i;
        }
        public void setDigit(int i) {
     this.digit = i;
        }
    public Object clone() throws CloneNotSupportedException{ throw new CloneNotSupportedException(); }
    }
    Now we serialize this class and de-serialize it after making some changes

    public class SerializationTest {
         static SingletonDemo instanceOne = SingletonDemo.getInstance();
    
         public static void main(String[] args) {
     try {
        // Serialize to a file
        ObjectOutput out = new ObjectOutputStream(
                                       new FileOutputStream("demo.ser"));
        out.writeObject(instanceOne);
        out.close();
               instanceOne.setI(2);
        // Serialize to a file
        ObjectInput in = new ObjectInputStream(new FileInputStream(
         "demo.ser"));
        DemoSingleton instanceTwo = (SingletonDemo)in.readObject();
        in.close();
    
               System.out.println(instanceOne.getI());
        System.out.println(instanceTwo.getI());
    
           } catch (IOException e) {
         e.printStackTrace();
     } catch (ClassNotFoundException e) {
         e.printStackTrace();
     }
        }
    }
    
    Output:
    ===========================================================================
    2
    1
    We can See that two objects got created, thus defeating our purpose of making class singleton
    readResolve is used for replacing the object read from the stream. So this is enforcing singletons; when an object is read, replace it with the singleton instance. This ensures that nobody can create another instance by serializing and deserializing the singleton.

    3. Why we need to override the clone() Method?
               By default, the clone() method is marked as protected, but if our SingletonObject extends another class that does support cloning, it is possible to violate the design principles of the singleton. Examine the following code snippet, which clones a singleton object.

    Our Singleton class without clone method

    public class SingletonDemo{
    
          private static volatile SingletonDemo instance;
     /** A private Constructor prevents any other class from instantiating. */
    private SingletonDemo() {} public static synchronized SingletonDemo getInstance() { if instance == null){ instance = new SingletonDemo(); } return instance; }
        protected Object readResolve() {
    
           return instance;
        }
    }

    public class MyClone
    {
     public static void main(String args[])
       throws Exception
     {
       // Get a singleton
       SingletonDemo obj = SingletonDemo.getInstance0();
    
       // Let's clone the object
       SingletonDemo clone = (SingletonDemo) obj.clone();
     }
    }
    
    We can See that clone objects got created, thus defeating our purpose of making class singleton

    Tuesday, August 9, 2011

    How to: Hard reset the NOKIA N900





    Right now there is no direct way as with other Nokia mobile to hard rest Nokia N900
    But it can be done following below mentioned steps. A word of caution, before hard resting your mobile don’t forget to back up all your mobile information like contacts, messages, notes etc. and also all the data from your 32 GB mobile storage  as after hard reset all data will be lost and your mobile will start as if it is starting first time.
    I have tried the steps mentioned below on my Nokia N900 and it works fine, but there is absolutely no responsibility from my side if something goes wrong during hard reset process.  
    That’s why it is highly advice to back up your data and finish all the steps mentioned below.
    Although during my mobile’s hard reset I wasn’t able to finish all the steps myself as I downloaded wrong file ( :D happens many a times), and still no harm was made to my mobile. So just follow the steps and it will work fine J
                                                    This tutorial is written to be used from a windows PC, but with slide changes it can be used from Linux based PC also. I will try to put one more tutorial on how to Hard reset NOKIA N900 using a Linux PC but for while it’s only indented for Windows PC

    Step 1: Download flashing software
    You need to download “Maemo Flasher, it needs to be installed in computer to perform hard reset


    The page will be somewhat like this.



    From the list choose the appropriate version (In my first attempt I downloaded the wrong one and it gave me error when I used it)

    The link is shown in Green rectangle box (Win Flasher_3.11.5.exe). Install the application after downloading.

    Step 2: Image files for NOKIA N900

    The file can be found here:

    It will be something like this



    In order to download the file, you will need to provide your device's 15-digit IMEI number and accept the end-user software agreement. How to find the IMEI number is given on top of the link itself.

    There are two files  you need to download from there.
    1.    eMMC content – This is the package to erase all data held on your 32GB storage.(For PR1.3 choose the one marked Latest)
    2.    OS – This is your operating system.
    There are multiple eMMC packages available, so download the Latest. At the time of writing this post it is PR1.3and It’s called:
    RX-51_2009SE_10.2010.13-2.VANILLA_PR_EMMC_MR0_ARM.bin
    The OS is a little more difficult to figure out which one you need.
    The notes alongside the software lets you find the right package easier.
    I found the best way to check is to do the following: (On the N900)
    1.    Menu
    2.    Settings
    3.    About Product
    This will show you this image (or similar)


    Download the OS package that exactly matches your device. In my first attempt I downloaded the package for India region
    RX-51_2009SE_20.2010.36-2.004_PR_COMBINED_004_ARM.bin (India)
    Where I needed to use
    RX-51_2009SE_20.2010.36-2.003_PR_COMBINED_003_ARM.bin (Middle East and North Africa)
    Therefore just be a bit careful while downloading the exact file matching your device.

    Step 3: Copy these to files in the installed “Maemo Flasher” folder.
    If u have installed it inc:\program files\maemo\flasher-3.5”, then put these two files in this folder
    You should now have two .bin files in the directory above.

    Step 4:Updating the NOKIA N900 OS
    1.    Your battery should be as much as full as possible  to prevent any crashes which could leave your mobile dead.
    2.    Turn your Nokia N900 off.
    3.    Press and hold the U key on the keypad.
    4.    Insert the USB cable, into a USB port, NOT a USB adapter. (A USB symbol should appear on the top right of your N900 screen, and also the Nokia logo in the centre).
    5.    You can now let go of the U key.
    6.    On your PC: Navigate to the Start Menu and select Maemo>Maemo Flasher 3.5>Maemo Flasher 3.5 or just go into the folder where “Maemo flasher” is install and run the exe directly.
    7.    In the command window you should now see: C:\Program Files\maemo\flasher-3.5>
    8.    Type: flasher-3.5 -F RX-51_2009SE_20.2010.36-2.002_PR_COMBINED_002_ARM.bin –f

    The name of file might change according to region and version you downloaded. It’s a good practice to use tab for completing the name of file so u can get rid of trouble of writing name exactly
    9.    You should see something like this on your terminal
    10.   


    Your personal data, such as Contacts, Images, SMS will still be on the device.
    So if you want to remove these as well, follow the next steps.
    10. Do not disconnect or reboot the device the device. Just leave as is for now.

    Step 5: Resetting the Mass Memory
    Type in the command window:
    flasher-3.5 -F RX-51_2009SE_10.2010.13-2.VANILLA_PR_EMMC_MR0_ARM.bin -f –R
    Again the name of file might change according to region and version you downloaded.
    This image below shows the completed reset of the eMMC (32GB HDD), in the command prompt on your PC.


    This would have now removed any data you had stored there. Including Music, Photos, Contacts, SMS.
    This completes the hard reset procees of your N900. You will get the restart screen on your mobile. If it is not restarting then restart it manually and u will get configuration screen on your mobile which u get on first run

    Congratulation!!!!!!!!! You have successfully hard reset your Nokia N900


    Wednesday, August 3, 2011

    Implementation of tomcat clustering


    When  first time i tried to cluster tomcat, found it very difficult. So after going through many many posts, i was able to finally get a cluster working.
    That's when i decided to put all my efforts in a simple steps to follow guide
    These steps are written keeping windows operating system in mind. For Linux and  other OS, installation process differ slightly.


    Types of clustering


    1)-Horizontal Clustering

     


    2)-Vertical Clustering

     




    Steps to follow:

    1- Download zip file for tomcat/don’t use direct installer as it doesn't contain “starup.bat” etc.
    2- Unzip it and rename it to your convenience say tomcatA
    3- Copy this unzipped folder (in our example I am calling it as tomactA) and make one copy of it and again rename it to your convenience say tomcatB
    4-If u want third tomcat also in cluster then make one more copy and rename it to say tomcat, I will be using only two tomcats in this example.
    5-now modify server.xml file in each tomcat, i.e. in our example in tomcatA and tomcat. The server.xml can be found in conf folder of tomcat.
    6)-just modify the highlighted part as shown in server.xml below


    tomcatA:
    <!-- Note:  A "Server" is not itself a "Container", so you may not
         define subcomponents such as "Valves" at this level.
         Documentation at /docs/config/server.html
     -->
    <Server port="8105" shutdown="SHUTDOWN">
      <!--APR library loader. Documentation at /docs/apr.html -->
      <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
      <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
      <Listener className="org.apache.catalina.core.JasperListener" />
      <!-- JMX Support for the Tomcat server. Documentation at /docs/non-existent.html -->
      <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
      <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
      <!-- Global JNDI resources
           Documentation at /docs/jndi-resources-howto.html
      -->
      <GlobalNamingResources>
        <!-- Editable user database that can also be used by
             UserDatabaseRealm to authenticate users
        -->
        <Resource name="UserDatabase" auth="Container"
                  type="org.apache.catalina.UserDatabase"
                  description="User database that can be updated and saved"
                  factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
                  pathname="conf/tomcat-users.xml" />
      </GlobalNamingResources>
      <!-- A "Service" is a collection of one or more "Connectors" that share
           a single "Container" Note:  A "Service" is not itself a "Container", 
           so you may not define subcomponents such as "Valves" at this level.
           Documentation at /docs/config/service.html
       -->
      <Service name="Catalina">
      
        <!--The connectors can use a shared executor, you can define one or more named thread pools-->
        <!--
        <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" 
            maxThreads="150" minSpareThreads="4"/>
        -->
        
        
        <!-- A "Connector" represents an endpoint by which requests are received
             and responses are returned. Documentation at :
             Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
             Java AJP  Connector: /docs/config/ajp.html
             APR (HTTP/AJP) Connector: /docs/apr.html
             Define a non-SSL HTTP/1.1 Connector on port 8080
        -->
        <Connector port="8081" protocol="HTTP/1.1" 
                   connectionTimeout="20000" 
                   redirectPort="8443" />
        <!-- A "Connector" using the shared thread pool-->
        <!--
        <Connector executor="tomcatThreadPool"
                  
    port="8180" protocol="HTTP/1.1" 
                   connectionTimeout="20000" 
                   redirectPort="8443" />
        -->           
        <!-- Define a SSL HTTP/1.1 Connector on port 8443
             This connector uses the JSSE configuration, when using APR, the 
             connector should be using the OpenSSL style configuration
             described in the APR documentation -->
        <!--
        <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
                   maxThreads="150" scheme="https" secure="true"
                   clientAuth="false" sslProtocol="TLS" />
        -->
        <!-- Define an AJP 1.3 Connector on port 8009 -->
        <Connector port="8109" protocol="AJP/1.3" redirectPort="8443" />

        <!-- An Engine represents the entry point (within Catalina) that processes
             every request.  The Engine implementation for Tomcat stand alone
             analyzes the HTTP headers included with the request, and passes them
             on to the appropriate Host (virtual host).
             Documentation at /docs/config/engine.html -->
        <!-- You should set jvmRoute to support load-balancing via AJP ie :
        <Engine name="Standalone" defaultHost="localhost" jvmRoute="jvm1">         
        --> 
        <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcatA">
          <!--For clustering, please take a look at documentation at:
              /docs/cluster-howto.html  (simple how to)
              /docs/config/cluster.html (reference documentation) -->
          
          <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
                
          <!-- The request dumper valve dumps useful debugging information about
               the request and response data received and sent by Tomcat.
               Documentation at: /docs/config/valve.html -->
          <!--
          <Valve className="org.apache.catalina.valves.RequestDumperValve"/>
          -->
          <!-- This Realm uses the UserDatabase configured in the global JNDI
               resources under the key "UserDatabase".  Any edits
               that are performed against this UserDatabase are immediately
               available for use by the Realm.  -->
          <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
                 resourceName="UserDatabase"/>
          <!-- Define the default virtual host
               Note: XML Schema validation will not work with Xerces 2.2.
           -->
          <Host name="localhost"  appBase="webapps"
                unpackWARs="true" autoDeploy="true"
                xmlValidation="false" xmlNamespaceAware="false">
            <!-- SingleSignOn valve, share authentication between web applications
                 Documentation at: /docs/config/valve.html -->
            <!--
            <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
            -->
            <!-- Access log processes all example.
                 Documentation at: /docs/config/valve.html -->
            <!--
            <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"  
                   prefix="localhost_access_log." suffix=".txt" pattern="common" resolveHosts="false"/>
            -->
          </Host>
        </Engine>
      </Service>
    </Server>




    2 tomcatB:
    <!-- Note:  A "Server" is not itself a "Container", so you may not
         define subcomponents such as "Valves" at this level.
         Documentation at /docs/config/server.html
     -->
    <Server port="8205" shutdown="SHUTDOWN">
      <!--APR library loader. Documentation at /docs/apr.html -->
      <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
      <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
      <Listener className="org.apache.catalina.core.JasperListener" />
      <!-- JMX Support for the Tomcat server. Documentation at /docs/non-existent.html -->
      <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
      <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
      <!-- Global JNDI resources
           Documentation at /docs/jndi-resources-howto.html
      -->
      <GlobalNamingResources>
        <!-- Editable user database that can also be used by
             UserDatabaseRealm to authenticate users
        -->
        <Resource name="UserDatabase" auth="Container"
                  type="org.apache.catalina.UserDatabase"
                  description="User database that can be updated and saved"
                  factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
                  pathname="conf/tomcat-users.xml" />
      </GlobalNamingResources>
      <!-- A "Service" is a collection of one or more "Connectors" that share
           a single "Container" Note:  A "Service" is not itself a "Container", 
           so you may not define subcomponents such as "Valves" at this level.
           Documentation at /docs/config/service.html
       -->
      <Service name="Catalina">
      
        <!--The connectors can use a shared executor, you can define one or more named thread pools-->
        <!--
        <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" 
            maxThreads="150" minSpareThreads="4"/>
        -->
        
        
        <!-- A "Connector" represents an endpoint by which requests are received
             and responses are returned. Documentation at :
             Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
             Java AJP  Connector: /docs/config/ajp.html
             APR (HTTP/AJP) Connector: /docs/apr.html
             Define a non-SSL HTTP/1.1 Connector on port 8080
        -->
        <Connector port="8082" protocol="HTTP/1.1" 
                   connectionTimeout="20000" 
                   redirectPort="8443" />
        <!-- A "Connector" using the shared thread pool-->
        <!--
        <Connector executor="tomcatThreadPool"
                  
    port="8280" protocol="HTTP/1.1" 
                   connectionTimeout="20000" 
                   redirectPort="8443" />
        -->           
        <!-- Define a SSL HTTP/1.1 Connector on port 8443
             This connector uses the JSSE configuration, when using APR, the 
             connector should be using the OpenSSL style configuration
             described in the APR documentation -->
        <!--
        <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
                   maxThreads="150" scheme="https" secure="true"
                   clientAuth="false" sslProtocol="TLS" />
        -->
        <!-- Define an AJP 1.3 Connector on port 8009 -->
        <Connector port="8209" protocol="AJP/1.3" redirectPort="8443" />

        <!-- An Engine represents the entry point (within Catalina) that processes
             every request.  The Engine implementation for Tomcat stand alone
             analyzes the HTTP headers included with the request, and passes them
             on to the appropriate Host (virtual host).
             Documentation at /docs/config/engine.html -->
        <!-- You should set jvmRoute to support load-balancing via AJP ie :
        <Engine name="Standalone" defaultHost="localhost" jvmRoute="jvm1">         
        --> 
        <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcatB">
          <!--For clustering, please take a look at documentation at:
              /docs/cluster-howto.html  (simple how to)
              /docs/config/cluster.html (reference documentation) -->
          
          <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
                
          <!-- The request dumper valve dumps useful debugging information about
               the request and response data received and sent by Tomcat.
               Documentation at: /docs/config/valve.html -->
          <!--
          <Valve className="org.apache.catalina.valves.RequestDumperValve"/>
          -->
          <!-- This Realm uses the UserDatabase configured in the global JNDI
               resources under the key "UserDatabase".  Any edits
               that are performed against this UserDatabase are immediately
               available for use by the Realm.  -->
          <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
                 resourceName="UserDatabase"/>
          <!-- Define the default virtual host
               Note: XML Schema validation will not work with Xerces 2.2.
           -->
          <Host name="localhost"  appBase="webapps"
                unpackWARs="true" autoDeploy="true"
                xmlValidation="false" xmlNamespaceAware="false">
            <!-- SingleSignOn valve, share authentication between web applications
                 Documentation at: /docs/config/valve.html -->
            <!--
            <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
            -->
            <!-- Access log processes all example.
                 Documentation at: /docs/config/valve.html -->
            <!--
            <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"  
                   prefix="localhost_access_log." suffix=".txt" pattern="common" resolveHosts="false"/>
            -->
          </Host>
        </Engine>
      </Service>
    </Server>


    7) - To check whether both tomcat are working properly or not
    1) - open terminal go to tomcat folder say d: /tomcatA/bin
    Now run startup.bat
    You will see the logs on terminal, saying server startup in xxx ms
    2) Do the same for remaining tomcats.
    One common error is message is CATLINA_HOME not defined properly, for clustering purpose we don’t need the variable defined. Therefore just open system variable and remove it from there.
    8)-Now install Apche on your system, if u hasn’t done so then download it first.
    9) - Now download” mod_jk” and copy it to modules folder of Apache.
    10) - Rename the downloaded file to mod_jk.so (if some other name is given u can use that name also on configuration but I feel this more convenient)
    11)-Now edit” httpd.conf file”, it can be found in Apache/conf folder
    12) - Just add following code in that file
    LoadModule jk_module modules/mod_jk.so 
    JkWorkersFile "C:\Apache\conf\workers.properties" 
    JkLogFile "logs/mod_jk.log" 
    JkLogLevel error 
    JkMount /cluster loadbalancer 
    JkMount /cluster/* loadbalancer

    Points to note here
    1)- if you have used any other name then mod_jk.so by skipping step 9 then add that name instead of “mod_jk.so” on first line of above code
    2) - I am assuming you have installed Apache on C drive, if it’s in some different location then change the second line of code accordingly
    13) - Now add “mod_jk.log” file in log folder of Apache, as some times Apache gives error if it is not present
    14) - Now create “worker.properties” file in Apache/conf
    15) –Add following content to the file
    Vertical tomcat clustering this file like
    workers.tomcat_home=/tomcatA
    workers.java_home=$JAVA_HOME
    ps=/
    worker.list=tomcatA,tomcatB,loadbalancer

    worker.tomcatA.port=8109
    worker.tomcatA.host=localhost
    worker.tomcatA.type=ajp13
    worker.tomcatA.lbfactor=1

    worker.tomcatB.port=8209
    worker.tomcatB.host=localhost
    worker.tomcatB.type=ajp13
    worker.tomcatB.lbfactor=1

    worker.loadbalancer.type=lb
    worker.loadbalancer.balanced_workers=tomcatA,tomcatB
    worker.loadbalancer.sticky_session=1




    For horizontal tomcat clustering
    workers.tomcat_home=/tomcatA
    workers.java_home=$JAVA_HOME
    ps=/
    worker.list=tomcatA,tomcatB,tomcatC,loadbalancer

    worker.tomcatA.port=8009
    worker.tomcatA.host=192.168.1.1
    worker.tomcatA.type=ajp13
    worker.tomcatA.lbfactor=1

    worker.tomcatB.port=8009
    worker.tomcatB.host=192.168.1.2
    worker.tomcatB.type=ajp13
    worker.tomcatB.lbfactor=1
    worker.loadbalancer.type=lb
    worker.loadbalancer.balanced_workers=tomcatA,tomcatB
    worker.loadbalancer.sticky_session=1


    Points to note:
                    The sticky_session property specifies the cluster behavior for HTTP sessions. If you specifyworker.loadbalancer.sticky_session=0, each request will be load balanced between node1 and node2; i.e., different requests for the same session will go to different servers. But when a user opens a session on one server, it is always necessary to always forward this user's requests to the same server, as long as that server is available. This is called a "sticky session", as the client is always using the same server he reached on his first request. To enable session stickiness, you need to setworker.loadbalancer.sticky_session to 1.
    16) - Now start Apache, you can do it by going in Apache/bin folder using terminal and then run httpd.exe
    17) - Start both the tomcat as explained on step 7
    18) - You have working cluster now, but we need to modify “web.xml” of any project in order to make it work in clustered environment, to achieve this just add following line in web.xml
    Add <distributable /> in web.xml file

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
       version="2.5">
      <distributable />
      
    </web-app>