Sunday, November 8, 2009

Java on the Decline?

I attended the No Fluff Just Stuff conference in Reston, VA this weekend (http://www.nofluffjuststuff.com/home/main), and once again it was excellent. One fact that is becoming clearer is that Java really is on the decline. With languages like Groovy and Scala (and Clojure - though I have no firsthand experience with that so I can't give much input there) on the rise, why should we still use Java?

I've been using groovy for the last year or so and use it in both tests and production code. Groovy is growing in popularity very quickly since it is just a dialect of Java, and all Java code is valid in Groovy. Developers can "groovify" code as they become more familiar with the Groovy idioms.

Scala is a bit newer to me, but I'm becoming familiar with that as well. At first I wondering why I needed language that could be both functional and OO, but it quickly became familiar. The functional aspect of Scala (and some of these operations are available in Groovy too) works magic on collections. Mapping operations to collections is a really nice feature. Think of all the times in Java you write code that looks something like this:

List myList// assume this is initialized
for ( MyObj o : myList ) {
System.out.println("o = " + o);
}

whereas in scala, the same code can be written as:

myList.foreach(n=> println(n))

This is a simple example, but any function can be mapped to every element in the list, which can be a real space saver.
I'm not going to try and write a Groovy or Scala tutorial here since there are already so many of those, but my takeaway is that these languages are on the rise, because they offer everything Java has to offer and more (with less code).

Monday, November 2, 2009

Immutable Collections

When we think of immutability in Java, the final keyword should come to mind. It's good practice to finalize whenever possible, particularly when working with multi-threaded applications. The less mutable state that exists, the less chance for side effects and bugs.
Working with collections is a bit trickier. When a class has a getter for a collection, things get a bit more difficult. Let's see what happens.

private final Collection<Object> aCollection;
public MyClass(Collection<Object> coll) {
aCollection = new LinkedList<Object>(coll);
}
public Collection<Object> getCollection() {
return aCollection;
}

Attempting to finalize a collection like this provides very little assurance that the collection will not be mutated. A client that calls getCollection can add or remove from the underlying collection as well as change the elements.
Addressing the first issue of adding or removing from the collection is easy to handle, yet I often see this overlooked. By using the Collections.unmodifiableXXX methods, we can easily create a collection that cannot be added or removed from. The constructor would now look like

public MyClass(Collection<Object> coll) {
aCollection = Collections.unmodifiableCollection(coll);
}

By finalizing in the constructor, this assures that neither private nor public methods can inadvertently mutate the structure of the list. The issue preventing a client from mutating the state of the objects in the list still exists. In order to prevent this, the objects would need to be completely immutable. There's not too much MyClass can do about this.
To sum up, try to make objects immutable whenever possible. You should be defaulting to final objects and unmodifiable collections and removing these restrictions only when absolutely necessary.

Wednesday, October 14, 2009

It's never too late for tests

So you've inherited a pile of buggy, spaghetti code, and now you're supposed to add some new features. We've all been there. It's very easy to say, "The code is already bad, so I'm not going to make the new features any nicer" but you shouldn't. This is your pile of spaghetti now, so you should work to make it incrementally better.

One big step in making bad code better is adding tests (I'm a firm believer in writing the tests first, so you shouldn't have much untested code, but it doesn't always happen). I'm not suggesting you drop everything and add tests to make sure you get to X% code coverage. But, as you add new features, you'll find yourself digging through old code. As you touch different parts of the code, refactor them where needed and add some tests. It will make you more confident in that part of the code, make life easier for yourself, and it will probably uncover some problems that you didn't know existed (and that have probably been there for a long time). A steady approach to testing will make any code better.

Sunday, October 11, 2009

Checked vs Unchecked Exceptions

The debate of whether to use checked or unchecked exceptions are a long debated topic in the Java world, and I'm still not sure that either side has emerged as a clear winner in the eyes of the development community. I personally think that unchecked exceptions are the way to go.

When a checked exception is thrown, there are several typical ways to deal with it.

These methods are the most appropriate ways to deal with a checked exception:

1. Handle it. Do something in response to the exception other than just re-throwing it or logging. If you have an I/O exception, maybe retry the operation.

2. Rethrow it. If you can't handle it, rethrow it, and maybe someone else above you in the call stack can handle it.

3. Wrap it as a runtime exception and rethrow it.

#2 and #3 become a bit more painstaking when methods throw multiple checked exceptions since Java doesn't support multiple exception catch blocks.

There are other ways to deal with it. These are not recommended, but any developer has seen these scenarios:

4. Log it/print stack trace and swallow the exception
5. Do nothing at all and swallow the exception

It's obvious that #4 and #5 can have very bad effects. These exceptions could be indicating some serious problems. While #4 will result in an entry in the log, it still could leave the application in a state that results in some unpredictable behavior. #5 should never be done.

With unchecked exceptions, you have all of the same options. However, #4 and #5 are much less likely since developers frequently do these out of laziness or because their IDE provides this as the default behavior.

Those that favor checked exceptions will say that you are much less likely to handle an unchecked exception since you the compiler does not force a method to declare that it is thrown. While this is true, the same can happen if the method wraps the checked exception in an unchecked one. And, in all actuality, how frequently do you actually handle exceptions vs logging and rethrowing them. If you're like me, you spend much more time doing the latter.

To be fair, there are some times when you really do want to handle the exception. Take the case of the IO exception when you want to retry an operation. Even if it was an unchecked exception, you could use annotations on the method you want to retry (not necessarily the direct method that throws the IO exception), which will work for an unchecked (or checked version) of the IO exception.

@RetryOnException(type=IOException.class)
public void saveState() {
State state = getState();
writeStateToFile(state);
}

private void writeStateToFile(State state) {
// write the state to file
}

The @RetryOnException idea puts the responsibility on the method that needs to be retried but doesn't require everyone in the call stack to declare an IOException. This idea will work the same for checked or unchecked exceptions.

Tuesday, October 6, 2009

Getting Groovy with XML Parsing

I generally like to use Groovy for data processing, particularly XML parsing. If you've used Groovy before, this won't be anything new, but if you haven't, this example might be enough to make you drink the groovy juice. Given this xml file of an address book, I want to print out all of the people in the address book.

<addressBook>
<person>
<firstName>John</firstName>
<lastName>Smith</lastName>
</person>
<person>
<firstName>Jane</firstName>
<lastName>Doe</lastName>
</person>
</addressBook>


Here's the Java way of doing it (if you've ever done any Java XML parsing, this will look very familiar):

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder parser = factory.newDocumentBuilder();
Document document = parser.parse("xml/sample.xml");
NodeList personNodes = document.getElementsByTagName("person");
List<String> names = new LinkedList<String>();
for (int i = 0; i < personNodes.getLength(); i++) {
String firstName = null;
String lastName = null;
Node personNode = personNodes.item(i);
NodeList children = personNode.getChildNodes();
for (int j = 0; j < children.getLength(); j++) {
Node child = children.item(j);
String nodeName = child.getNodeName();
String nodeValue = child.getTextContent();
if ("firstName".equals(nodeName)) {
firstName = nodeValue;
} else if ("lastName".equals(nodeName)) {
lastName = nodeValue;
}
}
names.add(firstName + " " + lastName);
}
for (String name : names) {
System.out.println(name);
}


That's 25 lines of Java code to print out a few names (and I didn't even include the public static void main(String[] args) declaration).

Now let's look at the groovy way of doing it:

def addressBook = new XmlSlurper().parse('xml/sample.xml')
addressBook.person.each { p -> println "${p.firstName.text()} ${p.lastName.text()}"}

Just 2 lines, that's it.

Happy groovy-ing.

Friday, October 2, 2009

Java Swing Threading

I've recently spoken with a few developers that were writing Swing apps (some for the first time) but were not familiar with the Swing threading model and the event dispatch thread, so I thought I'd review some of the basics. The main rule of Swing programming is that any code that updates the GUI (this applies only after a component has been realized, meaning its paint method has been called) must be invoked on the event dispatch thread (EDT). This can be accomplished using the methods SwingUtilities.invokeLater and SwingUtilities.invokeAndWait to run tasks on the EDT asynchronously and synchronously respectively. There are some exceptions to the rule, and Sun details those in an article http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html#exceptions (that whole article is a very good explanation of Swing threading as well).

While this does sound like a straight forward rule, there are some easy ways to get into trouble. One of these ways is when code is updating a GUI's model, which in turn updates the GUI component, that code must be invoked on the EDT. For example, calling model.setDataVector on the DefaultTableModel to update the data in a table must be called from the EDT. Even though you are just updating the model, the model fires an event that updates the GUI (note that some GUI libraries may already handle this for you, but it's not safe to assume this in general).

Violating this rule can cause unpredictable effects. Just like any threading error, reproducing and debugging the problem can be very difficult, so be sure to obey this rule religiously.

Wednesday, September 23, 2009

Spring Bean Constructor Args

Spring bean configurations frequently contain beans to which you pass constructor arguments. When setting constructor args, you can either reference them by index or by type. This example shows referencing by index.

<bean id="MyBean" class="com.mycompany.MyClass">
<constructor-arg index="0" ref="SomeOtherBean">
<constructor-arg index="1" ref="SomeOtherBean2">
<bean>


In this example, the spring configuration will break if the order of the constructor arguments change. A more robust way to wire this is to set the constructors by type.

<bean id="MyBean" class="com.mycompany.MyClass">
<constructor-arg type="com.mycompany.MyClass1"
ref="SomeOtherBean">
<constructor-arg type="com.mycompany.MyClass2"
ref="SomeOtherBean2">
<bean>


Now if the order of the constructor arguments change, the bean configuration does not need to change.

It's not always possible to do this, particularly if you have multiple constructor arguments of the same type (although you can mix and match by index and by type), but I recommend referencing by type whenever possible.

Monday, September 14, 2009

Continuous Integration and Dependency Management

If you're not using continuous integration and dependency management systems, you should be. I use Maven with Hudson, and the results have been spectacular (although Hudson/Cobertura seems to have some issues with double reporting test coverage in maven2 projects, but I've been able to work around that).

My introduction to continuous integration was a few years ago, and I immediately saw the benefits of the continuous build. I was working on a multi-site team and didn't always know what everyone was doing at any given time. Having a continuous build gave me a high degree of confidence that the system was working reasonably well. I knew when tests broke immediately and it was generally clear where the problems were occurring so they could be fixed easily. Watching the build logs, I could see which parts of the system were most active and it was easy for me to focus on learning more about those parts. But, I think by now a lot of us have seen these benefits.

Dependency management, on the other hand, seems to be a newer technology. Although Maven and ant have been around for a while, in projects I've worked on, they weren't as widespread. If you aren't using a dependency management system, you're probably doing something like uploading the .classpath file from Eclipse into your repository, which now binds everyone to Eclipse, or people are responsible for manually setting the project in their IDE to link to all of the libraries in the lib folder and finding that something doesn't work when a new library gets added.

Enter the POM. In maven, the POM has a nice, clean declarative xml syntax for declaring a dependency.

<dependency>
<groupid>org.apache.maven</groupid>
<artifactid>maven-project</artifactid>
<version>${mavenVersion}</version>
</dependency>


And that's it, now you've pulled in the maven-project jars (maven supports transitive dependencies as well, so if X depends on Y, and you import X, it will import Y as well). Maven provides an impressive central repository (http://repo1.maven.org/maven2/) and there are numerous repository manager tools (Apache Archiva and Sonatype Nexus for examples). If you haven't realized by now, I'm excited by Maven and happy to rid myself of ant.

Tuesday, September 8, 2009

Automated UI Testing

I've often been asked how to automate testing for a UI. There isn't an easy solution to this problem, and automated UI testing is very difficult. An application's UI is frequently changing, sometimes just minor layout changes, and sometimes major reworks. Regardless, the change can be enough to throw off a lot of automated UI testing tools. So does that mean we shouldn't test the UI?

Every situation is different, but these are a few tips that will help make automated UI testing easier:

  1. Make the UI as thin as possible. Don't put business logic in UI components, even though it can be tempting (patterns such as Model-View-Controller help with this). An example:
    Difficult to test:

    JButton button = new JButton("Check if even");
    button.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
    int num = Integer.parseInt(numberField.getText());
    if ( num % 2 == 0 ) {
    System.out.println("num " + num + " is even");
    }
    }
    });

    This is difficult to test because now the whole UI needs to be brought up just to test this function, and this is not conducive to automated testing. This can be refactored as follows:

    JButton button = new JButton("Check if even");
    button.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
    int num = Integer.parseInt(numberField.getText());
    if ( NumberUtils.isEven(num)) {
    System.out.println("num " + num + " is even");
    }
    }
    });

    public static class NumberUtils {
    public static boolean isEven(int num) {
    return num %2 == 0;
    }
    }

    While this may not look like a big deal, the change is signficant. The NumberUtils class can have a simple unit test written for it and now that code is being tested outside the UI. It's easy to see that as functions become more complex, it becomes even more important to move them outside the UI logic.

  2. Wait until the last responsible moments to write UI tests. Don't write automated UI tests while the UI is still in a great state of flux. You'll spend more time maintaining them than you will find useful. This will vary from project to project, but I find this doesn't generally happen until later on in the project.

  3. Maintain automated UI tests like you maintain code. They should be run as part of a regression test (even if it's a nightly test as opposed to a continuous build since they may take longer to run). They generally can't be simple record/playback tests. While this is a good place to start, they really should be refactored by a developer to make sure that when the UI changes and tests break, minimal changes will be needed to the UI tests. For example, if multiple tests are looking for a particular table column, make that a static string somewhere (or even reference it from the code under test if you can and the string itself is not under test). This way if the string changes, you don't need to update the string in multiple places.
You may find that you don't have the time or resources to write automated UI tests. It's the hardest thing to test and usually gets cut from testing first. If you're not going to have automated tests for it (and even if you are), be sure that UI code only includes UI related functionality, not the algorithms being invoked by the UI.

Wednesday, September 2, 2009

Software People Will Use

I recently listened to a talk by Joel Spolsky (http://blog.businessofsoftware.org/2009/09/joel-spolskys-talk-at-business-of-software-2008-on-being-number-one.html) on making software that is number one in the industry and it inspired me to write a bit about it. He talks about 3 key points behind this, but the ones I want to focus on are making the user happy and obsessing about aesthetics. I think these are keys to any good piece of software, not just the industry leaders, although we should all strive to be there, especially if we are in the business of making money.

I'll start with obsessing over aesthetics. As developers (he discusses this in his talk, but most developers probably know this), we don't spend a lot of time thinking about aesthetics. We're concerned with making sure the software works, and if it works, that is what's important. True, this is important, but there's a lot more than just making it work. The first thing the end user sees are the aesthetics. If the software doesn't look nice, it will be off-putting. Remember, most users aren't programmers! The users are our customers, and we need to make a product that will appeal to them.

That leads me to the point of making the user happy. There are various ways to make the user happy. Spolsky talks about putting the user in control of the software. Make it easy to use, but let the user feel like they are controlling what happens. It shouldn't take a programmer to use it. I like to think software should be simple, yet sophisticated.

I recommend watching this talk, but if you don't, the key takeaway I took from it was that the software is all about the user. While we should already all know, this talk was a nice reinforcement.

Monday, August 31, 2009

protected variables

I don't like protected variables. I hardly ever use them, and generally don't think they are useful. Making variables protected (or default access) exposes them to many of the same problems that public variables have, yet while we all (should) shutter at the thought of public instance variables, we generally don't as much for protected.

protected variables allow for multiple entry points. take the case:

public class MyClass {
protected int myProtectedVar;
private int myPrivateVar; // setters and getters omitted, but exist
}

public class Client {
private final MyClass mc = new MyClass();

public void doSomething1() {
mc.myProtectedVar = -1;
mc.setPrivateVar(-1);
}

public void doSomething2() {
mc.myProtectedVar = -2;
mc.setPrivateVar(-2);
}
}


Imagine multiple classes accessing the variables this way. At some point in development, I realized I have a bug where these variables are being set to the incorrect values so now I want to log the sets of the variables.


// easy case for the private variable
public void setPrivateVar(int i) {
LOGGER.debug("Variable i set to " + i);
this.myPrivateVar = i;
}


It should be clear now that the protected variable has no single entry point to log. While this is a trivial example, it can be extended to other concepts, such as validating inputs. It becomes even more of a problem if the variable is say a List. Now the protected variable is exposing the actual list, as opposed to returning an unmodifiable copy of it. Tracing problems gets extremely difficult, very quickly.

Exposing protected variables also discourages the "tell, don't ask" principle. By accessing the variable, you are querying the state of the object presumably to do something based on that state. Rather, you should be telling the object what to do and it will look at its own, private state.

I often hear arguments that it's ok to use protected (or even public) variables for final fields in lightweight data containers (or data transfer objects). I still don't like this because you lose the single entry point to do any sort of action on the data (validation, logging, etc). I generally find that exposing protected variables is a smell that too much internal state is being exposed.

Sunday, August 23, 2009

Spring Managed Singletons for Testability

I was recently writing some code that launched and external application and I never wanted to have more than one instance of this application running at once, so I immediately thought to make it a singleton. So, I started out with typical singleton code:

public class MySingleton {
private static final MySingleton INSTANCE
= new MySingleton();
private MySingleton() {
// initialization code here
}
public static MySingleton getInstance() {
return INSTANCE;
}
public Object getSomethingUseful() {
return somethingUseful;
}
}

I had a couple of classes that used this singleton, typically something like this (the method below doesn't do anything practical, it is just used for illustration):

public class SingletonUser {
public void doSomething() {
MySingleton s = MySingleton.getInstance();
Object o = s.getSomethingUseful();
if ( o == null ) {
throw new NullPointException("error");
}
System.out.println("Got the object o");
}
}

The test for the class looks something like:

public class SingletonUserTest {
private SingletonUser su;
@Before
public void setUp() {
su = new SingletonUser();
}
@Test(expected=NullPointerException.class)
public void testDoSomethingWhenGetSomethingUsefulIsNull() {
// do something to make
// su.getSomethingUseful to
// return null
su.doSomething();
fail("NullPointerException expected");
}
@Test
public void testDoSomethingWhenGetSomethingUsefulIsNotNull() {
// do something to make su.getSomethingUseful
// to return something non-null
// redirect System.out to a stream so we
// can test its contents
su.doSomething();
// do some asserts to make sure the stream
// was properly printed
}
}

So what's the problem with this? The line in the testDoSomethingWhenGetSomethingUsefulIsNull that sets the singleton object make sure O returns null. First, the test doesn't ensure that the singleton is reset back to the default state. The singleton may not provide this method (nor should it need to). Second, the singleton may not have easy methods for testing all of the conditions required. A typical solution is to add methods that are used for testing only, which I don't like at all. So what should you do?

Inject the singleton like you would any other bean in Spring and let Spring manage the singleton.

public class SingletonUser {
// A reference to the singleton
private MySingleton s;
public SingletonUser(MySingleton s) {
this.s = s;
}
public void doSomething() {
Object o = s.getSomethingUseful();
if ( o == null ) {
throw new NullPointException("oops");
}
System.out.println("Got the object o");
}
}

Now this class is much easier to test. You can mock out the MySingleton like you would any other class, but in production, the spring bean file would like something like:

<bean id="MySingleton" class="my.pack.MySingleton"
scope="singleton"/>
<bean id="SingletonUser"
class="my.pack.SingletonUser">
<constructor-arg type="my.pack.MySingleton"
ref="MySingleton"/>
</bean>

Now the nastiness of the getInstance calls will be removed and the code is easily tested.

Tuesday, August 18, 2009

Collective Code Ownership

Whether you're practicing agile, XP, or even waterfall, I'm a big believer in collective code ownership. Few things bother me more than another developer asking "Hey, is it okay if I modify your code?" with the exception of other developers getting angry when I modify "their" code.
The general rationale I get from non-believers is that someone changing the code may not know what they are doing and thus the code may break. I have a couple of problems with this:
1. Unit tests should be testing the code, especially if you're worried about it breaking. When any developer makes changes, if the tests are all still passing, you should be able to safely assume the code is working properly.
2. Developers generally aren't just going around changing code without knowing something about it (or at least they probably shouldn't be). And if the developer doesn't know too much about the area, they will (or should) ask someone that does know about it. In my opinion, it's definitely acceptable to have a person or people that are the points of contact for a given area of code. If you need help with it, ask them, but points of contact and code owners are very different.

Individual code ownership promotes blaming/praising individuals. While it is certainly important to know who is contributing what, a software team succeeds or fails as a whole. Sure, different people may contribute more than others, but if the product is not successful, the whole team fails. And that's really the bottom line.

Sunday, August 16, 2009

Why You Should Test "Prototype" Code

Too often developers create "prototype" code that makes it into the codebase without being tested. How does this happen? Maybe a developer is just testing one of many possible solutions and doesn't want to test code that he might throw away (hint: this sounds like a good place for TDD). Another common place I've seen this happen when you're prototyping ideas for a end-user to try out, and you don't even know if they'll like it, so you don't bother with the tests up front. I've seen this latter case happen most frequently when requirements are not well defined and the customer isn't entirely sure what they want.
Regardless of how this code gets in there, once it's part of your production code baseline, it's not prototype code anymore, it's production code. In an ideal world, we'd write all of our tests up front and we'd never have any untested code. While this doesn't always happen, when we do put that untested code in the baseline, be sure to go back and write the tests for it before moving on to the next feature. You and future developers will be glad you did.