Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Tuesday, May 8, 2012

Writing own cache in JAVA

Cache is being increasingly used for improving performance. The cache improves the performance by not getting to go to database or any other system which doesnot reside in the memory( here its JVM) again and again. The cache should store those frequently accessed data or objects in the memory itself. Here in this blog i have come up with 4 different kinds of algorithms that you can use to create a cache and store the objects in the memory. In the last part i have combined all these to form the framework which one can use in any java application.

First one is  LRU (Least Recently Used)

It says that the objects that are recently used are the one that will be kept in the cache otherwise it will be removed from the cache.

The code is shown below:

public class LRUCache  {
  private int cacheSize;
  private Map<Object,Object> cache;
  private List<Object> keyList;
  /**
   * Default constructor
   */
  public LRUCache() {
    this.cacheSize = 100;
    this.cache = new ConcurrentHashMap<Object,Object>();
    this.keyList = Collections.synchronizedList(new LinkedList<Object>());
  }
 
  /**
   * Add an object to the cache
   *
   *
   * @param key        The key of the object to be cached
   * @param value      The object to be cached
   */
  public void putObject(Object key, Object value) {
    cache.put(key, value);
    keyList.add(key);
    if (keyList.size() > cacheSize) {
      try {
        Object oldestKey = keyList.remove(0);
        cache.remove(oldestKey);
      } catch (IndexOutOfBoundsException e) {
        //ignore
      }
    }
  }
  /**
   * Get an object out of the cache.
   *
   * @param key        The key of the object to be returned
   * @return The cached object (or null)
   */
  public Object getObject(Object key) {
    Object result = cache.get(key);
    keyList.remove(key);
    if (result != null) {
      keyList.add(key);
    }
    return result;
  }
  public Object removeObject(Object key) {
    keyList.remove(key);
    return cache.remove(key);
  }
  /**
   * Flushes the cache.
   *
   *
   */
  public void flush() {
    cache.clear();
    keyList.clear();
  }
}

The second one is FIFO (First In First Out)

The code for the same algorithm is

public class FifoCache {
  private int cacheSize;
  private Map<Object,Object> cache;
  private List<Object> keyList;
  /**
   * Default constructor
   */
  public FifoCache() {
    this.cacheSize = 100;
    this.cache = new ConcurrentHashMap<Object,Object>();
    this.keyList = Collections.synchronizedList(new LinkedList<Object>());
  }

  /**
   * Add an object to the cache
   *
   *
   * @param key        The key of the object to be cached
   * @param value      The object to be cached
   */
  public void putObject(Object key, Object value) {
    cache.put(key, value);
    keyList.add(key);
    if (keyList.size() > cacheSize) {
      try {
        Object oldestKey = keyList.remove(0);
        cache.remove(oldestKey);
      } catch (IndexOutOfBoundsException e) {
        //ignore
      }
    }
  }
  /**
   * Get an object out of the cache.
   * @param key        The key of the object to be returned
   * @return The cached object (or null)
   */
  public Object getObject(Object key) {
    return cache.get(key);
  }
  public Object removeObject(Object key) {
    keyList.remove(key);
    return cache.remove(key);
  }
  /**
   * Flushes the cache.
   *
   * @param cacheModel The cache model
   */
  public void flush() {
    cache.clear();
    keyList.clear();
  }
}

Wednesday, May 2, 2012

Weak Reference vs Strong Reference vs Soft Reference in Java

One of the most neglected areas in JAVA is kind of references that we create. I was also not aware of the references untill i implemented the memory cache. I will be using it as an example to showcase the usage of references. One of the important variations in implementaion of cache is the memory cache where we define the refererence type. The benefit of having this kind of caching mechanism is that we can basically segregate the kind of objects that can be easily garbage collected and making the memory available for more important objects.

Java provides a way to create different kinds of references. These references types if used properly can be of immense use and can be a great performance booster for an application.

There are basically three kinds of references that we can create.
  1. Weak Reference
  2. Strong Reference
  3. Soft Reference.
The references are basically used to convey the message to the garbage collector.

If its a Weak reference then the object will be garbage collected if not currently in use making the memory available for the other objects. Using this kind of reference ( for key) in cache will immemsely increase the performance in the case of most popular results. But it has a downside that it will absolutely de allocate the memory.

Example:
Creating a WeakReference
reference = new WeakReference(value);

getting the value
value = ((WeakReference) ref).get();where the ref is the reference to the value.

If its a Soft reference it will reduce the likelihood of running out of memory in case the results are not currently in use and the memory is needed for other objects. However this is not the most aggresive in this regard.Hence memory still might be alloacted and unavailable for more important objects.

Example:
Creating the SoftReference
reference = new SoftReference(value);
getting the value

value = ((SoftReference) ref).get();
where the ref is the reference to the value.

In case of Strong reference the object will remain in memory untill and unless the object is not de referenced. In case of cache implementation the performance will be very good in case of particular query.

reference =

getting the valuevalue = ((StrongReference) ref).get();
where the ref is the reference to the value.
new StrongReference(value);
 

Monday, January 2, 2012

Hibernate Entity Generation Using Ant

Why would someone like to generate the sources from ant if its very easily generated through the IDE. The answer is simple: In a development environment different developers will use different versions of eclipse which will result in slightly different entities being generated. To provide the consistency across the team its better to have a ant or maven to generate the sources rather than rely on ide tools configuration.

Its very simple to generate the sources from ant's build.xml.

lets go through step by step


Build.xml is the file that the Ant uses to build the project. It has different tasks which we can use to perform different actions like compile, making jars, making wars, deployment etc. We will be using build.xml to generate sources. Hibernate tools comes with a predefined task which is org.hibernate.tool.ant.HibernateToolTask which is present in hibernate tools jar. We will be using this task to generate the sources.

1 Write a hibernate configuration file (a xml file.) which provides with all the details which the hibernate will require to connect to database. Hibernate will require
Username: username of the database
Password: password of the database
Schema: The name of the schema of the database
Driver: The driver to the database. For oracle its oracle.jdbc.OracleDriver
Connection Url: The connection url with portnumber, protocol and hostname.
Dialect: The dialect. For oracle 10 with hibernate its org.hibernate.dialect.Oracle10gDialect

At the end it will look like below.
oracle.jdbc.OracleDriver
development

username
password
org.hibernate.dialect.Oracle10gDialect


2 Write a reveng file which is an xml file which says which table metadata to be taken and converted to source.
For example:



3 Create a strategy class for the generation of classes. This strategy class will define the template for the source file generated. We will define this file to customize our class generation. We use HibernateCustomStrategy for our strategy. By default Hibernate tools provides with its own implementation.
4 Create a build.xml with the target. The class name mentions which class to be evoked when running this task. We will be using the predefined class HibernateToolTask which is present in the hibernate-tools.jar. Class path ref is the reference to the class path. For example
Create a path element. This element says that all the jar files in the lib directory will be part of this path.








We will refer this path element in the classpathref like below.






in ant task to generate the xml mapping files and uncomment to generate the DAOs.
11 To run this build.xml you can choose to use command line or through an IDE.
11.1 To run from the command line go to the directory of the build file. Use ant to run the build.xml. Note: You should have ANT_HOME set in your environment variable.
11.2 To run from Eclipse. Change the view to ant view. And double click on the targetname.
12 Check in the for the generated source.

A simple Test Framework with example

It’s a very common requirement to have a testing framework of its own for an application to provide a capability that’s common to all the unit classes. Say, if you are building test classes to test the Rest based webservices you would like to have a framework that provides the capability to provide the creation of request in the form of URLs. The response can be either xml or json and we can provide our own implementation to validate the response that’s come in, so that for each unit test of services we don’t have to write a code in each test class to validate the response. I am suggesting a simple framework that provides the backbone for such a framework implementation. It’s not specific to a particular architecture but can be modified to use it for any architecture that user wants.

I am suggesting a kind of driver class to run all the tests. The driver class will be responsible to provide specific behaviors to the whole test application. Suppose you want to add the facility of creating the url ,as described in the above example for the rest based webservice, of the resource. You need to add that method or operation in this driver class.

Coming on to Driver class.

Our driver class is that of TestCase. It has two abstract methods ;
protected abstract void executeTest() throws Exception;
protected abstract void checkActualResults() throws Exception;
which will be extended by every TestCase to have the specific behavior of the application. The other class will be that of AllTests which uses the junit test suites to run all the tests.

I am giving the code for the TestCase and AllTest below.

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


public abstract class TestCase {

private String testName = "";

protected Map testConditions = new HashMap();
private Map expectedResults = new HashMap();
private Map actualResults = new HashMap();

public TestCase() {
}


public boolean isTestPass() throws Exception {
System.out.println("Test Case: " + this.getTestName());

this.executeTest();
this.checkActualResults();
this.syncResults();

boolean isMatch = this.isResultsMatch();
System.out
.println((isMatch ? "PASS: " : "FAIL: ") + this.getTestName());
return isMatch;
}


protected abstract void executeTest() throws Exception;


protected abstract void checkActualResults() throws Exception;


private boolean isResultsMatch() {
Iterator i = expectedResults.entrySet().iterator();
Map.Entry result;
while (i.hasNext()) {
result = (Map.Entry) i.next();
if (this.getExpectedResult(result.getKey()) != this
.getActualResult(result.getKey()))
return false;
}
return true;
}


private void syncResults() {
int exp = expectedResults.size();
int act = actualResults.size();
if (exp == act)
return;
Map.Entry result;
if (exp > act) {
Iterator i = expectedResults.entrySet().iterator();
while (i.hasNext()) {
result = (Map.Entry) i.next();
if (!actualResults.containsKey(result.getKey())) {
actualResults.put(result.getKey(), false);
}
}
} else {
Iterator i = actualResults.entrySet().iterator();
while (i.hasNext()) {
result = (Map.Entry) i.next();
if (!expectedResults.containsKey(result.getKey())) {
expectedResults.put(result.getKey(), false);
}
}
}
}

// reset all test conditions, and test results
public void initialize() {
testConditions.clear();
expectedResults.clear();
actualResults.clear();
}


public void setAllConditions(Object value) {
this.setMapValue(this.testConditions, value);
}


public void setAllExpectedResults(boolean value) {
this.setMapValue(this.expectedResults, value);
}

private void setMapValue(Map m, Object value) {
Iterator i = m.entrySet().iterator();
Map.Entry entry;
while (i.hasNext()) {
entry = (Map.Entry) i.next();
m.put(entry.getKey(), value);
}
}


public void setTestCondition(String key, Object value) {
testConditions.put(key, value);
}

public Object getTestCondition(String key) {
return testConditions.get(key);
}

public void setExpectedResult(String key, Boolean value) {
expectedResults.put(key, value);
}

public Boolean getExpectedResult(String key) {
return expectedResults.get(key);
}

public void setActualResult(String key, Boolean value) {
actualResults.put(key, value);
}

public Boolean getActualResult(String key) {
return actualResults.get(key);
}

public String getTestName() {
return testName;
}

public void setTestName(String testName) {
this.testName = testName;
}

}

AllTest will look like


import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;


@RunWith(Suite.class)

@SuiteClasses({LoginServiceTest.class })

public class AllTests {
}

An example of using this:

We have LoginService like this

public class LoginService {

public boolean isValid(String username, String password) {

if (username.equals("kanishka") && password.equals("vatsa"))
return true;
return false;
}

}

We develop the TestCase like this :

public class LoginServiceTestCase extends TestCase {


private LoginService loginService = new LoginService();
protected final String CONDITION_USERNAME = "userName";
protected final String CONDITION_PASSWORD = "password";

protected final String RESULT_IS_ERROR = "isError";

private boolean isError;

protected void checkActualResults() throws Exception {
setActualResult(RESULT_IS_ERROR, isError);
}

protected void executeTest() throws Exception {
try {
String userName = (String) getTestCondition(CONDITION_USERNAME);
String password = (String) getTestCondition(CONDITION_PASSWORD);
isError = !loginService.isValid(userName, password);
} catch (Exception e) {
isError = true;
}
}

}

We write the junit test case like :

public class LoginServiceTest {


LoginServiceTestCase loginTestCase = new LoginServiceTestCase();

@Before
public void setup() {
System.out.println(" in setup");
loginTestCase.initialize();
}

@After
public void teardown() {
}

@Test
public void testLoginWithValidAccount() throws Exception {
loginTestCase.setTestName("Validate Login with valid credentials");
loginTestCase.setTestCondition(loginTestCase.CONDITION_USERNAME,
"kanishka");
loginTestCase.setTestCondition(loginTestCase.CONDITION_PASSWORD, "vatsa");
loginTestCase.setExpectedResult(loginTestCase.RESULT_IS_ERROR, false);
assertTrue(loginTestCase.isTestPass());
}

@Test
public void testLoginWithEmptyCredentials() throws Exception {
loginTestCase.setTestName("Validate Login with empty credentials");
loginTestCase.setTestCondition(loginTestCase.CONDITION_USERNAME, "");
loginTestCase.setTestCondition(loginTestCase.CONDITION_PASSWORD, "");
loginTestCase.setExpectedResult(loginTestCase.RESULT_IS_ERROR, true);
assertTrue(loginTestCase.isTestPass());
}

@Test
public void testLoginWithInvalidCredentials() throws Exception {
loginTestCase.setTestName("Validate Login with invalid credentials");
loginTestCase.setTestCondition(loginTestCase.CONDITION_USERNAME,
"user");
loginTestCase.setTestCondition(loginTestCase.CONDITION_PASSWORD,
"password");
loginTestCase.setExpectedResult(loginTestCase.RESULT_IS_ERROR, true);
assertTrue(loginTestCase.isTestPass());
}
}

In the loginServiceTest class we are encapsulating the LoginTestCase instance hence we are delegating the responsibility to provide the application specific behavior(in our example the restful behavior) to the TestCase instance which will provide the behavior.

Hope you will like this simple but useful implementation. Looking forward for your comments.

Happy coding :)

Monday, December 19, 2011

Encrypting the password in the configuration files of MYBATIS

In the configuration file of ORM tools like hibernate , mybatis, jpa we have a common concern that the password of the database is exposed to each and every developer or whoever has the access to the code. It’s a great security concern for the enterprise which has the sensitive data in the database. So there comes the need to have an encrypted password in the configuration file and read it programmatically and make the decrypted password available to the application only at the run time. So that no one can read the password.
We can achieve this through any encryption codec algorithm providers like apache, sun and many more. I am demonstrating here using apache codec which is opensource library to encrypt and decrypt the password. I am demonstrating it for mybatis but the same can be achieved through similar process in hibernate or JPA.
We have a database properties file which contains all the database related properties like username, password, driver and url. The configuration file reads from this property file. We will be storing the password (in encrypted form in this property file) and while reading we will decrypt the password and give it to the builder for creating a sqlSession. To write to the database properties file we will use the command line argument to provide it with the properties file.
Lets have a look at the properties file:
driver=com.ibm.db2.jcc.DB2Driver
url=jdbc:db2://localhost:50000/CDR
username=db2admin
password=VXR!tre6g

Lets have a look at the configuration.xml file.

















]]>



Lets have a look at the PasswordService.java file which will write to the database.properties file and will have functions like encrypt and decrypt the password.
public final class PasswordService {
private static PasswordService instance;

public PasswordService() {
}

public synchronized String encrypt(String plaintext) throws Exception {
if(plaintext != null)
return new String(Base64.encodeBase64(plaintext.getBytes()));
return null;
}

public synchronized String decrypt(String plaintext) throws Exception {
if(plaintext != null)
return new String(Base64.decodeBase64(plaintext.getBytes()));
return null;
}
public static synchronized PasswordService getInstance()
{
if (instance == null) {
instance = new PasswordService();
}
return instance;
}
public static void main(String args[]){
try {
String encryped = getInstance().encrypt(args[0]);
Properties prop = new Properties();
InputStream in = ConnectionFactory.class.getResourceAsStream("prop.properties");
prop.load(in);
Properties databaseprop = PropsUtils.load(prop.getProperty("databasepropertiesfile"));
Enumeration e = databaseprop.keys();
while(e.hasMoreElements()){
String str = (String)e.nextElement();
if(str.equals("password")){
databaseprop.setProperty("password", encryped);
}
}
URL url = ClassLoader.getSystemResource(prop.getProperty("databasepropertiesfile"));
FileOutputStream fos =new FileOutputStream(url.getFile());
databaseprop.store(fos, null);
} catch (Exception e) {
e.printStackTrace();
}
}
}


Lets have a look at the ConnectionFactory.java file which will create the sqlSession.

public class ConnectionFactory {

private static SqlSessionFactory sqlMapper;
private static Reader reader;
static {
try {
Properties prop = new Properties();
InputStream in = ConnectionFactory.class.getResourceAsStream("prop.properties");
prop.load(in);
Properties databaseprop = PropsUtils.load(prop.getProperty("databasepropertiesfile"));
String encrypedPassword = databaseprop.getProperty("password");
String password = PasswordService.getInstance().decrypt(encrypedPassword);
databaseprop.setProperty("password", password);
String conf =prop.getProperty("configurationfile");
reader = Resources.getResourceAsReader(conf);
sqlMapper = new SqlSessionFactoryBuilder().build(reader,databaseprop);

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

public static SqlSessionFactory getSession() {
return sqlMapper;
}
}

Lets have a look at the PropUtils.java file

public class PropsUtils {
private PropsUtils() { }
/**
* Load a properties file from the classpath
* @param propsName
* @return Properties
* @throws Exception
*/
public static Properties load(String propsName) throws Exception {
Properties props = new Properties();
URL url = ClassLoader.getSystemResource(propsName);
props.load(url.openStream());
return props;
}

/**
* Load a Properties File
* @param propsFile
* @return Properties
* @throws IOException
*/
public static Properties load(File propsFile) throws IOException {
Properties props = new Properties();
FileInputStream fis = new FileInputStream(propsFile);
props.load(fis);
fis.close();
return props;
}
}

Tuesday, December 6, 2011

Encapsulating the subclass creation in superclass

One of the common mistake that the programmers make it to instantiate the subclass directly rather than by the common interface. Lets explain it by a simple example. Say you have Animal , Tiger, Lion, Mouse and Bird as the classes. When you will design you will make Animal as the super class and Tiger, Lion, Mouse and Bird as its subclasses. Say Tiger has its own constructor. The client instantiate using
Tiger tig = new Tiger();
What is wrong with this? According to design principle one should always program to an interface. Something like this
Animal tig = new Tiger();
But why ? The basic reason for that is once developers write code that’s talks directly to the subclass type rather than through its common interface then its common tendency to change the subclass code in response to the needs of the client. And this will result into a number of special cases logic in the subclasses and will lead to maintenance problem.
How to restrict this ?
The answer to this is to encapsulate the creation of subclasses in the superclass. Something like this in the Animal abstract class add a method like
public abstract class Animal {
public Animal (){}
public static Animal createTiger(){return new Tiger()}
}
In Tiger subclass do something like this
public class Tiger{
protected Tiger(){}
}
What we have done is to modify the constructor of Tiger to provide it with protected access and have a creation method in the Animal. This will solve a lot of problem regarding the maintenance of code in the future.

Thursday, June 7, 2007

Comparing Hibernate and JDBC (time issues)

I used JFluid(Performance Analysis tool) for my web application
Contact management.
The product uses Hibernate to interact with the database.
As an example I will take Hibernate methods and some statistics
to compare it with simple JDBC.

On the console when I started the server the output was this.




It has all the methods that the tomcat needs to start up. The profiling is perfect. It has four columns. The first column tells about the method name. The second one tells about the % of total time. The third one tells about the time in absolute terms and fourth one tells about the invocation time in absolute terms.

Now coming on the actual implementation.





In this picture one thing that is worth noting that the hibernate internally does not take as much of the time as the apache Catalina loader and other apache functionalities. Even the so called expensive process of creation of sessionFactory (87 ms this takes into account the time taken to read the configuration file and the time taken to build the factory.) taking no time in comparison to the server methods. But it takes comparatively higher times in comparison to other methods like getNamedQuery ( double the time than this 54ms ) and other methods like getterMehods (34 ms) still lesser time.

Now coming on to Hibernate specific methods.

We will divide the work of hibernate in three different categories.

· Loading of Configuration . It will include reading from the XML file, loading the mapping and getting the methods to deliver the result.

· Interaction with the database. It will include the creation of connection with the sql and the time taken to query and creation of tables.

· Displaying the result.

Before we take a dip into the categories I would like to say that the first category took around 0.75 times the time taken by second category. This can change drastically if we increase the number of users. Though the schema update time won’t change. The third category is not even in contention.

Among the categories that are listed above the time taken by the different category is

Coming onto the first category.

In the first category when we take out the methods those took the maximum amount of time are listed in the next paragraph.

The init() method of org.hibernate.cfg.Configuration() which is used to upload the configuration given in the hibernate.cfg.xml takes 2.9 ms. The add method of the same class takes 13.7 ms. The building of factory takes 5.62 ms and creationMapping() took 1.32 second. Rest all the processes took less than 1 ms. Creation of session(0.012ms) out of sessionFactory did not take much time ( as per the expectation., session is lightweight object) . So putting the creation of sessionFactory in the Plugin is the step in the right direction.

Moving onto the second category.

The second category mainly consists of one time process of dialect upload , creation of Connection and multiple time processes of query translation, sqlgenerator from HQL and fetching of data from the tables.

One time process of connection creation takes in total of 23 ms. The amount of time is spent in dialect upload ( that is equivalent of loading the driver in JDBC) is 43ms. Which compares badly with the direct JDBC Driver loading. Even the creation of connection takes more time than the usual JDBC connection creation.

This statistics can put Hibernate lover to think once again for the application where the time is important parameter. The other big demerit of Hibernate is the translation of HQL to sql that also takes 12 ms which can be saved in case of JDBC. Fetching data once the sql has been generated would take the same amount of time.

Sunday, May 20, 2007

Plugins in Struts (Writing HibernateUtil Plugin)

In this blog i will take a real life example where the plugins from the struts can be useful.

First have a overview of what we are going to do.

Let us take a scenario. We are using Hibernate with Struts. In hibernate, the very first step that we do is to create a Configuration object. This Object inturns build SessionFactory object, which is responsible for creating Sessions. Anyone having even a iota of interest in Hibernate must be knowing Session is the object that performs all the tasks like persisting, creating Transation etc. SessionFactory is a bulky object. It will consume a lot of resources in creating a SessionFactory object. So it is preferable if we create this object only once and reuse it in the whole application. Just like what Singelton offers. If we are using Struts with Hibernate, this can be accomplished by writing a plugin that builds SessionFactory object.

Now look at what is Plugin in Struts.

In addition to the three classes (ActionServlet, Action and RequestProcessor) Struts provides another way to define your controller. These are Plugins. Struts Plugins are modular extensions to the Struts Controller. They have been introduced in Struts 1.1, and are defined by the org.apache.struts.action.Plugin interface. Struts Plugins are useful when allocating resources or preparing connections to databases or even JNDI resources.

This interface, like the Java Servlet architecture, defines two methods that must be implemented by all used−defined Plugins: init() and destroy(). These are the life−cycle methods of a Struts Plugin. The init() method of a Struts Plugin is called whenever the JSP/Servlet container starts the Struts Web application containing the Plugin. It has a method signature as follows:


public void init(ActionServlet servlet, ModuleConfig config) throws ServletException {


}

This method is convenient when initializing resources that are important to their hosting applications. As you will have noticed, the init() method receives an ModuleConfig parameter when invoked. This object provides access to the configuration information describing a Struts application. The init() method marks the beginning of a Plugin’s life.

Then there is destroy() method. This method marks the end of a Plugin’s life. It is used when you want to purposely close the connection or fluch something out of the buffer. The destroy() method of a Struts Plugin is called whenever the JSP/Servlet container stops the Struts Web application containing the Plugin. It has a method signature as follows:

public void destroy();

Till now i am sure you must have got what is Plugin in Struts. Now look at the programming aspect of it.

Creating a Plugin

Plugin is always created by implementing the interface Plugin. The signature will look like this.


import org.apache.struts.action.PlugIn;
//One has to import plugin to make it available to the implemanting class.

public class HibernateUtilPlugin implements PlugIn{


private static String _configFilePath = "/hibernate.cfg.xml";

// Gives the path of configration file. In my case it is stored in the directory where the class //files are

public static final String SESSION_FACTORY_KEY
= SessionFactory.class.getName();

private SessionFactory _factory = null;

// Initializes the SessionFactory object

private static SessionFactory factoryTest = null;

public void destroy() {
try{
_factory.close();
}catch(HibernateException e){

}

}

public void init(ActionServlet servlet, ModuleConfig config) throws ServletException {

// This method will be called only once. What we are doing is creating a SessionFactory object //here. Init is called when ever the container is initialized with the client request.


Configuration configuration = null;
URL configFileURL = null;
ServletContext context = null;

try{
configFileURL = HibernatePlugin.class.getResource(_configFilePath);
context = servlet.getServletContext();
configuration = (new Configuration()).configure(configFileURL);
_factory = configuration.buildSessionFactory();

//Set the factory into session

context.setAttribute(SESSION_FACTORY_KEY, _factory);

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

}

}

/**
* Setter for property configFilePath.
* @param configFilePath New value of property configFilePath.
*/

public void setConfigFilePath(String configFilePath) {
if ((configFilePath == null) || (configFilePath.trim().length() == 0)) {
throw new IllegalArgumentException(
"configFilePath cannot be blank or null.");
}


_configFilePath = configFilePath;
}

public static SessionFactory getFactory() {


Configuration configuration = null;
URL configFileURL = null;
if(factoryTest == null) {
try{

configFileURL = HibernatePlugin.class.getResource(_configFilePath);
configuration = (new Configuration()).configure(configFileURL);


factoryTest = configuration.buildSessionFactory();
//the creation of the sessionFactory.


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

}

}
return factoryTest;

}


}
}


This program will create the SessionFactory object which can be used again and again by the application.


But the task is incomplete. We will have to say the Struts that we have a plugin. The best place to do so will be the struts-config.xml file. This can be done by






Hope i am clear for the purpose of why plugin is used and how it can be used. Any question can be directed to kanishkavatsa@hotmail.com