Tuesday 25 June 2013

JCS implementation in JAVA



Java Caching System (JCS)

It’s a distributed caching system written in java. It is used to speed up applications by providing a way to manage cached data of various dynamic environments. JCS is most helpful for the applications where read operations are highly preferable than update operations.


It provides multiple additional features like below:
  • Memory management
  • Thread pool controls
  • Minimal dependencies
  • Data expiration (idle time and max life)
  • Extensible framework
  • Fully configurable runtime parameters
  • Region data separation and configuration
  • Remote synchronization
  • Remote store recovery
  • Element event handling
  • Custom event logging hooks
  • Custom event queue injection
  • Custom object serializer injection
  • Key pattern matching retrieval



Feature Details:-

  • JCS: - It’s a cache which supports caching data in memory, or a disk on a remote server using RMI. It is very much suitable for caching data on the Data Access layer.
  • It doesn't provide any provision to support caching of HttpResponse and Page Fragment caching on the presentation layer.
  • It helps in supporting for distributed cache. All updates and invalidations to the local cache are broadcast to all the caches involved in the cluster. Hence, it can be inferred that it is very much suitable for those applications which is having frequent reads and infrequent updates process.
  • Its cache area can be in indexed disk space, remote cache, memory and lateral cache. JCS is having the facility where a combination of caches can also be configured. If the memory area is full, objects are bounced to disk.
  • In JCS, the data in the disk is indexed to facilitate easy retrieval from disk. The facility for handling a remote cache is more suitable when we have multiple web server JVMs running on the same node.
  • A property file named config.ccf is needed to set JCS configurations.
  • It helps for accessing its cache from a Java class using JCS API.

Question: - What is Page Fragment caching?

Answer: - Page fragment caching provides a facility to wrap a part of logic in a cache block used in the page and served out of the cache store when the next request comes in.


Question: - How to implement JCS in java?
Answer:-  

Example of JCS implementation in Java.


System Requirements:-

          Eclipse Editor or any other.
         JDK 1.5 or higher(I am using jdk 1.7.0_03)
         JCS jars.


Required Jars are:-

commons-logging.jar
commons-lang-2.4.jar
concurrent.jar
jcs-1.3.jar


Steps for creating Eclipse java project for implementing Java Caching System:-

  • Create a java project in eclipse.
  • Create a package in the src folder with the name as com.gaurav.apachejcs.impl.
  • Add the required jars in the build path of the project.
  • Create the Product.java and ProductManager.java files in this package and place the corresponding below available code in those files.
  • Create a cache.ccf file and place the below code in that file. This file is used for the JCS configurations. This file needs to be placed in the src folder.
  • Execute the ProductManager.java by selecting the option Run as Java Application.

Product.java

package com.gaurav.apachejcs.impl;

/**
 * @author Gaurav
 *
 */
public class Product implements java.io.Serializable {
      /**
       *
       */
      private static final long serialVersionUID = -5372772868069600498L;
      private String productId;
      private String productName;
      private String productMaker;

      public Product(){

      }
      public Product(String prodId, String prodName, String prodMaker){
            this.productId = prodId;
            this.productName = prodName;
            this.productMaker = prodMaker;
      }
      /**
       * @return the productId
       */
      public String getProductId() {
            return productId;
      }
      /**
       * @param productId the productId to set
       */
      public void setProductId(String productId) {
            this.productId = productId;
      }
      /**
       * @return the productName
       */
      public String getProductName() {
            return productName;
      }
      /**
       * @param productName the productName to set
       */
      public void setProductName(String productName) {
            this.productName = productName;
      }

      /**
       * @return the productMaker
       */
      public String getProductMaker() {
            return productMaker;
      }
      /**
       * @param productMaker the productMaker to set
       */
      public void setProductMaker(String productMaker) {
            this.productMaker = productMaker;
      }

      @Override
      public String toString() {
            return productName + " made by " + productMaker + " and Model No is : " + productId;
      }

}


ProductManager.java


package com.gaurav.apachejcs.impl;

import org.apache.jcs.JCS;
import org.apache.jcs.access.exception.CacheException;



public class ProductManager {
      private JCS jcsCache;

      public ProductManager() {
            try {
                  // Loading the cache using the configuration file
                  jcsCache = JCS.getInstance("productDetailsCache");

                  // Initializing the cache by putting two product data into cache.
                  jcsCache.put("KDL-32EX650", new Product("KDL-32EX650",
                              "BRAVIA Full HD with Edge LED", "SONY"));
                  jcsCache.put("72LM9500", new Product("72LM9500",
                              "Full HD LED 3D Smart TV", "LG"));

            } catch (CacheException e) {
                  e.printStackTrace();
            }
      }

      public void addProductInCache(Product product) {
            try {
                  jcsCache.put(product.getProductId(), product);
            } catch (CacheException e) {
                  e.printStackTrace();
            }
      }

      public Product getProductById(String productId) {
            return (Product) jcsCache.get(productId);
      }

      public void removeProductFromCache(String productId) {
            try {
                  jcsCache.remove(productId);
            } catch (CacheException e) {
                  e.printStackTrace();
            }
      }

      public static void main(String[] args) {
            // Creating the ProductManager instance
            ProductManager productManager = new ProductManager();

            // Adding one more product data in the cache.
            productManager.addProductInCache(new Product("UA85S9AR",
                        "Smart TV 2.0", "Samsung"));

            // Getting all the products details which is added in cache

            Product product = productManager.getProductById("KDL-32EX650");
            System.out.println("The First Product retrieved from cache is :- " + product);

            product = productManager.getProductById("72LM9500");
            System.out.println("The Second Product retrieved from cache is :- " + product);

            product = productManager.getProductById("UA85S9AR");
            System.out.println("The Third Product retrieved from cache is :- " + product);


            // Removing a product from the productManager
            productManager.removeProductFromCache("KDL-32EX650");

            // Cross checking that the removed product is still available or not.
            System.out.println("\n**********************************************************************************************");
            System.out
                        .println("Again trying to retrieve the First product from the cache after removing the First product:- "
                                    + productManager.getProductById("KDL-32EX650"));
            System.out.println("**********************************************************************************************\n");

            System.out
            .println("Again trying to retrieve the Second product from the cache after removing the First product:- "
                        + productManager.getProductById("72LM9500"));

            System.out
            .println("Again trying to retrieve the Third product from the cache after removing the First product:- "
                        + productManager.getProductById("UA85S9AR"));

      }
}

Note: - We have wrapped the JCS get, put and remove methods in the ProductManager class
  • put (): puts an object in the cache, of the form (key, value). In this example, the product’s ID is the key and the value is the Product.
  • get(): returns the object with the specified primary key
  • remove(): removes the object with the specified primary key

cache.ccf

# DEFINING CACHE REGIONS FOR PRODUCTDETAILSCACHE

# -------The most basic configuration would be a pure memory cache where every region takes the default values.---------

jcs.region.productDetailsCache=DC
jcs.region.productDetailsCache.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.region.productDetailsCache.cacheattributes.MaxObjects=1000
jcs.region.productDetailsCache.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache

#------ IF WE WANT TO ADD MEMORY SHRINKING THEN WE CAN ADD THESE LINES ---------------

jcs.region.productDetailsCache.cacheattributes.ShrinkerIntervalSeconds=60
jcs.region.productDetailsCache.cacheattributes.MaxSpoolPerRun=500
jcs.region.productDetailsCache.elementattributes=org.apache.jcs.engine.ElementAttributes
jcs.region.productDetailsCache.elementattributes.IsEternal=false
jcs.region.productDetailsCache.cacheattributes.UseMemoryShrinker=true
jcs.region.productDetailsCache.cacheattributes.MaxMemoryIdleTimeSeconds=3600

#--------- FOR MORE CONFIGURATION DETAILS VISIT:- http://commons.apache.org/proper/commons-jcs/BasicJCSConfiguration.html ------------

Result:-

Jun 26, 2013 6:51:10 AM org.apache.jcs.engine.control.CompositeCacheManager configure
INFO: Creating cache manager from config file: /cache.ccf
Jun 26, 2013 6:51:10 AM org.apache.jcs.utils.threadpool.ThreadPoolManager loadConfig
INFO: thread_pool.default PoolConfiguration = useBoundary = [true] boundarySize = [2000] maximumPoolSize = [150] minimumPoolSize = [4] keepAliveTime = [300000] whenBlockedPolicy = [RUN] startUpSize = [4]
Jun 26, 2013 6:51:10 AM org.apache.jcs.engine.control.CompositeCacheConfigurator setDefaultAuxValues
INFO: Setting default auxiliaries to null
Jun 26, 2013 6:51:10 AM org.apache.jcs.engine.control.CompositeCacheConfigurator parseCompositeCacheAttributes
INFO: No special CompositeCacheAttributes class defined for key [jcs.default.cacheattributes], using default class.
Jun 26, 2013 6:51:10 AM org.apache.jcs.engine.control.CompositeCacheConfigurator setDefaultCompositeCacheAttributes
INFO: setting defaultCompositeCacheAttributes to [ useLateral = true, useRemote = true, useDisk = true, maxObjs = 100, maxSpoolPerRun = -1, diskUsagePattern = 0 ]
Jun 26, 2013 6:51:10 AM org.apache.jcs.engine.control.CompositeCacheConfigurator parseElementAttributes
INFO: No special ElementAttribute class defined for key [jcs.default.elementattributes], using default class.
Jun 26, 2013 6:51:10 AM org.apache.jcs.engine.control.CompositeCacheConfigurator setDefaultElementAttributes
INFO: setting defaultElementAttributes to [ IS_LATERAL = true, IS_SPOOL = true, IS_REMOTE = true, IS_ETERNAL = true, MaxLifeSeconds = -1, IdleTime = -1, CreateTime = 1372209670187, LastAccessTime = 1372209670187, getTimeToLiveSeconds() = -1, createTime = 1372209670187 ]
Jun 26, 2013 6:51:10 AM org.apache.jcs.engine.memory.lru.LRUMemoryCache initialize
INFO: initialized LRUMemoryCache for productDetailsCache
Jun 26, 2013 6:51:10 AM org.apache.jcs.engine.control.CompositeCache <init>
INFO: Constructed cache with name [productDetailsCache] and cache attributes [ useLateral = true, useRemote = true, useDisk = true, maxObjs = 1000, maxSpoolPerRun = 500, diskUsagePattern = 0 ]
Jun 26, 2013 6:51:10 AM org.apache.jcs.engine.control.CompositeCacheConfigurator parseAuxiliary
SEVERE: Could not instantiate auxFactory named "DC".
Jun 26, 2013 6:51:10 AM org.apache.jcs.engine.control.CompositeCacheConfigurator parseRegions
INFO: Parsed regions [productDetailsCache]
Jun 26, 2013 6:51:10 AM org.apache.jcs.engine.control.CompositeCacheConfigurator doConfigure
INFO: Finished configuration in 219 ms.
The First Product retrieved from cache is :- BRAVIA Full HD with Edge LED made by SONY and Model No is : KDL-32EX650
The Second Product retrieved from cache is :- Full HD LED 3D Smart TV made by LG and Model No is : 72LM9500
The Third Product retrieved from cache is :- Smart TV 2.0 made by Samsung and Model No is : UA85S9AR

**********************************************************************************************
Again trying to retrieve the First product from the cache after removing the First product:- null
**********************************************************************************************

Again trying to retrieve the Second product from the cache after removing the First product:- Full HD LED 3D Smart TV made by LG and Model No is : 72LM9500
Again trying to retrieve the Third product from the cache after removing the First product:- Smart TV 2.0 made by Samsung and Model No is : UA85S9AR


reference taken from http://commons.apache.org

Sunday 16 June 2013

Java ClassLoader



How ClassLoader Works in Java?


  • A class loader is an object, a java program that is responsible for loading classes. 
  • It is the class responsible for finding and loading class files at runtime. 
  • The Java ClassLoader is a part of the Java Runtime Environment (JRE) that dynamically loads Java classes into the JVM (Java Virtual Machine). 
  • Generally classes are loaded only on demand. Because of the help provided by Java Class Loaders the JRE system does not required to know about files and file systems. 
  • The JVM needs a class, so it asks the ClassLoader, by providing the name, and the ClassLoader attempts to return a Class object that represents that class. 
  • In JVM, each and every class is loaded by some instance of a java.lang.ClassLoader
  • The ClassLoader class is located in the java.lang package and we are free to subclass it to add their own custom ClassLoader functionality for class loading.

Questions: - What is Class Loading?


Answers: - The term “class loading” refers to the process of locating the bytes for the given class name and converting them into a Java Class instance. All java.lang.Class instances within a JVM start life as an array of bytes, structured in the class file format defined by the JVM specification.

ClassLoader.loadClass() is the entry point to the ClassLoader.

Its signature is as follows:

Class loadClass(String name) - Loads the class with the specified binary name.

ClassLoaders:-

A general Java program running from command line involves three ClassLoaders – Bootstrap, Extensions ClassLoader and System - Classpath ClassLoaders. When JVM is started, it forms an initial class loader hierarchy with the combination of these ClassLoaders.




ClassLoader Hierarchy



Bootstrap ClassLoader

Another name of bootstrap class loader is primordial ClassLoader. This ClassLoader is responsible to load JDK core java classes from rt.jar. This is the parent/super of all the ClassLoaders. The uniqueness of this ClassLoader is that it is not actually a subclass of java.lang.ClassLoader but is implemented by the JVM itself. Whenever a new JVM is started by typing java TestClass, the "bootstrap ClassLoader" is responsible for loading key Java classes like java.lang.Object and other runtime code into memory first. The runtime classes are packaged inside of the JRE\lib\rt.jar file. We can’t find the details of the bootstrap ClassLoader in the Java docs, since this is a native implementation. For the same reason, the behavior of the bootstrap class loader will also differ/changes across JVMs.

Extension ClassLoader

The extension ClassLoader is responsible to load classes from the jars kept in the JRE extension directory (<JAVA_HOME>/jre/lib/ext, or any other directory specified by the java.ext.dirs system property. This ClassLoader provides a standard mechanism to introduce new functionality beyond the core java classes. So a developer can add his own application .jar files or whatever libraries he might need to add to the classpath to this extension directory so that they will be loaded by the extension class loader. Extension ClassLoader in JVM is implemented by sun.misc.Launcher$ExtClassLoader. This is the immediate child of bootstrap ClassLoader, but calling getParent() on this instance will always return null, since the bootstrap loader is not an actual ClassLoader instance.

System-Classpath ClassLoader or Application ClassLoader 


System-Classpath ClassLoader is a child of Extension ClassLoader. This ClassLoader is responsible for loading all of the classes from CLASSPATH environment variable or corresponding to java.class.path system property or –cp or –classpath command line settings. It is implemented by sun.misc.Launcher$AppClassLoader class

User-Defined ClassLoader 


It allows applications to customize class loading as per their requirements.


Examples of some other JDK ClassLoaders:-
  • sun.applet.AppletClassLoader
  • java.net.URLClassLoader
  • java.rmi.server.RMIClassLoader
  • java.security.SecureClassLoader

Phases of Class Loading:-

The complete class loading process can be categorized into three phases:-

Loading: - During loading, the required class file is searched in specified classpaths. If the file is available in the specified classpath then it is read and the bytecode is loaded. This process gives a basic memory structure to the class object, and at this stage the methods, fields and other reference classes are not known.

Linking: - This process can be broken down into three stages, as this is a bit complex phase.

  • Bytecode verification: - ClassLoader does a number of checks on the bytecode.

  • Class preparation: - In this stage, ClassLoader prepares the necessary data structures that represent fields, methods and implemented interfaces that are defined within the class.

  • Resolving: - ClassLoader loads all the other classes which is being referenced by a particular class. The classes can be referenced in a number of ways:
      • Super classes
      • Interfaces
      • Field types
      • Method signatures
      • Local variables used in methods

Initializing: - During this phase any static initializers contained within a class are executed so that, static fields are initialized to their default values. 
Note:- It is interesting, that class loading can be performed in a lazy manner and therefore some parts of the class loading process may be done on first use of the class rather than at load time.


 






Class Loading Phases details




Java ClassLoader operation works on 3 principles:

Delegation

This principle tells, if a particular class is already not loaded, then the ClassLoader delegates the request to load that class to their parent ClassLoaders. This delegation continues until the top of the hierarchy is reached. Suppose we want to load HelloWorld.class which is application specific class, then the first request for loading this class will come to System-Classpath ClassLoader or Application ClassLoader, which will delegate to its parent Extension ClassLoader and again which further delegates that request to Bootstrap ClassLoader. Bootstrap ClassLoader will look for that class in rt.jar and since that class is not available there, then Bootstrap ClassLoader delegates the request to Extension ClassLoader and it tries to find on jre/lib/ext directory and locate this class there, if class is found there than Extension class loader will load that class and System-Classpath ClassLoader will never try to load that class but if it is not loaded by Extension ClassLoader than System-Classpath ClassLoader loads it from Classpath

  



Delegation principle



Visibility

This principle tells that Classes loaded by parent ClassLoaders are visible to child ClassLoaders but not vice versa. It means that if class HelloWorld.class is loaded by Application class loader than trying to load class HelloWorld.class explicitly by using Extension ClassLoader will throw exception.

In order to check the visibility principle we have following program:-

import java.util.logging.Level;
import java.util.logging.Logger;

public class VisiblityPrincipleTestInClassLoader {

            private final static Logger logger = Logger
                                    .getLogger(VisiblityPrincipleTestInClassLoader.class.getName());

            public static void main(String args[]) {
                        try {
                                    /**
                                     * Displaying ClassLoader of VisiblityPrincipleTestInClassLoader
                                     * class
                                     */
                                    System.out.println("VisiblityPrincipleTestInClassLoader.class.getClassLoader() : "
                                                            + VisiblityPrincipleTestInClassLoader.class
                                                                                    .getClassLoader());

                                    /**
                                     * Again trying to explicitly load
                                     * VisiblityPrincipleTestInClassLoader class by using Extension
                                     * Class Loader as we are calling getParent() method and Extension
                                     * ClassLoader is the parent of AppClassLoader or System-Classpath
                                     * ClassLoader.
                                     */
                                    Class.forName("VisiblityPrincipleTestInClassLoader", true,
                                                            VisiblityPrincipleTestInClassLoader.class.getClassLoader()
                                                                                    .getParent());
                        } catch (ClassNotFoundException ex) {
                                    logger.log(Level.SEVERE, "ClassNotFoundException", ex);
                        }
            }

}

Result:-

VisiblityPrincipleTestInClassLoader.class.getClassLoader() : sun.misc.Launcher$AppClassLoader@1050169
Jun 16, 2013 3:42:34 PM VisiblityPrincipleTestInClassLoader main
SEVERE: ClassNotFoundException
java.lang.ClassNotFoundException: VisiblityPrincipleTestInClassLoader
            at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
            at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
            at java.security.AccessController.doPrivileged(Native Method)
            at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
            at java.lang.Class.forName0(Native Method)
            at java.lang.Class.forName(Class.java:264)
            at VisiblityPrincipleTestInClassLoader.main(VisiblityPrincipleTestInClassLoader.java:26)


Uniqueness

This principle tells that when a ClassLoader loads a class, the child ClassLoader in the hierarchy should never load the class again. This follows from the delegation principle as we know that a ClassLoader always delegates class loading to its parents. The child ClassLoader will only try to load in case if parent ClassLoader hierarchy fails to load that class. Thus the uniqueness of the class is maintained.
 

There are many ways to access a ClassLoader:-



  • class.getClassLoader();
  • classLoader.getSystemClassLoader();
  • Thread.currentThread().getContextClassLoader();
  • Or Thread. getContextClassLoader();
  • An application specific method to retieve a class loader.


Explicit/Implicit Class Loading:-


  • Implicit Class Loading: - It occurs when the class is loaded as a result of reference, inheritance or initialization. In this type of loading, class is either return through the delegation model or from the cache.
  •  Explicit Class Loading:- It occurs when a class is loaded by using some specific methods which is as below:-

classLoader.loadClass("VisiblityPrincipleTestInClassLoader");

Here classLoader is an instance of java.lang.ClassLoader class.

Class.forName(“VisiblityPrincipleTestInClassLoader”);

If the class whose name is specified as the parameter for loading it explicitly, is already loaded then ClassLoader returns the reference to it from cache else ClassLoaders will follow the delegation model to load the class.

Question: - Why to write a custom ClassLoader?

Answer: - For the following purposes, we can write the custom ClassLoaders:-
  • Security: - Our ClassLoaders should be responsible to examine classes for having a digital signature before they are handed over to the JVM.
  • Encryption: - For providing the facility to our ClassLoaders that decrypts class files on the fly, so that our class files on disk are not readable by someone by using the decompiler.
  • To allow class loading from alternative repositories:- For integrating a feature into out ClassLoaders, so that it will be able to load the class files that are not in the classpath or it will be able to load classes from over the network.
  • Archiving: - If we want to distribute our code in a unique format or with some special compression.
  • For Loading of specific versions: - it helps in selectively loading classes from specific locations.
  • To allow the unloading of classes if required for any specific application.

About Custom ClassLoader

Generally, J2EE servers implement custom ClassLoader to enable features such as hot redeployment and application independence. Normally, the class loaded by custom ClassLoader is unknown to current class loader, we can't cast the object to real type, we can refer it as an object or refer it using its interface.


Questions:- How to write a custom ClassLoader?


Answer:- Minimal steps to implement a custom ClassLoader
  •        We need to extends the ClassLoader and needs to override loadClass () and findClass ()   method.
  •        Check whether the class has already been loaded, if already loaded, just return it.
  •        If not, check to see whether its parent class loader can load this class.
  •        If not, then we have to implement the logic to load it by its own.
  •        Define the class (call parent's method directly).
  •        Check whether the class has to be resolved (linked), and in that case, resolve it (call parent's method directly).
  •        Return the Class object to the caller.

Question:- What is JAR hell?

Answer:- JAR hell is a term which is very much similar to DLL hell which is used to describe all the various ways in which the classloading process can end up with not working.