Archive for October, 2009

29
Oct
09

Standard XML headers

The following page describes standard xml headers for common frameworks.

 

Spring Framework

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC
	"-//SPRING//DTD BEAN//EN"
	"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<!--your xml goes here-->	
</beans>

Spring Core with annotations

<?xml version="1.0" encoding="UTF-8"?>

<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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!--your xml goes here-->	
</beans>

web.xml

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

28
Oct
09

Using Annotations to Autowire beans in the Spring Framework

The new features of the Java 5 framework include Annotations. Annotations is a sort of meta-data about classes. These new Java 5 feature allow the developer to describe additional information about java classes methods and fields. This additional metadata can be used to generate boilerplate code used to configure the application at runtime.

Spring Framework and XML

If you have worked with the spring framework long enough you get to know that a lot of configuration is xml based. While this is great for very large application it can get to be a hassle for small project. Also if you are creating a rapid proto-type you want your codeing experience to be free-flowing. You dont really want to create a class and then have to write xml code inject it into another class.

In the following tutorial we will cover the basics of how to create a simple standalone spring application that will auto-wire itself with very little xml configuration. Spring XML configuration will be 2-3 lines of code  (not including the header).

Start a new project

mvn archetype:generate -DarchetypeArtifactId=maven-archetype-quickstart

Answer the rest of the questions like this:
Group ID: com.test
Artifact Id: springAnnotation

cd springAnnotation

We first start out by creating a plain old Java Application in the eclipse project. You can go ahead and create one and put a Maven 2 pom.xml file seen below.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.test</groupId>
	<artifactId>springAnnotation</artifactId>
	<packaging>jar</packaging>
	<version>1.0-SNAPSHOT</version>
	<name>springAnnotation</name>
	<url>http://maven.apache.org</url>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.0.2</version>
				<configuration>
					<source>1.5</source>
					<target>1.5</target>
				</configuration>
			</plugin>
		</plugins>
	</build>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring</artifactId>
			<version>2.5.5</version>
		</dependency>
	</dependencies>
</project>

Regenerate the project

Regenerate the project in eclipse by typing: mvn eclipse:clean eclipse:eclipse

Annotation Based configuration

Create the resources folder if it does not exist. and create the applicationContext.xml file.

src/main/resources/applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
 
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
 
http://www.springframework.org/schema/context
 
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
    
    <context:annotation-config/>

	<context:component-scan base-package="com.test"/>
 
</beans>

@Required

Indicates that this field is required to be injected. If this bean did not get injected by the time the injection step completes then the container shuts down and prints an error message.

@Autowired or @Resource (JSR-250) method

Used on setters to auto inject dependencies into beans. Prefer using @Resource because it is a Java Standard.

@Qualifier

Used for fine tuning of what gets selected for injection.

Example Application

src/main/java/com/test/ClassA.java

package com.test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.stereotype.Component;

@Component("classAA")
public class ClassA {
	private IClassB classB;

	public IClassB getClassB() {
		return classB;
	}
	@Autowired
	@Required
	public void setClassB(IClassB classB) {
		this.classB = classB;
	}

}

src/main/java/com/test/ClassB.java

package com.test;

import org.springframework.stereotype.Component;

@Component
public class ClassB implements IClassB {

	public void testMethod() {
		System.out.println("\n\n\nSpring Annotations are Easy!!!\n\n\n");
	}
}

src/main/java/com/test/IClassB.java

package com.test;

public interface IClassB {
	public abstract void testMethod();
}

The following is a test class that will print the results to the console.

src/test/java/com/test/AppTest.java

package com.test;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.util.CollectionUtils;

public class AppTest extends TestCase {
	public AppTest(String testName) {
		super(testName);
	}

	public static Test suite() {
		return new TestSuite(AppTest.class);
	}

	public void testApp() {
		ApplicationContext context = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		System.out.println(CollectionUtils.arrayToList(context
				.getBeanDefinitionNames()));
		ClassA classA = (ClassA) context.getBean("classAA");
		classA.getClassB().testMethod();
	}
}

Run the test

At the root directory for the project type the following.

mvn test

This should print out the following to the console:

[org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalRequiredAnnotationProcessor, classAA, classB]



Spring Annotations are Easy!!!



Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.338 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 second
[INFO] Finished at: Sun Jun 06 22:03:36 EDT 2010
[INFO] Final Memory: 15M/159M
[INFO] ------------------------------------------------------------------------

Component Scanning

In the previous section we reviewed how to inject beans that are already defined in the application Context injected into new beans using @Autowired or @Resource.

In this section we will go over how those beans got into the application context in the first place.

The magic starts with specifying a comma separated list of packages that will be scanned for Annotations. Put the following line into the spring configuration file.


<context:component-scan base-package="test"/>

The system will scan the test package for components that should be added to the application context. There is no need to define them in an xml file. You do need to put the following annotation at the class level so they get recognized.

Component Scan Annotations

@Repository – this was added as part of Spring 2.0 to indicate that this class serves the role of a datamanager or DAO.
@Component - this annotation indicates that this class is a general purpose spring managed bean. The @Repository, @Service, and @Controller are specializations of this base bean. You can always use @Component for all beans, but its not a good idea.
@Service – this annotation indicates that this is a class that contains Business Logic and serves as the Service/Model bean.
@Controller – Typically indicates that this class is used as a Controller in a Web Application.

Naming Component Scanned Beans

By default unless other wise specified a bean name will be the same name as the class however the first letter will not be capatalized. For example the following class will appear as movieFinderImpl

@Repository
public class MovieFinderImpl implements MovieFinder {
//...
}

If you want to specify a custom name for a bean all you need to specify is the following and the bean will be known as specialMovieFinder in the spring container.

@Repository("specialMovieFinder")
public class MovieFinderImpl implements MovieFinder {
//...
}

Constructor Injection

If your beans use constructor injection instead of setter injection you can still use annotations. Just use the @Qualifier annotation for each constructor parameter.

@Component("classAA")
public class ClassA {
    private IClassB classB;
 
    public IClassB getClassB() {
        return classB;
    }

    @Autowired
    public ClassA(@Qualifier("classB") IClassB classB) {
        this.classB = classB;
    }
}

Scalar Values

At this moment it does not look like you can specify scalar values based on annotations. But after a few minutes of thinking this thru, why would you want to? You can always set the scaler value in the constructor or where you are defining the attributes. With spring 3 you may use @Value annotation.

28
Oct
09

Maven for Eclipse IDE Platform Developers

Maven is a great build tool. There are many resources out there describing this topic in detail. There are many examples of how to generate eclipse projects on this site however they cover the more advanced cases. This page describes how to generate a simple standalone project using a simple pom.xml file.

Quick History about Maven

Maven was originally started as an attempt to simplify the build processes in the Jakarta Turbine project. The developers of the Turbine project thought that this tool can be used to build any project and worked on generalizing it for use by the general development community.

A complete description about Maven is available here

Maven is used to Generate Eclipse Projects

On this site I use Maven to generate eclipse projects. The advantage for doing it this way is that the projecs are uniform no matter what platform they are on. Since the dependencies are well documented within the Maven’s main config file called pom.xml you dont need to worry yourselves with downloading them from third party websites.

A typical project will start by you the developer creating a new project. The second step is to place a pom.xml file (seen a the end of the post) into the main directory of the project. Then you will drop the command line and cd to the project’s folder and type mvn eclipse:clean eclipse:eclipse

Before you can start generating your own eclipse projects you need to install Maven. Please follow the instructions

Once that is complete you need to execute the following command

mvn -Declipse.workspace=<path to your workspace> eclipse:add-maven-repo

Once installation of maven is complete you can continue and create the pom file.
The following is the pom.xml file that was used to generate the above project

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>test</groupId>
	<artifactId>TestProject</artifactId>
	<packaging>jar</packaging>
	<version>1.0.1-SNAPSHOT</version>
	<name>TestProject</name>

	<build>
		<sourceDirectory>src</sourceDirectory>
		<resources>
			<resource>
				<directory>src</directory>
			</resource>
		</resources>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.0.2</version>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-eclipse-plugin</artifactId>
				<configuration>
					<downloadSources>true</downloadSources>
					<downloadJavadocs>true</downloadJavadocs>
				</configuration>
			</plugin>
		</plugins>
	</build>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring</artifactId>
			<version>2.5.5</version>
		</dependency>
	</dependencies>
</project>

cd /workspace
mvn eclipse:clean eclipse:eclipse

verma@verma-desktop:~/workspace/TestProject$ pwd
/home/verma/workspace/TestProject
verma@verma-desktop:~/workspace/TestProject$ mvn eclipse:clean eclipse:eclipse
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'eclipse'.
[INFO] ------------------------------------------------------------------------
[INFO] Building TestProject
[INFO]    task-segment: [eclipse:clean, eclipse:eclipse]
[INFO] ------------------------------------------------------------------------
[INFO] [eclipse:clean]
[INFO] Deleting file: .project
[INFO] Deleting file: .classpath
[INFO] Deleting file: .wtpmodules
[INFO] Deleting file: .component
[INFO] Deleting file: org.eclipse.wst.common.component
[INFO] Deleting file: org.eclipse.wst.common.project.facet.core.xml
[INFO] Deleting file: org.eclipse.jdt.core.prefs
[INFO] Deleting file: org.eclipse.ajdt.ui.prefs
[INFO] Preparing eclipse:eclipse
[INFO] No goals needed for project - skipping
[INFO] [eclipse:eclipse]
[INFO] Using Eclipse Workspace: /home/verma/workspace
[INFO] no substring wtp server match.
[INFO] Using as WTP server : Apache Tomcat v6.0
[INFO] Adding default classpath container: org.eclipse.jdt.launching.JRE_CONTAINER
[INFO] Resource directory's path matches an existing source directory. Resources will be merged with the source directory src
[INFO] Wrote settings to /home/verma/workspace/TestProject/.settings/org.eclipse.jdt.core.prefs
[INFO] Wrote Eclipse project for "TestProject" to /home/verma/workspace/TestProject.
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 second
[INFO] Finished at: Wed Oct 28 21:31:31 EST 2009
[INFO] Final Memory: 20M/437M
[INFO] ------------------------------------------------------------------------

Return to eclipse and click refresh on the project. You will now have a fresh new project with all the dependencies in the build classpath of the project. You will not need to download those from third party websites. Maven will retrieve them from the central Maven repository.

Screenshot-Properties for TestProject

The text of the whole book that describes Maven is available online.

click here to view the site

That’s all for now!

27
Oct
09

Ibatis 2.3 spring 2.5 Hello World

This page describes a very simple HelloWorld type application being created so that it can be used as a base for more complex projects.

We start out with adding this to an already created pom.xml file.

		<dependency>
			<groupId>org.apache.ibatis</groupId>
			<artifactId>ibatis-sqlmap</artifactId>
			<version>2.3.4.726</version>
		</dependency>

If you have not done so already add the jdbc drivers for your database. In my case I am using mySQL.

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.9</version>
		</dependency>

regenerate the eclipse project:
mvn eclipse:clean eclipse:eclipse

REturn back to eclipse and refresh the project.

IBatis Main Configuration File

We first start with defining the main configuration file for the Ibatis framework. If you are working with a web application this is typically your WEB-INF folder. If you were using ibatis as a standalone framework you would have needed to put additional configuration entries in this file. However since we are using this with the state of-the-art dependency injection functionality provided by the spring framework.

MappersConfig.xml currently contains the locations of all the xml configuration files of all the individual sqlMap files.

MapperConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig
        PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
        "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
    <sqlMap resource="com/vermatech/electronics/repository/ItemDataManager.xml"/>
</sqlMapConfig>

SQL Maps configuration files

Each SQL MAp resource specifies a set of sql statements that may be run against an entity. Inserts, updates, deletes etc are specified within XML syntax. In addition to SQL Statements you may specify additional attributes like how long you want the statements to cache. Aliases may be defined for class names. REsults map for returned results and parameter map for parameters.

Parameters Maps and Result Maps

Here is an example that uses parameters map and results maps explicitly

<typeAlias alias=”product” type=”com.ibatis.example.Product” />
<parameterMap id=”productParam” class=”product”>
         <parameter property=”id”/>
</parameterMap>
<resultMap id=”productResult” class=”product”>
         <result property=”id” column=”PRD_ID”/>
         <result property=”description” column=”PRD_DESCRIPTION”/>
</resultMap>
<select id=”getProduct” parameterMap=”productParam”
         resultMap=”productResult” cacheModel=”product-cache”>
    select * from PRODUCT where PRD_ID = ?
</select>

If you want to keep the xml configuration simple you can have Ibatis make educated guesses on how to map a Bean to Parameter and from Results back to beans. There is a slight performance consequence in that this approach requires accessing the ResultSetMetaData. This limitation can be overcome by using an explicit resultMap. Result maps are described in more detail later in this document. This uses the auto mapping feature of the framework which could be slower than if you specified the mappings yourself.

Here is an example that allows the sqlMap to make educated guesses about the mappings

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap
  PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
  "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace=”Product”>
   <select id=”getProduct” parameterClass=” com.ibatis.example.Product”
                              resultClass=”com.ibatis.example.Product”>
         select
            PRD_ID as id,
            PRD_DESCRIPTION as description
         from PRODUCT
         where PRD_ID = #id#
   </select>
</sqlMap>

Since the developer is specifying SQL witin XML you need the ability to escape characters that would appear in xml. An example is the < and > signs.

<select id="getPersonsByAge" parameterClass=”int” resultClass="examples.domain.Person">
         SELECT *
         FROM PERSON
         WHERE AGE <![CDATA[ > ]]> #value#
</select>

SQL Fragments

In order to reduce SQL Code duplication you can use things like Fragments but keep in mind that it does increase the amount of testing effort if something in the common fragment changes.

Here is an example:

<sql id="selectItem_fragment">
         FROM items
         WHERE parentid = 6
</sql>
<select id="selectItemCount" resultClass="int">
         SELECT COUNT(*) AS total
         <include refid="selectItem_fragment"/>
</select>
<select id="selectItems" resultClass="Item">
         SELECT id, name
         <include refid="selectItem_fragment"/>
</select>

Auto generated keys

Supported by using the following XML code

<!—Oracle SEQUENCE Example -->
<insert id="insertProduct-ORACLE" parameterClass="com.domain.Product">
    <selectKey resultClass="int" >
         SELECT STOCKIDSEQUENCE.NEXTVAL AS ID FROM DUAL
    </selectKey>
    insert into PRODUCT (PRD_ID,PRD_DESCRIPTION)
    values (#id#,#description#)
</insert>
<!— Microsoft SQL Server IDENTITY Column Example -->
<insert id="insertProduct-MS-SQL" parameterClass="com.domain.Product">
    insert into PRODUCT (PRD_DESCRIPTION)
    values (#description#)
    <selectKey resultClass="int" >
         SELECT @@IDENTITY AS ID
    </selectKey>
</insert>

Calling Stored Procedures

<parameterMap id="swapParameters" class="map" >
  <parameter property="email1" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
  <parameter property="email2" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
</parameterMap>
<procedure id="swapEmailAddresses" parameterMap="swapParameters" >
  {call swap_email_address (?, ?)}
</procedure>

The next steps are to start coding your CRUD operations on your objects. I talk about this in more detail at the following page




Follow

Get every new post delivered to your Inbox.

Join 34 other followers