Sunday, March 05, 2006

Using JNLP for a J2EE application client

In Moving the view away from the controller I talk about general ideas for separating the typical cohosting of a J2EE application (the service layer and below) from the view (JSPs, etc.).

Sun's own way of handling this is to make the client intimately familiar with the application beans. But this is the opposite of the direction I want to go in. Instead, I want to have the controller reside at the server, and the veiw in the client without any knowlege of beans and such.

Of course, this is the same as having any of a REST, SOAP, RPC or similar architectures, or all of them.

Presently, I am evaluating JBoss serialization v. REST-RPC to see how they compare for performance, reasonableness and ease of development, but am open to other suggestions.

My goal is to construct a demo client and server application with JNLP Swing at one end and standard J2EE servlets at the other. Fortunately for me, Sun gets me started and there are good examples by others.

Friday, March 03, 2006

IntelliJ IDEA 5175

Yah! Finally, an EAP build of what will become IntelliJ IDEA 6.0 that is usable for me. The previous EAP build (5162) had two problems for me:

  1. It threw exceptions a lot.
  2. Fatally, 5162 corrupted project settings files.

But the new 5175 build works great.

I like the newer way of handling views borrowed from Eclipse (I presume) but without the klunkiness feel of Eclipse perspectives (although the J2EE portion has some kinds to iron out: I get the J2EE view twice in the drop list).

I also see lib/emma.jar and lib/emma-agent.jar new with 5175 (perhaps also with 5162, but not in 5131). I have not found any UI yet for unit test code coverage, but it looks like IDEA is heading that direction.

Lastly, I also noticed lib/rt/org.eclipse.jdt.core.jar which is not in 5.1. I wonder what JetBrains is up to?

JUnit testing for exceptions

A JUnit pattern I find myself using very frequently is testing constructor and method inputs. Usually the first testcase I have for a new class is to test what happens in the constructor with null inputs. I believe in fail-fast coding principals and expect calls to quit as soon as they know there is no point in continuing. This helps me find bugs and other problems quickly during development rather than slowly during deployment.

So my typical test looks like this. For some class Foo whose constructor takes a single non-null parameter, bar, and which throws an IllegalArgumentException otherwise, I check for the name of the missing parameter in the exception message (as a convention):

 1 /**
 2  * Test {@link Foo#Foo(String)} for {@code null} <var>bar</var>.
 3  *
 4  * @throws Exception if unexpected
 5  */
 6 public void testFooForNullBar()
 7         throws Exception {
 8     try {
 9         new Foo(null);
10         fail("Did not throw");
11 
12     } catch (final IllegalArgumentException e) {
13         assertExceptionMessageContains(e, "bar");
14     }
15 }

But what about assertExceptionMessageContains? It is very simple:

 1 /**
 2  * Assert that the given exception, <var>e</var>, constains the given
 3  * string, <var>s</var>, in its message failing with <var>message</var>
 4  * otherwise.
 5  *
 6  * @param message the failure message
 7  * @param e the exception
 8  * @param s the string in the message
 9  */
10 protected static void assertExceptionMessageContains(final String message,
11         final Exception e, final String s) {
12     assertTrue(message, e.getMessage().contains(s));
13 }
14 
15 /**
16  * Assert that the given exception, <var>e</var>, constains the given
17  * string, <var>s</var>, in its message.
18  *
19  * @param e the exception
20  * @param s the string in the message
21  */
22 protected static void assertExceptionMessageContains(final Exception e,
23         final String s) {
24     assertExceptionMessageContains(
25             "Exception missing message: " + s + ": " + e, e, s);
26 }

Originally I threw NullPointerException from my constructors when encountering missing parameters, but over time I changed to IllegalArgumentException as more descriptive, and also so that any NullPointerException would always indicate something unexpected from the JVM.