Sunday, December 13, 2009

Simple Layouts with JSP in Spring MVC

Every web application has elements common to all its pages which are good candidates for re-use. While Spring MVC provides integration with Tiles, it can be an overkill for simple applications and needs using Spring's client side JS library for AJAX (correct me if I'm wrong).

For most applications, standard JSPs can serve as good layout engine. This post shows how Spring's handler interceptor can be used to specify a normal JSP file as the layout for a Spring MVC web application.

This interceptor allows you to specify a JSP file containing the layout for the application into which the actual views get plugged. The interceptor takes the actual model and view and replaces the actual view with the layout view's name and puts the actual view name into the model map to be used by the layout file. If you do not want to include the layout for certain requests (AJAX requests) you can prefix the view name with "noLayout:".

The Interceptor
public class LayoutInterceptor extends HandlerInterceptorAdapter {
private static final String NO_LAYOUT = "noLayout:";

private String layoutView;

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
super.postHandle(request, response, handler, modelAndView);

String originalView = modelAndView.getViewName();

if (originalView != null) {
includeLayout(modelAndView, originalView);
}
}

private void includeLayout(ModelAndView modelAndView, String originalView) {
boolean noLayout = originalView.startsWith(NO_LAYOUT);

String realViewName = (noLayout) ? originalView.substring(NO_LAYOUT.length()) : originalView;

if (noLayout) {
modelAndView.setViewName(realViewName);
} else {
modelAndView.addObject("view", realViewName);
modelAndView.setViewName(layoutView);
}
}

public String getLayoutView() {
return layoutView;
}

public void setLayoutView(String layoutView) {
this.layoutView = layoutView;
}
}

Sample Usage
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<list>
<bean id="layoutInterceptor" class="LayoutInterceptor">
<property name="layoutView" value="layout"></property>
</bean>
</list>
</property>
</bean>

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
With that all the views returned by controllers can be included within the layout JSP by including the following line in WEB-INF/jsp/layout.jsp.
<jsp:include page="/WEB-INF/jsp/${view}.jsp"></jsp:include>

Sunday, November 01, 2009

Mocking Math.random() using PowerMock

Let's consider the below Game class in a guessing game where a random target is chosen by the system and the user guesses the target. The system returns an appropriate message based on whether the guess was higher, lower or equal to the random target.

package org.game;

public class Game {
private int target = (int) (Math.random() * 100);

public int guess(int guess) {
return target - guess;
}
}

No magic there. Now let's look at the unit test for this class.

package org.game;

// imports hidden;

public class GameTest {
private Game game;

@Before
public void setUp() {
game = new Game();
}

@Test
public void testHigherGuess() {
int result = game.guess(55);
Assert.assertTrue(result < 0);
}

@Test
public void testLowerGuess() {
int result = game.guess(35);
Assert.assertTrue(result > 0);
}

@Test
public void testCorrectGuess() {
int result = game.guess(50);
Assert.assertTrue(result == 0);
}
}

As you might have guessed by now this wouldn't work as the target is randomly generated. Now we have three options to handle this.
  1. Add a constructor taking the target value as argument and set the target using that. This would make passing a non-random value for testing simple. However, this would change the interface of the class unnecessarily.
  2. Access "target" using reflection and set its value after object creation. However, this would make the unit test fragile as it knows too much about the internals of the class under test.
  3. We can make Math.random() to return a constant value within our test case. This is the approach demonstrated in this post.
PowerMock is a mocking framework which extends several popular frameworks to allow mocking of static methods and more. In this post we'll use PowerMocks' extension for EasyMock. The general technique to mock static methods using PowerMock is outlined here.

This wouldn't work for system classes like Math. To workaround this, we can prepare the class using the static method for test rather than the class containing the static method. Which means we'd be using @PrepareForTest(Game.class) instead of @PrepareForTest(Math.class) in our case. The completed unit test would look like this.

package org.game;

// imports hidden

@RunWith(PowerMockRunner.class)
@PrepareForTest(Game.class) // Preparing class under test.
public class GameTest {
private Game game;

@Before
public void setUp() {
// Mocking Math.random()
PowerMock.mockStatic(Math.class);
EasyMock.expect(Math.random()).andReturn(0.50).anyTimes();
PowerMock.replay(Math.class);

game = new Game();
}

@Test
public void testHigherGuess() {
int result = game.guess(55);
Assert.assertTrue(result < 0);
}

@Test
public void testLowerGuess() {
int result = game.guess(35);
Assert.assertTrue(result > 0);
}

@Test
public void testCorrectGuess() {
int result = game.guess(50);
Assert.assertTrue(result == 0);
}
}

Now PowerMock ensures that any call to Math.random() would always return a constant value within the Game class when used for testing. Hence we can test the guess() method just as how any client code using the Game class would.

Saturday, August 29, 2009

Using Javascript as DI Container in Java

Javascript is almost as dynamic as any programming language can get. However, it is mostly used only within the browser and many developers (including dynamic language fans) don't know of many of the cool language features of Javascript. When these features are used effectively, it lets us write highly expressive code which even many dynamic languages can't match.

Most Java developers turn to Spring for their DI and AOP requirements. However the configuration of Spring is quite verbose and is mostly XML. Plain JDK can handle AOP using dynamic proxies and as this post demonstrates Javascript can be used to handle the dependency injections.

Starting with Java 6, Java applications can invoke scripting languages within their JVM instance and communicate with them seamlessly using the Scripting API. Sun's JRE also ships with a built-in engine for handling Javasript through this API. We can utilize Javascript's power and expressiveness to perform cool stuffs on top of the JVM.

What are we Building?
  1. Two DAOs and their mock implementations.
  2. A sample service utilizing these DAOs.
  3. JS script wiring them up together.
  4. A simple interceptor to log invocations of service methods.
DAOs
package dao;

public interface BooksDAO {
public int count();
}

package dao;

public interface MembersDAO {
public int count();
}

package dao;

public class MockBooksDAO implements BooksDAO {

@Override
public int count() {
return 500;
}
}

package dao;

public class MockMembersDAO implements MembersDAO {

@Override
public int count() {
return 100;
}
}

Service
package service;

public interface LibraryService {

public abstract int countBooks();

public abstract int countMembers();

}

package service;

import dao.BooksDAO;
import dao.MembersDAO;

public class MockLibraryService implements LibraryService {
private BooksDAO booksDAO;
private MembersDAO membersDAO;

public MockLibraryService(BooksDAO booksDAO, MembersDAO membersDAO) {
this.booksDAO = booksDAO;
this.membersDAO = membersDAO;
}

public int countBooks() {
System.out.println("In countBooks()");
return booksDAO.count();
}

public int countMembers() {
System.out.println("In countMembers()");
return membersDAO.count();
}
}

DI Script

We utilize Javascript's Object literals to define and group our DAOs and services. These can then looked up from our applications to obtain the actual implementations.

src/objects.js
importPackage(Packages.dao)
importPackage(Packages.service)
importPackage(Packages.interceptor)

daos = {
booksDAO : new MockBooksDAO(),
membersDAO : new MockMembersDAO()
}

services = {
libraryService : LoggingInterceptor.getProxy(new MockLibraryService(daos.booksDAO, daos.membersDAO))
}

Application Code

We use the ScriptEngineBuilder introduced in a previous post to evaluate our Javacript and then obtain the service instance from it.

package app;

import javax.script.ScriptEngine;
import javax.script.ScriptException;

import service.LibraryService;
import util.ScriptEngineBuilder;

public class Main {
public static void main(String[] args) throws ScriptException {
ScriptEngine engine = new ScriptEngineBuilder("js").add("/objects.js").build();

LibraryService service = (LibraryService) engine.eval("services.libraryService");

System.out.println("Found " + service.countMembers() + " Members!");
System.out.println("Found " + service.countBooks() + " Members!");
}
}

Adding AOP to the Mix

Let's create a JDK dynamic proxy to log all method invocations.
package interceptor;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class LoggingInterceptor implements InvocationHandler {
private Object target;

public static Object getProxy(Object target) {
ClassLoader loader = LoggingInterceptor.class.getClassLoader();
Class[] interfaces = target.getClass().getInterfaces();
InvocationHandler handler = new LoggingInterceptor(target);

return Proxy.newProxyInstance(loader, interfaces, handler);
}

private LoggingInterceptor(Object target) {
this.target = target;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
try {
System.out.println("Entered Method: " + method.getName());
Object val = method.invoke(target, args);
System.out.println("Completed Method: " + method.getName());
return val;
} catch (Exception e) {
System.out.println("Exception in Method: " + method.getName());
throw e;
}
}

}

Let's now modify our service creation in DI script as below to utilize the proxy.

libraryService : LoggingInterceptor.getProxy(new MockLibraryService(daos.booksDAO, daos.membersDAO))

So there we have a nice and clean DI configuration including AOP without needing anything outside of Java SE. An important thing to note here is that we are still maintaining the DI and AOP config entirely outside our application code unlike when using annotations. Spring would have needed a truck load of XML to achieve the same!

Friday, August 28, 2009

ScriptEngineBuilder for Java

Java 6 allows you to execute and communicate with scripts written in any scripting language, using the Scripting API. However, the code needed to create a ScriptEngine and evaluate a set of script files within it, is quite verbose and throws several checked exceptions.

I decided to create a simple fluent Builder which can be used to create a ScriptEngine and execute a set of script files inside it. It also allows you to add Java Objects into the engine before executing the script files.

ScriptEngineBuilder
import java.io.InputStreamReader;
import java.net.URL;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class ScriptEngineBuilder {
private ScriptEngine engine;

public ScriptEngineBuilder(String shortName) {
this.engine = new ScriptEngineManager().getEngineByName(shortName);
}

public ScriptEngineBuilder add(String scriptResource) {
try {
URL scriptURL = getClass().getResource(scriptResource);
InputStreamReader scriptReader = new InputStreamReader(scriptURL.openStream());
engine.eval(scriptReader);

return this;
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public ScriptEngineBuilder put(String key, Object value) {
engine.put(key, value);
return this;
}

public ScriptEngine build() {
return engine;
}
}


Applications can create an instance of ScriptEngineBuilder by passing the shortName of the engine to the constructor. Then they can invoke add() method for the script files to be evaluated (as classpath resource name). They can finally invoke build() to get the ScriptEngine instance.

Sample Invocation
ScriptEngine engine = new ScriptEngineBuilder("js").add("/script1.js").put("myObj", obj).add("/script2.js").build();

Saturday, April 11, 2009

DevCamp Bangalore 2

I had attended DevCamp Bangalore 2 on Saturday. There were several sessions planned and many happened simultaneously. So I could attend only a handful of them though many others were interesting too. I had quite a nice experience in most of the sessions except for those where either I was not interested or didn't understand anything.

Sahi

Sahi is an automation and testing tool for web applications, with the facility to record and playback scripts. Sahi runs on any modern browser which supports javascript. The founder of Sahi, Narayan Raman, gave a nice descriptive demo of how Sahi works and was answering the various interesting questions fired at him by audience. He also mentioned the limitations which Sahi had in its current state.

Visualization of Code Metrics


Neal Ford gave a nice presentation on the various tools which provide visual presentation of various code metrics like Cyclomatic Complexity, LOC, Methods per Class, etc. It was a nice learning for me about various standards and thresholds the industry follows regarding code quality.

Augmented Reality

Mrinal Wadhwa's session on this one didn't really interest me and I just moved out. Not that the session was bad just that it did not align with my interests.

Productive Programmer Mechanics

This is was one of the more interesting sessions. Neal Ford talked about different ways to improve the productivity of programmers. While it was nothing revolutionary, some of the tips on using IDEs better were Aha! moments.

When he mentioned but Window's behavior affected programmers' productivity, I felt it was indeed so true. Though, I myself have never realized it though I'm sick of Windows. This indeed has been disturbing me at work daily but I just never realized it.

Erlang & Distribution

Bhasker V Kode's session on Erlang was very interesting. Especially his biological analogies were helping in explaining it a lot better. However, since I have absolutely no familiarity with Erlang and have very little understanding of FP, it really was greek and hebrew to me.

Ruby for the Curious Hacker

This was a session I was waiting for given my recent in RoR. Sidu had a very simple presentation but the Q&A discussion took up the session's time and even exceeded it a bit.

There were several people criticizing the syntax of Ruby and its monkey patching capabilities. Sidu also expressed some of his gripes about Ruby and to some extent Rails.

DSLs

Neal Fords, session on how normal languages can be used as DSLs was the last session I attended. It was very interesting as he demonstrated how playing around with languages' syntax can turn them into DSLs. He also mentioned various ways of building DSLs out of common languages.

Over all it was a very nice experience, interacting and learning from fellow geeks.

Thursday, December 25, 2008

Netbeans Firefox Hack

Most Ubuntu (any distro specific Firefox package for that matter) users who also happen to use Netbeans, would have come across this annoying issue.

Even if the Arguments setting for Firefox was changed to juts "{URL}" in Netbeans options, it displays an error when the project is run multiple times and then Firefox is closed. But at least it doesn't display for each run. Still getting the error is annoying even though it is only when Firefox is closed after multiple runs.

I felt Netbeans was somehow waiting for Firefox to close before next run (I really have no clue what exactly is wrong). So I thought starting Firefox in background and returning immediately to Netbeans will help.

So I created a shell script with the following content. And made it executable.
#!/bin/bash
firefox "$1" &

Then I selected the shell script as the command for starting Firefox in Netbeans. Final settings in Netbeans, look like this.



While I never understood how this fixed it, it did. No more annoying error messages. :)

Monday, December 01, 2008

Making openAL use PulseAudio in Ubuntu Intrepid

With the release if Ubuntu Intrepid, everything was supercool except for one pain point. Sound system would crash leaving a noise which would not stop until a system reboot whenever I play and exit from torcs.

For a system wide fix for this problem, edit /etc/openal/alsoft.conf and change the device value in the section titled [alsa] as below.
device = alsa
Ubuntu rocks again. :)