Thursday, April 26, 2007

Long-running Processes with Spring DAO and Hibernate

Spring and Hibernate are increasingly used together in Java web applications. Spring is used as the MVC and dependency-injection framework and also provides support for data access, transaction management etc. Hibernate is usually used alongside Spring as the object-relational mapping framework. Spring's support for Hibernate is impressive through it's DAO templating mechanism. This truly simplifies matters as all the routine infrastructure plumbing code is taken care of by Spring.

Spring intercepts requests made to the webapp and through dependency-injection makes objects available in order to fulfil the request. This includes creating the Hibernate Session object used by the DAOs. The Session object is lightweight and created and destroyed for every request. Hibernate sessions are not threadsafe and should be used by only one thread at a time. In order to keep the session open throughout the lifetime of a request we tie it to the view. This is done either by using Spring's OpenSessionInViewInterceptor or OpenSessionInViewFilter as below:

<bean id="openSessionInViewInterceptor" 
    class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
    <property name="sessionFactory" ref="sessionFactory" />
    <property name="flushModeName" value="Flush_AUTO" />
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    ...
</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    ...
</bean>

Most requests are synchronous and completed before the response is returned to the client. However, in the case of long-running processes, a new thread is created for execution of the process. The response is returned back to the client and the process runs independently on the server. Hibernate sessions obtained through OpenSessionInViewInterceptor are no longer available to the process as they are closed once the view has returned. This throws a LazyInitializationException complaining that the owning session was closed.

The problem can be overcome by directly accessing the Hibernate SessionFactory bean and binding the session to the long-running process thread. Hence the session is available and open within the thread itself. The UML diagram below describes our objects.

TestController is the Controller class that handles the request. Since it implements the ServletContextAware interface, Spring automatically passes the ServletContext object to it. This is used to obtain the ApplicationContext object. Next we create an instance of our LongProcessInvoker class, pass ApplicationContext to it and finally start execution using an Executor.

// TestController.java
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
    try {
        ApplicationContext ac = 
            WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
            
        LongProcessInvoker lpi = new LongProcessInvoker();
        lpi.setApplicationContext(ac);
            
        Executor ex = Executors.newSingleThreadExecutor();
        ex.execute(lpi);
    }
    catch(...) {
        ...
    }
}

In LongProcessInvoker we obtain the Session using SessionFactoryUtils and bind it to the current thread. Next the long running process is invoked and once complete we execute some clean-up code by releasing and closing the Session.

// LongProcessInvoker.java
public void run() {
    try {
        // Bind session object. 
        SessionFactory sessionFactory = 
            (SessionFactory) applicationContext.getBean("sessionFactory");
        Session session = SessionFactoryUtils.getSession(sessionFactory, true);
        TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));        
        
        LongProcess lp = (LongProcess) applicationContext.getBean("longProcess");
        lp.runLongProcess();
        
        // Release session object.
        session.flush();
        TransactionSynchronizationManager.unbindResource(sessionFactory);
        SessionFactoryUtils.closeSession(session);
    }
    catch(...) {
        ...
    }
}

Using the above approach, we can now run long-running processes by obtaining the Hibernate session outside the view.

Thursday, April 12, 2007

Loading Log4j Properties in Webapps on Tomcat

Log4j is a well established and widely used logging framework for the Java platform. At the core of Log4j lies a configuration file that allows to finely configure the logging requirements for an application. Currently, the configuration file is either a XML or Java properties file. The documentation states that this configuration file should be present in the classpath of the application. This works fine for most situations however causes problems within webapps on Tomcat.

The Log4j FAQ describes this due the way in which JavaEE and Servlet containers utilize Java's class loading system.

The problem can be overcome by using Log4j's PropertyConfigurator. PropertyConfigurator enables to statically load the configuration from an external file. Using the configure(String configFilename) method we can manually specify the path to the properties file within the webapp. We can tie this code into a ServletContextListener's contextInitialized(ServletContextEvent sce) event to force the properties file to be loaded at webapp startup.
Our ServletContextListener implementation is listed below:

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.log4j.PropertyConfigurator;

public class ServletContextListenerImpl implements ServletContextListener {
    public void contextDestroyed(ServletContextEvent sce) {

    }

    public void contextInitialized(ServletContextEvent sce) {
        String path="WEB-INF/classes/log4j.properties";
        ServletContext context = sce.getServletContext();
        PropertyConfigurator.configure(context.getRealPath(path));
    }
}

Our Log4j properties file should now be successfully loaded when the webapp is initialized.

Friday, March 30, 2007

Secure Email Attachments with TrueCrypt

Digital documents have finally come of age. We now increasingly receive our bank statements, insurance quotes and receipts as digital files such as Word or PDF. Also, there is often a need to attach these documents to an email. Securing these attachments in transit over the Internet is an immediate concern. There are a number of solutions available such as Hushmail, a secure free email provider and PGP Desktop Email, a commercial email encryption product. The solution that I discuss here is based on a free, open-source encryption software called Truecrypt.

Truecrypt makes using bullet-proof encryption really easy through the concept of virtual encrypted disks. Each disk is stored as a single encrypted file and can be mounted as a real disk. Once mounted, it can be used as a local drive on the system. Entire hard-drives or USB memory sticks can be encrypted as well. Volumes can be protected using a password or through key files. Any file on the system can be used as a key file as an alternative or in addition to using a password. The key file or sequence of key files is required to encrypt and decrypt the disk.

The concept of key files makes using Truecrypt really valuable while sending sensitive attachments over email. In addition to using a password, if the sender and the receiver agree on a common file or a sequence of files that are uniquely present on both systems such as digital photographs or video clips, the encryption can be made highly secure. Hence the encrypted attachments are useless if intercepted during transit without the key files.

Truecrypt is extremely simple to use and hence there is just no excuse for not securing confidential files on storage or in transit.

Saturday, November 18, 2006

Windows Vista - Features Under the Hood

Windows Vista introduces some promising new features that aim to take desktop computing to the next level. Apart from all the eye-candy that is provided by the new Aero interface, gadgets and flip effects, there are some pretty neat features on offer under the hood. Some of these add improvements to the performance, security and productivity of the system.

Below are some of the features that I am really looking forward to in Vista.

ReadyBoost
Memory is usually one of the bottlenecks that affects system performance. As applications and background processes like anti-virus scans and drive indexing run concurrently, processor cycles and memory space are increasingly consumed. The result can be a drastic degradation in system performance. It would be great if memory could be added on the fly, providing extra space to ease the burden. Vista's ReadyBoost does just that.

With ReadyBoost, a USB memory drive with at least 512 MB of space can be plugged into the system and used by Vista as memory. The drive can be plugged out at any time without affecting or corrupting the system. Even more, all data on the drive is encrypted and hence is of no use to a malicious attack. With 2GB+ memory drives available today, this seems like a very promising technology.

BitLocker
Security of data is a primary concern these days to businesses and individuals alike. Regular reports of data theft, especially from notebook computers being stolen fuels our concerns. BitLocker is a technology that adds real-time data encryption to the Operating System volume. Hence lost or decommissioned computers are protected from data theft.

BitLocker which is available in the higher-end versions of Vista has some system prerequisites. A TPM (Trusted Platform Module), a cryptographic hardware chip needs to be present in the system. In the absence of a TPM, a USB stick that contains a startup key must be inserted at boot time.

ReadyDrive
Another new feature that exploits the latest developments in hardware is ReadyDrive. ReadyDrive makes use of hybrid hard drives, the latest hard drives that integrate non-volatile flash memory with traditional drives. This helps Windows to boot faster, resume from hibernation quicker and save on battery power. Finally the long wait for the boot process will be rather short!

Tuesday, November 07, 2006

100% CPU!

I have been doing some heavy-duty image processing on my computer at work this morning and it's pushing my machine to the max! Looking at the performance graph, I was amazed to see my CPU crunching away going steadily at 100%. Looks like it's time to convince my boss to get me one of those shiny new quad-core chips from Intel...

From

Tuesday, September 26, 2006

Backup for a Rainy Day!

We all know that backups are important! However, most users realize the importance of backups only after lightning strikes. We need to protect our data from the usual suspects such as hard disk crashes, fire, floods, theft etc. I have been using a free tool from Microsoft called SyncToy that makes running backups an ease. This post describes the backup procedure using SyncToy.

Note: Windows XP Professional comes with an out-of-the-box Backup utility. This utility produces a single backup file (.bkf) that could be later used to restore data and system settings. I prefer using SyncToy as it creates an exact replica of the directory and file structure. Thus the backed-up copy can also be used as a read-only reference when away from the source computer.

Steps to Getting Backups Up and Running 1. Centrally arrange data for easy backups. 2. Get an external USB hard drive. 3. Download and install Microsoft SyncToy. 4. Run SyncToy to backup your data. 5. Create a backup schedule. 6. Store the external hard drive safely.

1. Centrally arrange data for easy backups.
The first thing to do is to arrange our data centrally, preferably in a single hard drive partition or folder to facilitate easy backups.

2. Get an external USB hard drive.
There are a number of options available to store backed up data. These range from CD-Rs, DVD-Rs, USB sticks, external USB hard drives, SAN drives etc. I personally prefer USB hard drives as they are fairly inexpensive, easy to use, mobile and have significant storage capacities.

3. Download and install Microsoft SyncToy.
Once installed, setting up a backup job is pretty straightforward. Start by creating a 'New Folder Pair' (Screenshot). After specifying the source and destination folders we need to specify the synchronization action. This needs to be 'Echo' in our case (Screenshot). Using Echo, new and updated files are copied across and renames and deletes are repeated on the backup. One point to note is that Echo does not delete directories on the backup. Our backup job is now ready to run!

4. Run SyncToy to backup your data.
Running the SyncToy backup is an easy process. Select the relevent folder pair from the list at the left side of the main window and then click 'Run' (Screenshot). A progress bar apprears showing the advancement of the process.

5. Create a backup schedule.
Backups are valuable only when they are run regularly! We can automate this process by creating a Scheduled Task in Windows. This can be accessed at Start -> All Programs -> Accessories -> System Tools -> Scheduled Tasks. The wizard is simple to follow (Screenshot). To run our backup job, add -R "<folder-pair_name>" to the end of the Run command. To run all folder pairs just add -R.

6. Store the external hard drive safely.
Once we have a backup schedule in place it makes sense to store the backup drive at a separate geographic location to the source. This proves essential in times of natural calamities such as fire, floods, theft etc.

Thanks to SyncToy we now have a backup procedure in place!

Wednesday, September 13, 2006

Spring MVC and AJAX with JSON

One of the main decisions to be taken while developing AJAX applications is the format of messages passed by the server to the client browser. There are many options to choose from including plain text, XML, CSV etc. One of the more popular choices today is the JavaScript Object Notation (JSON). JSON provides a nice name-value pair data format that is easy to generate and parse. This is especially true when using an AJAX toolkit like Dojo that provides built-in functionality to parse JSON messages at the client. If you are using Spring MVC as your web framework, generation of these JSON messages is very straight-forward as well. Below we understand how to produce JSON messages while using Spring MVC.

Spring MVC defines the View interface to render views to the client. The framework provides a number of implementations including JstlView, RedirectView, TilesView etc. In order to return JSON messages we implement the View interface to create a new class that returns data formatted using the JSON notation. We shall call this class JSONView.

The method that we need to implement is render(Map model, HttpServletRequest request, HttpServletResponse response). The render method accepts a Map as it's first parameter and produces the output. We could manually iterate through the Map, process and produce the JSON output. However, there is a Java library called JSON-lib that produces the JSON notation. The code below shows our JSONView class that can be used as a Spring MVC View to return JSON output to the client.

import java.io.PrintWriter;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
import org.springframework.web.servlet.View;
 
public class JSONView implements View {
    public void render(Map map, HttpServletRequest request,
    HttpServletResponse response) throws Exception {
        JSONObject jsonObject = JSONObject.fromMap(map);
        PrintWriter writer = response.getWriter();
        writer.write(jsonObject.toString());
    }
 
    ...
}

As can be seen from the code above, Spring exploits MVC to it's full potential and provides the flexibility to tailor the view to exactly suit our needs.