Tuesday, February 27, 2007

[quick tips] To Speedup your junit testing in Ant

If your development project get bigger, and have incorporated thousands of test cases, u may find that unit testing target getting slower and slower. It may come to a point your developers start to ignore test cases, or worst, don't write any test cases at all, as it will slow down build process.

Now, before u look into your unit testing code to improve the performance, why don't have a check on your Ant Junit Target (I discovered this accidentally yesterday, as I am frustrated by the slow build process). If u have setup ur Ant to fork a new JVM for unit testing target, by default, Ant will fork a new VM per Test Class, which is slow, and expansive (imagine forking 1000+ jvm for your project). To correct this, we just needs to set correct forkmode="perBatch".
junit fork="true" forkmode="perBatch"

My test result, before forkmode="perBatch", my test process take ~= 16 minutes
after, my test process take < 2 minutes

Cheers, and happy coding

Monday, February 12, 2007

[Tech Tips] Implementing Command Design Pattern via Spring Framework - Part II

The RemoteControl class needs to hold list of supported commands, and needs to delegate request to respective command class base on the pass in command string. Here is the RemoteControl source:

2 package blog.coolboy.springexample.cp;
4 import java.util.List;
5 import java.util.HashMap;
6 import blog.coolboy.springexample.cp.command.CommandType;
7 import blog.coolboy.springexample.cp.command.Command;
10 public class RemoteControl {
12 private HashMap<String, Command> supportedCommands = null;
14 public RemoteControl() { }
17 public void setListOfSupportedCommands(List<Command> commandList) {
18 supportedCommands = new HashMap<String, Command>();
19 for(Command cmd : commandList) {
20 supportedCommands.put(
21 }
23 }
25 public void execute(String cmdString) {
26 Command cmd = supportedCommands.get(cmdString);
27 if(cmd != null) {
28 cmd.execute();
29 } else {
30 System.out.println("The cmd->" +
+ " is not supported!");
31 }
32 }
34 }
The RemoteControl will transfer a list of supported commands to internal HashMap using commandString as object key, thus, removing the needs of iterating commands list for each new command execution.

Here's the fun part, we will inject list of supported commands to the RemoteControl above using Spring XML configuration, as shown in code below:

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

<beans xmlns="http://www.springframework.org/schema/beans"

<!-- listing of supported Commands here -->

<bean id="tvOnCommand"
<bean id="tvOffCommand"
<bean id="lightOnCommand"
<bean id="lightOffCommand"

<bean id="remoteControl"
<property name="listOfSupportedCommands">
<ref bean="tvOnCommand"/>
<ref bean="tvOffCommand"/>
<ref bean="lightOnCommand"/>
<ref bean="lightOffCommand"/>

That's all, our remote control class is finished. To roll out new Command, developer just needs to
1. declare the new command type, and it's command string at the CommandType enum
2. implements the command, and
3. inject new command via Spring Configuration.

Here are remoteControlService class to test the remoteControl

 1 package blog.coolboy.springexample.cp;
3 import java.io.BufferedReader;
4 import java.io.IOException;
5 import java.io.InputStreamReader;
6 import org.springframework.context.support.ClassPathXmlApplicationContext;
7 import org.springframework.context.ApplicationContext;
8 import org.springframework.jms.listener.DefaultMessageListenerContainer;
10 public class RemoteControlService {
11 public static void main(String [] args) {
12 ApplicationContext context =
13 RemoteControl remoteControl = (RemoteControl) context.getBean("remoteControl");
14 BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
15 System.out.println("Remote Control Ready, enter 'Quit' to terminate the program");
16 String txtCommand;
17 try {
18 do {
19 System.out.print("Enter your command->");
20 txtCommand = reader.readLine();
21 if(txtCommand.equalsIgnoreCase("quit")) {
22 break;
23 } else {
24 remoteControl.execute(txtCommand);
25 }
26 System.out.println("");
27 } while(true);
28 } catch (IOException ex) {
29 ex.printStackTrace();
30 }
32 }
33 }
Here are the try run:

Remote Control Ready, enter 'Quit' to terminate the program
Enter your command->tv.on
Switching On TV
Enter your command->tv.off
Switching off TV
Enter your command->light.on
Turning on Light
Enter your command->light.off
Turning off Light
Enter your command->quit


Isn't this fun? In the next article, I will explain how I would extends the app to support JMS and SOAP command request, using Spring, stay tune.

Friday, February 09, 2007

[Tech Tips] Implementing Command Design Pattern via Spring Framework - Part 1

I been using Spring Framework for pass few months, and I am big fans of the Framework. The framework help a lot, as we don't have to write lengthly, repetitive boring code, most application code are wire via Spring XML configuration, the framework also make our code cleaner, as it provide out of box AOP engine, developer could focus on implementing module core function, and “AOPing” other programming aspects such as transaction control, logging, security, and etc when require.

Thus, to say a big thank u on providing such great framework, and contribute back to the communities, starting from today, I will use this blog to share my experience, tips, and journal of using Spring here. Most of the write up will assume u have some basic idea of using Spring (Just do a google search on Spring tutorial).

So, my very first 2007 technical topic is “Implementing Command Design Pattern using Spring”. I will use the remote control example from very popular design pattern book, “Head First Design Patterns” from OREILLY.

The original requirement of the remote control are

1 . The remote control will have multiple buttons,
2. Each button could be program to turn on/off a household device.

I change the requirement a little, the remote control will not have any buttons, but:

1. It will accept command as a string from a console
2. Each device's command will have unique command String, such as

The very first thing we need to do is to roll out the command interface

1 package blog.coolboy.springexample.cp.command;
3 public interface Command {
4 public CommandType getCommandType();
5 public void execute();
6 }

Next, we needs to define an enum to hold all possible supported CommandType, each CommandType holds it's command string, which is unique. That's a helper method to return CommandType base on passing command string.
 1 package blog.coolboy.springexample.cp.command;
3 public enum CommandType {
4 LIGHT_ON("light.on"),
5 LIGHT_OFF("light.off"),
6 TV_ON("tv.on"),
7 TV_OFF("tv.off");
9 private String commandString;
11 // return CommandType base on passing
12 // commandString
13 public static CommandType valueOfCommandString(String cmdString) {
14 CommandType theCommandType = null;
15 for(CommandType cmdType : CommandType.values()) {
16 if (cmdType.getCommandString().equals(cmdString)) {
17 theCommandType = cmdType;
18 break;
19 }
21 }
22 return theCommandType;
23 }
25 CommandType(String cmdString) {
26 commandString = cmdString;
27 }
29 public String getCommandString() {
30 return commandString;
31 }
33 public void setCommandString(String commandString) {
34 this.commandString = commandString;
35 }
37 }

Now, implements all supported commands, below is sample code TV ON Command;

 1 package blog.coolboy.springexample.cp.command.impl;
3 import blog.coolboy.springexample.cp.command.Command;
4 import blog.coolboy.springexample.cp.command.CommandType;
7 public class TVOnCommand implements Command {
9 private final static CommandType cmdType = CommandType.TV_ON;
11 public TVOnCommand() {
12 // U suppose to pass in a TV instance here..
13 }
15 public CommandType getCommandType() {
16 return this.cmdType;
17 }
19 public void execute() {
20 System.out.println("Switching On TV");
21 }
23 }

The rest of commands (TV.Off, Light On, Light.Off) follows the same structure..

In part II, we will roll out the RemoteControl class, and use Spring to inject supported commands to the Remotecontrol, and provide remoteControlService as an interactive shell for user to test out the remote control, stay tune.