Hamid Fadishei's Blog

January 5, 2010

Spring Load-time Weaving on Tomcat: Does It Really Work?

Filed under: Java,Spring,Tomcat — fadishei @ 5:44 am

Are you frustrated in making the Spring load-time weaving (LTW) work on Tomcat application server? Then keep reading as the process is explained below.

Inversion of Control

Spring is an “Inversion of Control” (IoC) container. IoC lets the developers of a class (bean) relax from thinking how to satisfy the dependencies for the class. Dependencies will be “injected” into the bean by the container.  For example, a bean may need to be a client of a web service. Then the developer does not have to think about how to get the stub for the web service. The only thing he has to do is to provide a means to get the dependency from the container, for example by providing the container with a property setter for the stub, and take it for granted. More information about IoC and DI can be found here.

Load-Time Weaving

Sometimes, your beans are created outside of the container. Then, the framework can not simply inject their dependencies. One solution is to get the dependencies yourself by making your bean “application-context-aware”. However, this will result in foregoing the IoC. Another solution is to make your bean @Configurable and use weaving to inject the dependencies at load-time, or at compile-time. More information on LTW in Spring can be found here.

The Environment

Spring framework has recently released the stable 3.0 version. I use this version in this tutorial, along with Tomcat 6.0 as the applications server. The source code as an Eclipse project can be found here. This is a very simple web application which will say hello to a name that is specified as a bean property in the spring context. The property will be injected using load-time weaving.

Step 1- Project Dependencies

The needed libraries for running the example:

aspectjweaver-1.6.7.jar
commons-logging-1.1.1.jar
log4j-1.2.15.jar
spring-asm-3.0.0.jar
spring-aspects-3.0.0.jar
spring-beans-3.0.0.jar
spring-context-3.0.0.jar
spring-core-3.0.0.jar
spring-expression-3.0.0.jar
spring-transaction-3.0.0.jar
spring-web-3.0.0.jar

Step 2- Make the Bean Configurable

This code shows how I made my ultra-simple Person bean configurable:

package ir.fadishei.test.ltw;

import org.springframework.beans.factory.annotation.Configurable;

@Configurable
public class Person
{
	private String name;

	public String getName()
	{
		return name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public String toString()
	{
		return name;
	}
}

Step 3- The Spring Context

Here is the simplistic configuration:

<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop
		http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context.xsd">

	<context:spring-configured />
	<context:load-time-weaver aspectj-weaving="autodetect"/>

	<bean class="ir.fadishei.test.ltw.Person" scope="prototype">
		<property name="name" value="Timon"/>
	</bean>

</beans>

Step 4- Change the Tomcat Class Loader

Somtimes people fail to make LTW work on Tomcat by missing this step. The default Tomcat class loader does not support class transformation. You’ll need to use the one provided by Spring. First you should copy the spring.instrument.tomcat-3.0.0.jar to the lib folder of your tomcat installation. then use this context.xml to tell the web application server to use the new class loader:

<Context path="/ltwdemo">
    <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>

Step 5- Run

Run the web server and browse the following page. You should see the Hello <name>! message, in which name should be what provided in the bean definition.

http://localhost:8080/ltwdemo/

The source code of this tutorial as an Eclipse project

Advertisements

January 4, 2010

Hello world!

Filed under: Uncategorized — fadishei @ 4:06 pm
public class Hello
{
	public static void main(String args[])
	{
		System.out.println("hello");
	}
}

Blog at WordPress.com.