Java AWT Robot and Windows Remote Desktop

June 15th, 2010

Problem

If you’re attempting to use the Java AWT Robot to help automate tests, you may find it convenient to log in via remote desktop to watch the tests execute and verify they work well. You may also find that they work fine while you’re watching them but then inexplicably start failing whenever you aren’t. Basically your test is an angel from Dr Who.

What’s most likely happening is that when you disconnect from the remote desktop session, the console on the Windows box is left in a locked state and you need to enter the user password before you can resume interacting with programs on the main display. Since the AWT Robot is doing a very effective job of acting like a user, it also can’t interact with the programs you’re intending and instead is interacting, probably quite ineffectively, with the login dialog box.

Solution

It may be possible to get the AWT Robot to actually login before continuing, but then your tests would break when you were watching and it complicates the tests. Instead, you can take two approaches:

  1. Stop using remote desktop and switch to VNC which doesn’t lock the screen when you disconnect.
  2. Rather than disconnecting from remote desktop, transfer the session back to the console. Use Start->Run or a DOS prompt and run:
    tscon.exe 0 /dest:consol
    

Or of course just get up and walk over to the remote machine and watch the tests on the console directly, but that’s not always a viable option.

Returning Parameters in JMock 2

March 9th, 2010

If you have a method like:

String getParameter(String name, String defaultValue)

where defaultValue is returned if the parameter isn’t specified, it can be challenging to get the right behavior in JMock without just hard coding what the defaultValue should be. Fortunately, a custom match which doubles as an Action can solve this pretty easily:

import org.hamcrest.*;
import org.jmock.api.*;

public class CapturingMatcher<T> extends BaseMatcher<T> implements Action {
	public T captured;

	public boolean matches(Object o) {
		try {
			captured = (T)o;
			return true;
		} catch (ClassCastException e) {
			return false;
		}
	}

	public void describeTo(Description description) {
		description.appendText("captured value ");
		description.appendValue(captured);
	}

	public Object invoke(Invocation invocation) throws Throwable {
		return captured;
	}
}

It can then be used like:

context.checking(new Expectations() {{
	CapturingMatcher<String> returnCapturedValue = new CapturingMatcher<String>();
	allowing(mockObject).getParameter(with(equal("expectedParameterName")), with(returnCapturedValue)); will(returnCapturedValue);
}});

The matcher is used both for the parameter value (which it stores) and the return action, so it acts like a back reference would in a regex. The same class be be useful alone as a matcher to let you interrogate the parameter value using normal assert statements rather than building a custom matcher.

I really should investigate what the describeTo function really should do though – I’m sure it would generate pretty weird messages at the moment.

Show Me the Metrics

March 3rd, 2010

There’s been a lot of new innovations going on in programming languages and development techniques in general lately, but there’s a really key missing element: metrics.

Seeing posts like Stephan Schmidt’s Go Ahead: Next Generation Java Programming Style and the response from Cedric Otaku really should make any professional software engineer concerned about the future of their craft. Not because either of them are necessarily right or wrong, but because two highly skilled engineers are engaged in debate based purely on pure personal preference. There’s barely even any anecdotal evidence provided, let alone actual measurements to see what impact on productivity, quality or other desirable qualities the proposed approaches have.

A while back I stumbled across the slides from Greg Wilson’s presentation Bits of Evidence. It’s almost a shame that the slides are well designed because they really are a short summary and I’d love to have heard all the extra information Greg spoke about around those slides. Even so, they really highlight the fact that we’re rushing off down all these new paths basically just because some guy said to. One of the side notes sums it up really well:

Please note: I’m not disagreeing with his claims – I just want to point out that even the best of us aren’t doing what we expect the makers of acne creams to do.

It would be easy to dismiss the importance of this because in your own experience technique A works better than technique B and with regular Agile retrospectives you’d notice if it had failings and worked to overcome them. Unfortunately, you’re very likely to fall victim to the same selection bias that makes psychics believable. People inherently remember the “hits” and forget the “misses”1, so even personal experience isn’t something you should depend on to make decisions unless it’s backed up at least partly by real hard data.

I like playing with new technology as much as the next person, but at the end of the day I have to wonder if the benefits are always as compelling as we’d all like to think. Probability would suggest that some of the new approaches really are a big improvement, but it would also suggest some of them are a mistake. Without metrics to judge them on, how are we going to know the difference?

1 – Wikipedia claims this was first raised in Broad, C. D. (1937). The philosophical implications of foreknowledge. Proceedings of the Aristotelian Society (Supplementary), 16, 177-209.

Better File System APIs

January 21st, 2010

Dylan complained about the lack of testability with file system APIs, which reminded me of a neat looking library I stumbled across while looking at build systems: EntityFS. Among a bunch of other useful sounding things it provides:

File system APIs are backend-independent. File systems can be created in RAM memory, on Zip files, on file system directories, etcetera

Sadly it’s under the LGPL which makes it difficult if you happen to sell to big enterprises that are still somewhat scared of GPL type licenses, but they’re nowhere near as common as they used to be. I should note though that Holocene Software are offering commercial licenses for an undisclosed price.

The New Cross Platform

September 25th, 2009

When I first started professional programming, Java was reasonably young and was being hailed as a work of genius with it’s cross platform deployment capabilities. Programming was going to be revolutionised forever and all programs would run on any OS1. Then Java wound up being most popular on the server side and liberated server code from the choice of OS more than the desktop side2.

Server OS’s started to compete mostly on how well they were a server rather than what programs ran on them because what really mattered was that you could run the Java stack. In other words, Java became the platform that people deployed their applications to. It shouldn’t come as a surprise that a single platform didn’t stand unchallenged for long. .NET sprang up as the big enterprise competitor to Java and all of a sudden you had to choose sides again.

The interesting thing is that another layer of platform abstraction is starting to spring up. Languages like Ruby and Python came from a background of running standalone and are now starting to abstract away the choice of the Java or .NET platform, just as Java abstracted away the choice between Linux, Windows or Solaris in it’s time.

From what I can tell, none of the languages have really developed a fully complete, heavy production ready, bet-the-company-on-it implementation for both the JVM and .NET but both Ruby and Python seem to come very close and have serious corporate sponsorship behind them. Right now the sense I get is that people are either using Iron Python or Jython, Iron Ruby or JRuby but not seriously deploying the same code to both. It doesn’t look like it will be long before doing so would be quite feasible though.

Exciting times ahead.

1 – Interestingly enough this has actually been the trend, but not because programs were developed in Java – it just inspired developers in other languages to build cross-platform abstraction libraries.

2 – albeit not as smoothly as anyone would have liked