About This Blog

Hi, I'm Ben Pryor. This blog contains my thoughts about general software engineering topics, and occasionally specifics that I find interesting. If you see something here that sparks your interest, please feel free to comment on a post or send me an email at ben at benpryor.com.

23 August 2006 - 20:39Closures for Java

It looks like there’s a very good chance that the Java language will finally get closures. This is, of course, a direct result of the influence of the programming techniques that Ruby (and Rails) has popularized. After all, Sun has considered the issue of closures before. Back when Microsoft had J++ Sun published a whitepaper declaring that a new J++ feature called delegates (a form of closures) was totally unneccessary. The Sun party line has always been that inner classes provide all the benefits of closures without adding additional language constructs.

Of course, J++ is now gone, Microsoft has .NET (with delegates), Ruby on Rails has exploded in popularity, and Java programmers are starting to envy their counterparts who can do in one line of code what takes them 5. Maybe inner classes aren’t the answer to everything. Heck, maybe even objects aren’t a panacea.

I really hope this makes it into the language. My top three wishes for the Java language are closures, type inference, and eliminating checked exceptions, so it’s great to know that at least one of those has a chance at being reality. Of course, as the closures feature is slated for Java 7, it will still be many years before most Java programmers will get to use closures in day to day work (how many shops are still on Java 1.3?).

No Comments | Tags: Uncategorized

23 August 2006 - 20:04Java: Advantages of Interfaces

Occasionally I hear the claim that creating an interface is only justified if there are multiple implementations of the interface. Developers will sometimes claim that an interface with only one implementation is a violation of YAGNI or is an example of an unnecessary complex (ie overengineered) design. While it certainly is possible to misuse and abuse interfaces, claims like these show misunderstanding of some of the most important reasons for using an interface.

Interfaces are commonly used to provide polymorphic behavior, and this is of course a valid use. It’s also the way that interfaces are usually taught, so this is the scenario that many developers associate with interface use. However there are lots of other uses for interfaces, including some that involve only having a single implementation.

Contracts

If you asked me to define what an interface is, I’d reply that an interface defines a contract. Of course, a class defines a contract as well, so I should refine that definition. An interface defines an only a contract - nothing more. I often use interfaces solely for the purpose of clarifying an existing implicit contract between two classes and making it explicit.

Why is it important to think in terms of contracts? It’s all about coupling. Explicitly defining the contracts in play during class interactions forces you to think hard about how coupled together classes are. Thinking in terms of contracts often leads to refactorings that can greatly improve the design of code, which leads me to…

Separation of Concerns

Here’s an experiment. Randomly choose one of the biggest classes in the codebase that you work on (remembering that this article is primarily about Java and Java-like languages). For many projects this would be a class that’s more than a few thousand lines long. I’m going to make a claim that the majority of the time, this class is suffering from either a) lack of separation of concerns, b) duplicated code, or c) both. If the class contains many blocks of code with a striking resemblance to each other, it’s probably a victim of the copy-and-paste coding technique, and a little bit of refactoring might go a long way towards cleaning that up. On the other hand, if the class contains lots of dissimilar code it’s probably a “spaghetti” class and could use some separation of concerns.

Interfaces are great for separating out concerns in a class like this. By identifying each concern, writing an interface that defines that concern, and then altering the class to code to the interface, you can greatly reduce the size and complexity of the class. (Arguably, you may also be increasing the overall complexity of the system - it’s always a tradeoff). I would almost always rather see a set of small classes with interfaces that define the contracts between them rather than one huge mangled class.

API Publishing

Interfaces are great to use when publishing APIs. By publishing an interface and keeping the implementation undocumented and internal, you can achieve benefits for both the API producer and consumer. Producers gain the advantage of having a clear delineation between what is API and what isn’t, and consumers won’t be tempted to depend on “implementation details”.

Interfaces are a reification of the “what not how” principle of design. By publishing only the “what” as public API, you are free to make internal structural changes to the “how” without causing any client breakages.

Of course, the argument is often made that abstract classes are better for APIs than interfaces because more changes can be made to an abstract class without breaking existing clients. There is certainly merit to this argument, but I think it is mostly true when interfaces have been misused. Interfaces should be short and focused. There are many techniques for evolving an interface based API, most of which involve using composition and adapters to allow for both new and old interfaces to coexist peacefully.

Use Interfaces

Interfaces carry few costs (including having little or no performance costs) and have many advantages that go beyond simplistic polymorphism use cases. Interfaces have the ability to break up complex designs and make clear the dependencies between objects. There are many important use cases I haven’t even touched on at all, like using interfaces to make objects more testable and using interfaces to increase configurability of systems.

I like to think of interface use as a tool for increasing the clarity of my designs, and it’s a tool I’m glad to have in my toolbox.

No Comments | Tags: Uncategorized

15 August 2006 - 16:25Java: Dynamic Proxies and InvocationTargetException

Recently I was fixing a bug in some code I’m responsible for, and the bug was interesting and general enough to share the details of.

A common approach in Java is to use dynamic proxies to provide decorator-style behavior. Doing this allows you to add additional behavior “around” an object without the object itself or it’s callers being aware of the decorating. The only requirement to use this built-in dynamic proxying is that the object must be accessed through an interface (third-party bytecode generation products like cglib do not have this restriction). For an example of how this technique is used, see my entry about Java active objects.

The key part of creating a dynamic proxy is to implement the InvocationHandler interface. The dynamic proxy object (which is generated by Java library code) calls the invoke method of this interface to dispatch method invocations at runtime.

An extremely common pattern is to implement the InvocationHandler interface something like this:

class MyHandler implements InvocationHandler {
    private Object delegate;

    public MyHandler(Object delegate) {
        this.delegate = delegate;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // wrapping behavior could go here, before the real method is invoked ....
        Object value = method.invoke(delegate, args);
        // ... or here, after the real method returns
        return value;
    }
}

The idea here is that the dynamic proxy is providing some AOP-style behavior (resource management, logging, security, etc), but the real work is being done by a delegate object. The delegate object directly implements the interface that is being proxied, and all of the interface methods are forwarded to the delegate by the InvocationHandler (using Java reflection).

There is a subtle bug with the above code, and any InvocationHandler written as above should be treated as suspect.

If you read the documentation for the java.lang.reflect.Method.invoke method you’ll see that it can throw an InvocationTargetException. This occurs when the method being reflectively invoked throws any exception.

Part of the reason the InvocationTargetException class exists is because of Java’s checked exceptions. Since reflectively calling a method could result in a checked exception being thrown but not handled (since the signature of Method.invoke does not declare it), all exceptions thrown by the target are wrapped in a checked InvocationTargetException, which is declared in the signature of Method.invoke.

Normally when calling Method.invoke() the InvocationTargetException must be explicitly handled, since it is a checked exception. However, in the above case we’re calling it from inside an InvocationHandler’s invoke method, whose signature declares that it throws Throwable. Because of this, it is very easy to write an InvocationHandler that throws an InvocationTargetException out of its invoke method (which the above code will do).

Now if you read the documentation for the InvocationHandler.invoke method, you’ll see that it describes how Java dynamic proxies respond to any Throwable thrown out of the InvocationHandler. In particular, if the exception is either a checked exception that is declared by the proxied interface, or is an unchecked exception, it will be propagated directly to the caller of the proxied method. However, if the exception is checked and is not declared by the proxied interface, it will first be wrapped in an UndeclaredThrowableException. This is analogous in some ways to how Method.invoke wraps all exceptions in an InvocationTargetException. Again, the reason has a lot to do with the checked exception system in Java.

Remembering that InvocationTargetException is a checked exception, what this all boils down to is that any InvocationHandler written as above does not explictly handle the InvocationTargetException from Method.invoke() and will end up propogating an UndeclaredThrowableException to client code. The client code calling the proxied method is hardly ever going to expect this exception.

Given that most of the time, the goal of dynamic proxying is to provide transparent proxying of a service, this situation is hardly going to result in transparency. When client code invokes a proxied method, and the “real” implementation throws any exception (checked or unchecked), that exception should propagated to the calling client code. Any other implementation will result in client code that needs to be aware of the proxying, which means losing one of the main advantages of using dynamic proxies in the first place.

Here’s the correct implementation of the InvocationHandler.invoke() method from the above code:

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    try {
        Object value = method.invoke(delegate, args);
        return value;
    }
    catch (InvocationTargetException ex) {
        throw ex.getCause();
    }
}

This implementation has all the right properties: any exception (checked or unchecked) thrown by the “real” method will be directly propagated to callers of the dynamic proxy. Re-throwing the InvocationTargetHandler’s cause will not repopulate that exception’s stack trace, so the client code will be able to see the real cause of the exception including the original stack trace.

If the thrown exception will propagate all the way to the top of the call stack, the distinction between the above two methods doesn’t really matter much. That is, in the case where the exception is totally unexpected by client code and will be caught by a top-level exception handler, the second approach isn’t technically needed. However, client code often explicitly handles exceptions and performs some sort of recovery. The only way to allow client code that does that is to properly handle the InvocationTargetException as in the second code example.

Admittedly the first code example is buggy. However, a lot of this complexity could have been avoided were it not for the Java language’s checked exception design. This feature is a source of controversy among Java programmers - some love checked exceptions while others have grown to hate them. I admit that I can see both sides of the argument, but I fall firmly on the side of the fence that says checked exceptions were a nice experiment but have proven to be a failure.

Note:

One commenter noted that InvocationTargetException.getTargetException() should be used instead of getCause(). The two methods are actually equivalent for InvocationTargetException, so using either works.

No Comments | Tags: Uncategorized