Javascinating

April 8, 2010

TCP and UDP Channel Adapters in Spring Integration 2.0.0 M3

Filed under: Software Development — Gary P. Russell @ 10:38 pm

Check out my recent blog about this cool technology at SpringSource.

October 31, 2009

Dependency Injection Explained in 2 Minutes

Filed under: Software Development — Gary P. Russell @ 8:22 pm

Bad – MyBar is tightly coupled to MyFoo

public class MyFoo{
    public void someMethod() {
         ...
    }
}

public class MyBar {
    private MyFoo foo = new MyFoo;
}

Good – MyBar refers to the interface Foo; to change to a different implementation you only have to change where MyFoo is instantiated.

public interface Foo{
    public void someMethod();
}

public class MyFoo implements Foo{
    public void someMethod() {
         ...
    }
}

public class MyBar {
    private Foo foo = new MyFoo();
}

Better – MyBar refers to interface Foo and gets the implementation by calling a factory; the factory decides which implementation of Foo to return.

public interface Foo{
    public void someMethod();
}

public class MyFoo implements Foo{
    public void someMethod() {
         ...
    }
}

public class MyFooFactory {
    public static Foo getInstance() {
        return new MyFoo();
    }
}

public class MyBar {
    private Foo foo = FooFactory.getInstance();
}

The getInstance() method can take, say, a Properties parameter so the client can supply attributes about what kind of Foo he wants.

Best – MyBar refers to interface Foo and has no direct involvement as to exactly which implementation of Foo is supplied; the instance is “injected” into MyBar; in this case, in the constructor.

public interface Foo{
    public void someMethod();
}

public class MyFoo implements Foo{
    public void someMethod() {
         ...
    }
}

public class MyBar {
    private Foo foo;

    public MyBar(Foo foo) {
        this.foo = foo;
    }
}

I clearly have a bias, but the Spring Framework provides an excellent method for injecting dependencies.

July 28, 2009

MSI K9N2 SLI Platinum / AMD Phenom 9600 x4 0×0000007e Stop

Filed under: Hardware — Gary P. Russell @ 7:20 am

More details to follow, but here are the cliff notes…

After moving WinXP disk to this platform, received the dreaded 0×7e stop on boot; google pointed me to a problem with intelpmp.dll, but this wasn’t my (initial) problem; I couldn’t even boot from the XP install disk which is not tailored for Intel.

Turned out a mobo bios flash (3.3 -> 3.5) did the trick (also had to remove the intelpmp.dll because the install came from an Intel box).

Hope this helps someone.

Will fill in the details later.

January 3, 2009

Enhanced Code Coverage for Finite State Machines

Filed under: Software Development — Gary P. Russell @ 6:45 pm

I was recently engaged to help debug and fix some code that was implemented as a Finite State Machine (FSM). There were no existing JUnit tests for the code, so I set about to write some. However, as one would expect with such an architecture, simple code coverage is not enough to verify that all the state transitions are exercised. Indeed, I had 100% code coverage with just a handful of tests, even though there were several hundred valid state transitions. (This was verified with the excellent EMMA based eclipse plugin – www.eclemma.org).

For those unfamiliar with this tool, it lights up your code in green and red showing executed/unexecuted lines; it also has some excellent reporting facilities.

I used a technique similar to the following to verify that I had covered all the allowable transitions.

In a future article (if there is sufficient interest), I will show how I used Apache POI to drive the JUnit from an Excel spreadsheet so I could solicit help from the user community to create all the test cases and their expected results. Please add a comment (or email me) if you would like to see an article on spreadsheet driven testing.

Using these two techniques, I quickly identified a number of issues which were corrected, resulting in another happy customer.

The following is a drastic simplification but, hopefully, it illustrates the technique.

Given the following simple state machine implementation…

package net.gprussell;

import java.util.HashMap;
import java.util.Map;

public class State {
	public static String STATE1 = "S1";
	public static String STATE2 = "S2";
	public static String STATE3 = "S3";
	public static String STATE4 = "S4";

	public static String TRANSITION1 = "T1";
	public static String TRANSITION2 = "T2";
	public static String TRANSITION3 = "T3";
	public static String TRANSITION4 = "T4";

	/*
	 * 		Valid transitions
	 *       S1 -> S2
	 *       S1 -> S3
	 *       S2 -> S3
	 *       S3 -> S4
	 */
	static Map<String , String> allowed;
	static {
		allowed = new HashMap<String , String>();
		allowed.put(STATE1 + TRANSITION1, STATE2);
		allowed.put(STATE1 + TRANSITION2, STATE3);
		allowed.put(STATE2 + TRANSITION3, STATE3);
		allowed.put(STATE3 + TRANSITION4, STATE4);
	}

	private String currentState;

	public State() {
		this.currentState = STATE1;
	}

	public State transition(String transition) {
		String newState = allowed.get(this.getCurrentState() + transition);
		if (newState == null)
			throw new RuntimeException("Invalid transition from " +
					this.getCurrentState() + " with transition " + transition);
		this.setCurrentState(newState);
		return this;
	}

	public String getCurrentState() {
		return currentState;
	}

	public void setCurrentState(String currentState) {
		this.currentState = currentState;
	}
}

It can be shown that the following test case executes 100% of the code.

package net.gprussell;

import junit.framework.TestCase;

public class NotGoodEnoughTest extends TestCase {

	public void testGoodTransition() {
		State state = new State();
		assertEquals(State.STATE2, state.transition(State.TRANSITION1).getCurrentState());
	}

	public void testBadTransition() {
		State state = new State();
		try {
			state.transition(State.TRANSITION4).getCurrentState();
			fail("Expected exception");
		} catch (RuntimeException e) {
			assertTrue(e.getMessage().startsWith("Invalid transition"));
		}
	}

}

Here is the EMMA report for this test.

However, we clearly have not exercised all the allowed state transitions.

The following test case ensures that all transitions are executed.

package net.gprussell;

import java.util.HashSet;
import java.util.Set;

import junit.framework.TestCase;

public class FullCoverage extends TestCase {

	private static Set<String> coverage;
	protected void setUp() throws Exception {
		if (coverage == null) {
			coverage = new HashSet<String>();
			for (String s : State.allowed.keySet())
				coverage.add(s);
		}
	}

	private State testing(State state, String trans, String newState) {
		coverage.remove(state.getCurrentState() + trans);
		state = state.transition(trans);
		assertEquals(newState, state.getCurrentState());
		return state;
	}

	public void testGoodPath1() {
		State state = new State();
		state = testing(state, State.TRANSITION1, State.STATE2);
		state = testing(state, State.TRANSITION3, State.STATE3);
		state = testing(state, State.TRANSITION4, State.STATE4);
	}

	public void testGoodPath2() {
		State state = new State();
		state = testing(state, State.TRANSITION2, State.STATE3);
		state = testing(state, State.TRANSITION4, State.STATE4);
	}

	public void testBadTransition() {
		State state = new State();
		try {
			state.transition(State.TRANSITION4).getCurrentState();
			fail("Expected exception");
		} catch (RuntimeException e) {
			assertTrue(e.getMessage().startsWith("Invalid transition"));
		}
	}

	// final test - ensure we covered all transitions
	public void testCoverage() {
		if (coverage.size() > 0) {
			for (String s : coverage) {
				System.out.println(s);
			}
		}
		assertEquals("Not all transitions covered", 0, coverage.size());
	}

}

First, before we execute any tests, we add all the allowable state transitions to a set. As each test is executed, it is removed from the set. At the end, we verify that the set is empty, ensuring that all allowable transitions have been exercised.

Simple, but effective.

Conclusion

It is important to realize that simple code coverage verification is not sufficient in many cases. While it is good to strive for 100% coverage, sometimes even that is not enough and we need to go a step further.

Gary
about

December 25, 2008

Proxying Your Stubs Can Save Space and Time

Filed under: Software Development — Gary P. Russell @ 11:41 am

Setting aside the discussion of stubs Vs. mocks in JUnit testing (that is covered more than adequately elsewhere), let’s say you’ve decided to use stubs, for whatever reason.

Please understand that the simple examples in this article may be more appropriately handled with mocks; they are for illustrative purposes only

Now, let’s say your class under test (CUT) uses a data access object (DAO) that has many methods, but it only needs one or two of those methods. The problem with a stubbed interface is you have to provide implementations of all the methods on the interface. Sure, modern IDEs such as eclipse can do the grunt work and generate all the method shells for you, with you being left to implement just the method(s) you need. However, especially with large stubbed interfaces, you can end up with a large amount of boilerplate code that can easily add up to 90%+ of the LoC in your test case.

This article discusses how to use dynamic proxies to eliminate this problem.

The technique allows you to create a class that implements just those methods you expect your CUT to use.

The examples below use JDK 1.4 syntax; at the end of the article, I provide the full project files in both JDK 5 and 1.4 versions, where the JDK 5 uses the strong typing provided by generics.

Onward…

First, declare the stub wrapper that creates the proxy; I prefer to make this a nested class within the test case so that I can invoke JUnit methods to make tests fail gracefully.

public class MyTest extends TestCase {
//...
    private static class StubWrapper implements InvocationHandler {
        private Object wrappedStub;
        private Class clazz;

        public StubWrapper(Object wrappedStub) {
            super();
            this.wrappedStub = wrappedStub;
            this.clazz = wrappedStub.getClass();
        }

        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            try {
                return clazz.getMethod(method.getName(),
                        method.getParameterTypes()).invoke(wrappedStub, args);
            } catch (Throwable t) {
                t.printStackTrace();
                fail("Stub method invocation failed");
                return null;
            }
        }

        public static Object wrap(Class type, Object stub) {
            return Proxy.newProxyInstance(StubWrapper.class
                    .getClassLoader(), new Class[] { type }, new StubWrapper(
                    stub));
        }
    }

}

The static method at line 25 creates a new instance of our proxy; the caller passes the interface in the parameter type and an instance of the class that implements the desired method(s) in parameter stub; the method uses the JDK Proxy mechanism to create the proxied stub. Note that we pass in a new instance of the StubWrapper, which has a reference to user supplied implementation instance.

The invoke method at line 13 is called when the CUT calls a method on the interface. This method is called by the proxy, passing in the proxy instance, the method that was invoked and a list of the arguments that were passed in. It simply delegates (via reflection) the method call to the wrapped stub, with an identical method name and parameter type list.

Note: if the method has not been implemented, we invoke the JUnit fail() method with an appropriate diagnostic.This is an added benefit of the technique. WIth the classic stub technique, if another developer adds a call to another method (in the CUT) there is nothing to force him or her to fill out the stub and the test may continue to pass even though no such implementation is provided. With this technique, the JUnit is sure to fail in such a circumstance.

Now we implement the stub itself…

public class MyTest extends TestCase {
//...
    private boolean daoCalled;
//...
    // no need to implement the interface; we get here via a proxy
    private class StubDAO{
        public Collection findSomeStuff() {
            daoCalled = true;
            MyVO vo = new MyVO();
            vo.setSomeAttribute("someValue");
            ArrayList l = new ArrayList();
            l.add(vo);
            return l;
        }
    }
//...
}

This is a simple test case that returns a list of value objects. Note that we set a boolean so we can assert later that the stub was called.

Instantiate the stub…

public class MyTest extends TestCase {
    private MyDAO stubDAO = (MyDAO) StubWrapper.wrap(MyDAO.class, new StubDAO());

//...
}

See how we simply invoke the StubWrapper.wrap method to obtain our proxy that implements the MyDAO interface.

The cast to (MyDAO) is not needed in the JDK 5 version because the wrap method is strongly typed to return an instance of the class passed in as the type parameter.

Finally, we implement the test…

public class MyTest extends TestCase {
    private MyDAO stubDAO = (MyDAO) StubWrapper.wrap(MyDAO.class, new StubDAO());
    private boolean daoCalled;

    public void testMyClassUnderTest() {
        CUT cut = new CUT();
        cut.setDao(stubDAO);
        cut.doSomething();
        assertTrue("Expected DAO call", daoCalled);
    }
//..
}

We instantiate the CUT, inject the stub, call some method on the CUT (which calls the stub) and assert that the stub was called.

Putting it all together…

package net.gprussell.test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;

import junit.framework.TestCase;
import net.gprussell.CUT;
import net.gprussell.MyDAO;
import net.gprussell.MyVO;

public class MyTest extends TestCase {
    private MyDAO stubDAO = (MyDAO) StubWrapper.wrap(MyDAO.class, new StubDAO());
    private boolean daoCalled;

    public void testMyClassUnderTest() {
        CUT cut = new CUT();
        cut.setDao(stubDAO);
        cut.doSomething();
        assertTrue("Expected DAO call", daoCalled);
    }

    // no need to implement the interface; we get here via a proxy
    private class StubDAO{
        public Collection findSomeStuff() {
            daoCalled = true;
            MyVO vo = new MyVO();
            vo.setSomeAttribute("someValue");
            ArrayList l = new ArrayList();
            l.add(vo);
            return l;
        }
    }

    private static class StubWrapper implements InvocationHandler {
        private Object wrappedStub;
        private Class clazz;

        public StubWrapper(Object wrappedStub) {
            super();
            this.wrappedStub = wrappedStub;
            this.clazz = wrappedStub.getClass();
        }

        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            try {
                return clazz.getMethod(method.getName(),
                        method.getParameterTypes()).invoke(wrappedStub, args);
            } catch (Throwable t) {
                t.printStackTrace();
                fail("Stub method invocation failed");
                return null;
            }
        }

        public static Object wrap(Class type, Object stub) {
            return Proxy.newProxyInstance(StubWrapper.class
                    .getClassLoader(), new Class[] { type }, new StubWrapper(
                    stub));
        }
    }

}


This zip file
contains the JDK 5 version of the above code (eclipse project).
This zip file contains the JDK1.4 version of the code (eclipse project).

Gary
about

December 23, 2008

The Customer Comes First (Back to the Future?)

Filed under: Software Development — Gary P. Russell @ 10:52 pm

It is nearly 30 years since I graduated as an industrial engineer; back then, as the “new kid on the block”, I was given the assignment of being the liason to the IT (then called Data Processing) department. Yes, I’m an old fart and, yes, we had punched cards back then.

I simply freaked when I found that even the simplest request (add a subtotal on a report, change a report sort etc) took 6 to 8 weeks to happen. So, I figured out on my own how to do ad-hoc reports; if folks in the IE dept. needed a new report, they had it on their desk in a couple of hours. I put a few noses out of joint but this was the start of my transition into IT.

Sure, more complex stuff takes a while but often something simple that can be implemented quickly can provide huge business impact.

Roll forward 30 years; after a short stint at that company and 25+ years in product development for one of the BUNCH, I have spent the last few years consulting in Java and related technologies.

My observation is that not a lot has changed; many IT departments are still considered to be laws unto themselves. With all our technology and cool stuff, we still need to understand that we are there to support the business. If one of our internal (or external) clients needs something that is easy to provide, just do it. It will pay off in spades; the next time something is hard to do, and will take time, they will understand; if it’s easy and you take care of it quickly, the kudos will flow. Often times, something that is easy to us seems hugely complex to clients (of course, the opposite is the case too but, again, if you help them out most of the time, they’ll believe you when you say something is hard to do).

This all might seem obvious, but I fear that too many lose sight. All I can say is that this philosophy has worked well for me over the years.

Moving forward…

Satisfying the customer gives one a good feeling, but that alone is not enough. What gets me out of bed in the morning is the sure fact that I know I’ll learn something more today.

As time goes by, I hope to use this blog to share some of the more interesting things that I learn.

Gary

Powered by WordPress