A Django site.
January 2, 2008
» [Java] Don’t call subclass methods from a superclass constructor

When designing a class for subclassing, it’s important to avoid calling any method that the subclass could or must override from the superclass constructor. This includes any non-final public or protected methods (either abstract or concrete). The only methods that are appropriate to call from the superclass constructor are final methods or private methods in the superclass.

Unfortunately, this mistake is all too easy to make – I’ve made it myself lots of times. Usually, this is done because the superclass has some invariant that must be enforced, and part of enforcing the invariant involves calling at least one method that the subclass could or must override.

For example, consider the following contrived class:


class SuperClass {
private final FooBar fooBar;
private String message;

public SuperClass(FooBar x) {
fooBar = x;
message = computeMessage(x);
}

protected String computeMessage(FooBar x) {
return x.someMethod() + "..."; // details of the message are not important for this example
}
}


This class exhibits the problem this entry describes. Class ‘SuperClass’ is designed for subclassing, but it calls an abstract method from its constructor. The intention of this class is to enforce the invariant that the ‘message’ field will never be null after construction, and computing the correct value for the ‘message’ field involves the subclass. Even though this is a contrived example, many needs for calling subclass methods from a superclass constructor have this form in essence.

The reason this is bad is because in Java, superclass constructors run before subclass constructors (that is, a subclass must invoke super() before other statements in its constructors). By invoking a subclass method, code in the subclass will be invoked before the subclass gets a chance to initialize itself. The subclass will see default values for all its fields, and will not have access to any data passed in the subclass constructor.

For example, consider the following subclass of the class given above:


class SubClass extends SuperClass {
private MessageHelper helper;

public SubClass(FooBar x, MessageHelper helper) {
super(x);
this.helper = helper;
}

protected String computeMessage(FooBar x) {
return helper.getMessage(x); // NullPointerException!
}
}


In this example, the subclass takes a helper object in its constructor. The helper object is used in the overridden abstract method. However, because the superclass constructor calls the abstract method, the subclass does not have a chance to assign the helper object to a field (its constructor has not run yet). This requires the subclass to either guard for this condition (but what should it do when the condition happens?) or contain a NPE bug as in the example above.

Fortunately, this problem is easy to fix with the following design pattern. First, observe that there are two issues at play here: (1) enforcing an invariant and (2) designing for subclassing. The best way to satisfy both issues is to make the superclass abstract and require (through documentation) that all subclasses enforce the invariant in their constructor.

For example, here is a fixed version of ‘SuperClass’ and ‘SubClass’ from above that fix the problem:


abstract class SuperClass {
private final FooBar fooBar;
private String message;

protected A(FooBar x) {
fooBar = x;
}

protected final void initialize() {
message = computeMessage(fooBar);
}

protected abstract String computeMessage(FooBar x);
}

class SubClass extends SuperClass {
private MessageHelper helper;

public SubClass(FooBar x, MessageHelper helper) {
super(x);
this.helper = helper;
initialize(); // subclass MUST call initialize
}

protected String computeMessage(FooBar x) {
return helper.getMessage(x); // no NullPointerException
}
}


The superclass is made abstract to avoid the possibility of creating an instance in which the invariant is not satisfied. This is OK, since a fundamental part of this design is to allow for subclassing. In addition, all subclasses must call the protected initialize() method from their subclass constructor. If they fail to do so, the superclass-subclass contract is broken and invariants can’t be guaranteed.

The fix may be considered a little cumbersome. It requires the creation of at least one other class (since before the fix, the superclass could be used directly). The fix also requires (but can’t enforce through the compiler) that subclasses all follow certain rules. However, these tradeoffs are much better that having the situation in which subclass code is invoked before the subclass can initialize itself. By the way, I am pretty sure this issue is also discussed in Effective Java (I’d be sure, but I don’t have a copy handy at the moment).




October 15, 2007
» Managed Environments

When writing Java code, it’s useful to differentiate between two types of targets: a “normal” environment and a “managed” environment [1]. The difference between the two is simple. In a normal environment, you (the person writing the code) call the main() method [2]. In a managed environment, you do not. Managed environments are sometimes called container environments because they usually follow a containment or hosting model. In this model, the host container is the code that contains the main() method, and independent units of third-party code (hereafter plugins[3]) are managed by the container.

One of the most familiar examples of managed environments to most Java developers is the application server model used to host server-side Java applications. Such an application server can range from a full-blown JEE container implementation to a smaller-scale operation that hosts servlets with possibly a few EE features. Another example of a managed environment that most Java developers will have interacted with is the Eclipse IDE. Eclipse is entirely built around a container model (for the last few versions, that model has been OSGi). Users of Eclipse need not know or care about this, but anyone who writes plugins for Eclipse must understand the model and its implications.

It’s helpful to think about the differences between managed and normal environments. In theory, the environment should be mostly transparent to the code executing in that environment. In practice, however, there are some issues that need to be considered. This is especially true if you are writing library-level code: some libraries are much more “container-friendly” than others. If you are writing application-level code this may or may not be an important issue for you. Occasionally, you might have a single code base that you want to use in both types of environments.

The biggest difference between the two types of environments is the classloader layout. Normal Java environments are usually pretty simple in this regard [4]. Without going into unnecessary detail, this layout contains a bootstrap classloader that loads the system classes (like java.*) and an application classloader that loads everything else, including the classes that you write and any libraries those classes depend on. In contrast, a managed environment usually implies a more complicated classloader hierarchy. There will typically be a separate classloader for each plugin. There will often also be one or more classloaders in the hierarchy to support the container itself, and one or more classloaders that are shared among all of the plugins [5].

Why is the classloader layout important to think about? Two big reasons: visibility and static variables. Visibility is a simple property that has to do with the relationship between classloaders. Class A has visibility of class B if A’s classloader is able to load class B. Visibility becomes important in a variety of contexts. For example, many APIs will instantiate objects for you. In order to do this, they might need to have visibility of the class to be instantiated [6]. Static variables are associated with a class instead of an instance of that class, and are often used to obtain global variable semantics in Java. However, static variables aren’t really that similar to global variables – they do have a scope, and that scope is the class they are associated with. Such variables are only visible to classes that have visibility to the static variable class. If two different classloaders in the application each load a class that defines a static variable, there will be two instances of that variable. This situation may or may not be anticipated by the author of the class.

In the “normal” environment, it’s hard to make things go wrong classloader-wise. Any libraries your application code has dependencies on are pretty much guaranteed to have visibility of your code, since there’s essentially just one flat classloading space. Any static variables behave mostly like global variables for the same reason. In fact, you can pretty much ignore many classloader issues in a normal environment.

In a managed environment, there is much more potential for things to go wrong. As mentioned above, each plugin will have its own classloader. Most managed environments have complicated rules or configuration options that govern the relationships between the plugin classloaders, any shared classloaders, the container classloaders, and the bootstrap classloader. Since there is not a flat classloading space, visibility issues come into play. For instance, a library may not be able to instantiate an object because it does not have visibility to a classloader. A class may be loaded twice, and then both versions of the class may be attempted to be used in the same context (leading to very confusing ClassCastExceptions!). In short, all kinds of problems can happen, and debugging them can make for hours and hours of fun.

A particularly interesting problem that often occurs in managed environments is an insidious type of memory leak. Managed environments often provide for some amount of dynamic loading and unloading of plugins at runtime. This is most often implemented by discarding the plugin classloader when the plugin is unloaded. The plugin classloader contains references to all of the plugin classes, which in turn contain references to any static variables defined by the plugin. If all goes well, the garbage collector can reclaim the plugin classloader and everything referenced by it. However, it only takes one outside reference to a single object from the plugin to keep the classloader from being garbage collected. This is because every object has a reference to the classloader that loaded it. It turns out to be very non-trivial to cleanly unload a plugin at runtime – just perform a web search for “classloader memory leaks” to read all sorts of war stories. The Java language and libraries are just not designed for that kind of thing. Luckily, most managed environments do not have core functionality that depends on dynamic unloading [7].

Another problem occurs with the issue of configuration. Let me skip straight to an example: using Java system properties for configuration simply does not work in a managed environment [8]. System properties have global scope – when a system property is set, the value is read by every other part of the application. In particular, system properties span classloader visibility. Suppose a managed environment contains plugin A and plugin B, both of which depend on a library which is placed in a shared classloader space. Assume further that said library relies on system properties for configuration. This is bad because plugin A can now affect plugin B’s configuration.

So when writing Java code, whether a library or not, consider the target environment of your code. Managed environments are becoming more and more common. Managed environment techniques like custom classloaders that would have been considered advanced 5 years ago are now much more commonplace, which means you’re much more likely to run into them. Managed environments, long the standby of the server-side Java space, are now increasingly popular on the desktop. The Java community is starting to take a lot of interest in standardizing managed environments [9]. If you’re writing application-level code, understand which type of environment you’re targeting. If you’re writing a library, take the time to write container-friendly code.

Footnotes:


[1] The term “managed” here means something different than another common use of the word: in the .NET world, the term “managed” refers to code that uses automatic memory management as opposed to manual allocation and freeing. That’s not the meaning I’m using in this article.


[2] That is, the public static void main(String[] args) method. In other words, you control the entry point of the Java application.


[3] Plugins may not be the best term, but “containees” or “independent third-party units of code” was just too unwieldy to use throughout the rest of the article. If you’re a server-side person, just substitute “web application” everywhere you see “plugin”.


[4] But not always. As non-trivial applications grow, they almost always eventually start playing magic classloader tricks to support various features. At that point, they start to look a lot more like managed environments from the perspective of some of the code.


[5] For example, see
this document for a description of the classloader hierarchy in one managed environment.


[6] Of course, a well-written API that does this will not require such visibility. Instead, it will either require that a classloader that does have visibility be passed, or it will make use of hacks such as the
thread context classloader.


[7] For instance, most JEE containers support hot redeploying of applications. This functionality is very useful during development but rarely enabled when the application is put into production.


[8] Despite the fact that it does not work, many libraries do it anyway. You’ve been warned! ;-)


[9] See
OSGi, JSR 277, and JSR 291.

August 16, 2007
» Simple Concurrency Guidelines for Designing APIs

When designing an API, one of the considerations you usually have to address is concurrency. In other words, for every class in the API, what is the class's threading policy? At the very minimum, an API should document how it behaves with regard to concurrent access, and even better is an API designed with concurrent access in mind.

Writing a good API that is concurrency-friendly is hard. More than anything, it requires lots of reasoning about how all of the moving pieces will work together under concurrent access. In this article I’m going to discuss a few simple guidelines you can follow when designing APIs and reasoning about concurrency. The specifics of what I’ll discuss apply to Java, although the general concepts probably apply equally well to .NET and other similar environments.

The goal is, in general, to choose the design that is the easist to reason about and still has acceptable concurrent performance and API usability. Here are four guidelines that can be used as a starting point when thinking about what the threading policy of a class should be:

1) For non-collection-oriented classes, default to immutable
2) For collection-oriented classes, default to mutable and thread safe
3) Prefer collections of immutable elements
4) For collections of mutable elements, make copies and treat the contained elements as immutable internally

These guidelines will help you to design classes that make it easier for the consumer of your API to reason about concurrency policy. This reasoning is made possible by clear documentation of each class’s design for concurrent access. Failure to consider the threading policy for a class leads to under-documented APIs, unexpected behavior at runtime, and obscure bugs that are hard to reproduce. Documenting the concurrency of an API is essential in order to guide the API’s consumers to correctly using the API.

Note that documenting an API as “not thread safe” is a valid design choice. It may not be the best choice (depending on the API). However, it is better to document that a class isn’t thread safe than to make the API consumer guess or rely on undocumented behavior that could change.

In the discussion below, I make a distinction between collection-oriented classes and non-collection-oriented classes. Collection-oriented classes contain multiple similar child objects (elements). They are usually easy to recognize since they often contain methods to add elements, remove elements, find elements, and perform similar operations across the contained elements. Collection-oriented classes shouldn’t be confused with composite classes that are made by composing together dissimilar classes.

Now I’ll go over each guideline. Remember that ultimately, we are looking at a class and trying to determine what a reasonable threading policy for that class might be.

For non-collection-oriented classes, default to immutable

Immutable classes are one of the best design choices you can make when designing an API. For classes that aren’t collection-oriented, default to using an immutable design.

Only design mutable classes if it seems that API consumers would be greatly inconvenienced by the immutable classes. Usually though, immutable non-collection-oriented classes aren’t a big hassle for users.

Immutable classes have the inherent property of being safe for simultaneous access from multiple threads. You don’t have to do any internal or external locking. This is the first big advantage of immutable classes – thread safety for free and no performance hit under concurrent access.

Another big advantage of immutable classes is that when you use them, you can more easily build a mental model of the system you’re designing. Since immutable classes are very easy to reason about, it takes less mental RAM to think about how instances will behave at runtime - they can only ever be in a single state (post construction).

Immutable classes are also a great way to set API consumer expectations. One of the most frustrating things about an API is when some class, say a service of some kind, takes a mutable object as initialization data. What happens after you hand the mutable configuration data off to the service? Are you still allowed to modify the configuration data? Does the service care? Will it break? Using an immutable class design for the configuration data instead solves these problems.

Designing immutable classes is extremely easy in Java. Briefly, here are the requirements you should satisfy when designing a class in order to call it immutable:

1) All fields in the class should be declared final
2) All fields should be either immutable objects or mutable objects that are not mutated outside of a constructor
3) The this reference does not escape a constructor
4) No mutable objects passed to a constructor are retained by the instance or any of its components
5) No mutable objects escape the instance

Satisfying these requirements is not the only way to design a thread safe immutable object, but other techniques are much harder to explain and require deep knowledge of Java’s memory model.

For collection-oriented classes, default to mutable and thread safe

When designing a collection-oriented class, the default choice should be to write a mutable container that can be safely accessed by multiple threads concurrently. Most collection-oriented classes should be mutable since that’s what the API consumer will expect. When using a collection-oriented class, the most common reason is because you want to modify the collection (add or remove elements) or modify the contained elements themselves. An immutable collection-oriented object makes consumers jump through hoops to do this.

Often, collection-oriented classes in an API will be used only from a single thread for many scenarios. It can be tempting not perform the necessary locking to make these classes thread safe, since that locking will be unnecessary for the majority of usage scenarios. In this case, one valid design decision would be to skip the locking and document the collection as not being thread safe. However, doing this penalizes the users of the class who are in concurrent-access scenarios, since the burden of implementing thread safety is now on them.

I recommend going ahead and doing the internal locking to make these types of classes thread safe. On modern Java runtimes, the cost of uncontended synchronization is extremely low (JCIP talks about this in detail). Even when the common case is single-thread use, it’s better to design a class to be thread safe if there are potential concurrent scenarios. If a profile reveals that the locking is a hotspot when using the class, then you have a good reason to avoid it. Otherwise, assume that locks are essentially free when uncontended.

Although it’s not the first choice I’d make, for some APIs immutable collection-oriented classes may not be a bad decision. You get all of the advantages mentioned above for immutable classes. If API consumers will not often need to mutate the collection or the collection’s elements, doing this may make sense. For example, some collection-oriented objects are often just passed around to other parts of the API, and rarely changed. If you decide to design an immutable collection-oriented class, be sure to document this very explicitly. Also, avoid method names that imply that the receiver is being changed as they can be confusing to a casual user of the API. An immutable collection-oriented class should not have a "public void add(Foo f)" method since the signature of that method implies that it alters the receiver.

Prefer collections of immutable elements

Whenever possible, collection-oriented classes should contain immutable elements. This helps reduce confusion about the API, since it is clear that the state of the elements can’t be changed while the collection contains them. I’ve found that designs that use small, immutable objects as building blocks and contain them in mutable containers tend to be very robust and easy to understand.

The biggest reason this is important is that most non-trivial collection-oriented classes have one or more invariants that they must enforce. For instance, a collection-oriented class may store elements that each have an identifier of some sort, and the collection may guarantee that contained elements will have unique identifiers. This is just an example – often the constraints can be much more complicated. If the contained elements are externally mutable, it will be very hard or even impossible for the collection to enforce those invariants.

Mutable collections of immutable objects are also very fast to make copies of. Since the contained elements are immutable, copying the collection only involves making a shallow copy. Supporting copies of collections is important for many APIs, so anything that makes this easier and faster is a win.

For collections of mutable elements, make copies and treat the contained elements as immutable internally

Unfortunately, it’s not always possible to design using only collections of immutable elements. Often, for one reason or another, the collection must contain mutable elements. One case of this is a collection-oriented class where the elements themselves are collection-oriented. No matter the specifics, there is a design pattern you can follow in this case.

The collection should make copies of the mutable elements as they are added or retrieved, ensuring that no external clients have a reference to the actual contained instances. In other words, every time a mutable element is added to the collection, the collection makes a copy and adds the copy instead. Every time a mutable element would be obtained, a copy is obtained instead. Internally, the collection should treat the contained elements as though they were immutable and should not call any method on the elements that could change them. By doing this, the collection will contain “effectively immutable” elements. The collection is then free to enforce constraints on the contained elements and know that no external client can break the constraints.

I can attest that this kind of design works well, but it does require some careful API documentation. Without proper documentation, clients may expect that they can obtain a contained element, mutate it, and have those changes automatically show up in the collection. Instead, this kind of design facilitates a more transactional usage. Clients obtain an instance, perform some changes to it, and then must add that instance back in to the collection. This usually isn’t a huge burden on the clients as long as expectations are set correctly.

That covers the 4 guidelines. Note that these guidelines are really meant to only cover simple cases – however, the simple cases make up the bulk of most APIs. There are certainly complex classes that don’t fall easily into one of the categories above, and they will need to be designed with more thought.

March 9, 2007
» Embedded Beanshell for Runtime Diagnostics

For the Teamprise product line, I've always had a focus on providing comprehensive runtime diagnostics. This feature gets used any time we have a customer report a problem. With just a few clicks, the customer can produce a zip archive containing a complete set of diagnostic data that our support team can peruse through. This kind of thing really cuts down on the back-and-forth usually involved with customer support. I should really do a complete blog entry sometime on the entire diagnostic system, since it's a pretty neat piece of engineering. But today, I'm going to talk about just one aspect of our runtime diagnostic system.

When a customer invokes our support dialog, one of the tabs is labeled "BeanShell" and looks like this:


BeanShell is a popular script engine for Java. It interprets a lightweight, dynamically typed scripting language that has syntax very similar to Java syntax. BeanShell has a small footprint and is perfect for being embedded in other applications. Embedded BeanShell could be used for many purposes - a plug-in system, an administrative console, and lots of others. In the Teamprise support dialog, we use Embedded BeanShell to allow us to run arbitrary diagnostic commands at runtime.

The basic idea is that a Teamprise contact can provide a customer with a snippet of BeanShell code that was composed to track down a problem. The customer pastes the snippet into the BeanShell dialog, and presses the eval button. Any results of the snippet are logged as well as displayed in the dialog. The customer can then either send us their logs or report on what the output was.

Of course, for this kind of thing to be useful, the BeanShell script must be able to access important objects in the system. BeanShell has the perfect feature for this - when setting up the interpreter programmatically, you can predefine certain variables that the script can then access. We predefine variables for the Eclipse workspace, the TFS connection object, and lots of other important "root" objects in our system.

Just as an example, here is a snippet of BeanShell. When run in our support dialog this will print out all the work item queries for the first Team Project on the server:


workItemClient = tfsConnection.getClient(com.teamprise.core.WorkItemClient.class);
project = workItemClient.getProjects().getProjects()[0];
for (query:project.getStoredQueries().getQueriesByScope(null)) {
print(project.getName() + "/" + query.getName() + ":\n" + query.getQueryText() + "\n");
}

This script makes use of the predefined tfsConnection variable, which is our connection to the TFS server.

No matter how comprehensive a diagnostic reporting system is, there will always be data you don't have the forethought to collect at development time. Using an embeddable scripting language like this gives us control to run diagnostic code at runtime and allows our customers to quickly run new diagnostic tests that we create for them.

August 24, 2006
» Closures 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?).

» Java: 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.



August 15, 2006
» Java: 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.

June 30, 2006
» Eclipse 3.2 is out

Eclipse 3.2 is final as of today (downloads, torrents) (updated torrent link - thanks Martin). This is the once-a-year major new release of the Eclipse SDK (read the New and Noteworthy document for some highlights of what's been added and improved). Something new this year is that 9 other top-level Eclipse projects are being released simultaneously along with the SDK. This "release train" is codenamed Callisto.

I've been using early versions of the 3.2 SDK for months now, and just like in years past, it's a solid release. Lots of new features and better performance. Of course, we've tested our Eclipse plugin product (Teamprise) and it's working great with the new Eclipse release.

» Pack200

Perhaps you’ve heard the term Pack200 before but haven’t had a chance to become familiar with it. Or maybe you already know that Pack200 is related to deployment of Java applications, but aren’t sure how it could be used with your application. Compared to other new features of Java 5, Pack200 hasn’t gotten as much attention. In this entry I’ll answer two questions: first, What is Pack200?, and second, Why would I want to use it?

Pack200 was released as part of the Java 5 platform, and is essentially a technology for achieving much better compression ratios of deployable Java code. Java code has traditionally been packaged and deployed as JAR (Java Archive) files, which are nothing more than standard zip files with the extension .jar. Pack200 can result in radically higher compression ratios of Java bytecode when compared to traditional JAR packaging.

The name Pack200 is derived from two sources, and to understand why the name was chosen you have to know a little bit of the history of the technology. William Pugh (best known as the developer of FindBugs) released a paper detailing a number of advanced techniques for compressing Java class files. These techniques were used by Sun to decrease the size of the JRE and the JDK downloads, starting sometime around the Java 1.4.1 release. William Pugh’s ideas and the format Sun used were referred to as Pack. Around the same time period, Java Web Start / JNLP technology was becoming relatively popular and Java applets were also starting to become more popular once again. A JSR (Java Specification Request) was created called JSR 200. The JSR was created to specify a “dense download” format for Java bytecode, based on the technology presented by William Pugh in his paper and already in use internally at Sun. This technology was eventually called Pack200 (from the JSR number) and became public and supported with Java 5.

The target use case for JSR 200 was to enable more optimal web deployment of Java applications, specifically in the case of Java Web Start and applet applications. The motivation there was to reduce the download / update time for the client and the bandwidth usage for the server. Java 5 includes hooks in the JNLP bits and the browser plugins so that you can use Pack200 out of the box with Web Start applications and applets (see Sun’s deployment guide). Even though Pack200 was designed for the Web Start type scenario, it is very applicable to any type of client-side Java - I’ll explain how later on in this entry.

The Pack200 technology is intended to be a deployment vehicle, and doesn’t come into play at runtime. A Java virtual machine still works only with class files and JAR archives on the classpath – Pack200 packages must be unpacked before the bytecode inside them can be loaded into a virtual machine. The right way to think about Pack200 is that it’s a faster, more efficient way to get bytecode onto client machines.

The basic premise of Pack200 is simple. Since the JAR format is a standard, generic file format, it is not designed to treat Java class files any differently from other file types. However, Java class files have certain properties that can be cleverly used by a more specific packaging technology. By exploiting specific aspects of the Java class file format, an extremely dense representation of a collection of class files can be generated. Traditional JAR files normally achieve compression ratios of 1:2 or 1:3. It’s not uncommon for Pack200 files to achieve compression ratios of 1:10 or greater.

For an example, I took a collection of about 1000 class files that make up a library in one of the projects I’m working on right now. I created a traditional JAR archive and a Pack200 package containing these class files. The files take up 3,987,908 bytes on disk. The JAR archive takes up 1,834,269 bytes on disk, or about 46% of the size of the original class files. The Pack200 package takes up 266,803 bytes on disk – 15% of the size of the JAR file, or an amazing 6.7% of the original size.

So how does Pack200 achieve such high compression ratios? For the full answer, read William Pugh’s paper linked above. In short, Pack200 combines a number of different low level techniques, each of which exploits a different aspect of the Java class file format or Java bytecode. Among other things, Pack200:

-- Merges the constant pools of each individual class file to form one constant pool that’s shared for a collection of class files. This is a big win since many of the same constants (common class names for instance) appear in many of the individual constant pools. Basically, this technique eliminates the redundancy in the individual constant pools of class files in a package.

-- Uses delta encoding whenever possible. For trivial example, to store two Strings that share a common section of characters, only one complete String needs to be stored, and the second String is stored as a delta off the first. This kind of encoding can be applied in a lot of different areas – even storage of similar sequences of numbers optimized with this technique.

-- Implements variable length encoding. Variable length encoding allows values of the same data type to be stored using different amounts of space. For example, a small numeric value of a data type can be stored using fewer bytes than a larger value of that same data type.

-- Enables more optimal secondary compression. Pack200 packaging is normally followed immediately by a gzip stage, which reduces the size of the package further.

-- Incorporates a number of optional techniques for further reducing the size of class files. For instance, debug attributes can be stripped out of the class files.

Pack200 packing takes a JAR file as an input. A .pack file is then produced with the packed bytecode. The pack process is normally finished by gzipping the .pack file (the secondary compression mentioned above), ending with a .pack.gz file. The unpack process simply reverses the above: first ungzipping the .pack.gz file, and then producing a JAR file from the .pack file. The pack / unpack process is fairly resource intensive (especially compared to simple JARing). The pack process is done once on the server, and the unpack process is done once on each client machine at the time of install or deployment.

Pack200 has two interfaces: a command line interface and a programmatic interface. The Java 5 JDK and JRE ship with two command line tools: pack200 and unpack200. Interestingly enough, these command line tools are native C++ executables – they have no dependency on a Java runtime. There is also a class than can be used to programmatically pack and unpack – java.util.jar.Pack200.

Even though Pack200 works against JAR files, it’s not correct to think of it as a generic compressor for JAR files. For instance, a JAR file containing mostly resources will not achieve that high of a compression ratio – but a JAR file containing mostly class files will. Pack200 is a compressor for Java bytecode – it just uses JARs as input for convenience and integration with existing packaging mechanisms. The Pack200 format is lossless – run a JAR all the way through (pack and unpack) and the final JAR will be different from the original. Of course, the two JARs will be equivalent from the point of view of a Java virtual machine. This has some implications for JAR signing, so be sure to read through Sun’s deployment guide linked above if you’re going to combine Pack200 and JAR signing.

Don’t make the mistake of thinking that Pack200 is useful only for Web Start and applet scenarios. Any time there is a need to move Java bytecode from a server onto many client machines, Pack200 can be used to make life easier for both the client and server. A heavyweight Java client application could greatly benefit from Pack200. All it requires is Java 5 on the client machine, and an install routine that unpacks the Pack200 packages as part of the installation. This install routine could itself be written in Java and would make use of the Pack200 support in Java 5 (either programmatically or through use of the command line tools). An install scenario like this could reduce the download size of a client-side Java application by half or more, greatly reducing the bandwidth used by the server and the wait time on the client for the download.

A real-world example of where this technology is being successfully used outside of the Web Start and applet case can be found in the popular Eclipse IDE. Starting with version 3.2, the Eclipse update manager (used to get new Eclipse features and update existing features) will make use of Pack200 technology when Java 5 is available on the client. This will greatly reduce the wait time for updates to through the update manager, as well as reducing the bandwidth burdens on the Eclipse mirrors.

If you’re writing client-side Java applications in 2006 and haven't yet looked at Pack200, take some time to evaluate the technology and see how it might fit into your overall deployment strategy.

May 4, 2006
» JVM vs CLR memory allocation

The Common Language Runtime (CLR - virtual machine for .NET) and the Java Virtual Machine (JVM) share similar architectures, but there are lots of differences, especially when it comes to memory management and allocation. Both virtual machines have automatic memory management in the form of garbage collection - the programmer is not normally responsible for allocating and releasing memory. Both virtual machines implement multiple generations of garbage collection for performance reasons, and both manage a "heap" of memory internally for application code use. However, there are a few subtle differences that don't seem to be discussed much so I'm going to highlight them here. A caveat: what I'm going to discuss would probably be considered implementation details of Microsoft's CLR and Sun's JVM on the Windows platform. The behavior may be different in future releases, on other platforms, or on VM implementations from other vendors.

Difference #1: Fixed upper limit on the heap size

Both the CLR and the JVM manage an internal heap of memory that is used for allocations. Both VMs will grow the heap by allocating more memory from the operating system when needed. However, the JVM places a fixed upper limit on the heap size. This limit is specified by using the -Xmx switch when starting the runtime. If the JVM tries to satisfy an allocation that would result in the heap growing beyond that limit, and no garbage can be collected, then an OutOfMemoryError is thrown and the allocation fails. As far as I can tell, the CLR has no such artificial upper limit on the heap size. The CLR heap maximum size will be dependent on how much memory can be allocated from the operating system.

Difference #2: Contiguous vs non-contiguous heap

I'm a little short on details on this difference, so I won't say too much. From what I understand, the JVM implementation requires that the heap be allocated contiguously (that is, all the native memory addresses for the heap are in a sequence). The CLR does not have this requirement. For more info see this blog entry and comments.

Difference #3: Releasing allocated memory

Something that surprises a lot of programmers about the JVM is that it does not release allocated memory back to the operating system, even if it could. For a hypothetical example, imagine that a JVM process starts and allocates 25 MB of memory from the operating system initially. Application code then attempts allocations that require an additional 50MB of heap. The JVM will allocate an additional 50MB from the operating system. Once the application code has stopped using that memory, it is garbage collected, and the JVM heap size will decrease. However, the JVM will not free the allocated operating system memory. For the rest of the lifetime of the process, that memory will remain allocated, even if the heap is never grown again.

In practice, this doesn't tend to matter too much. Normally this "unused" memory will be paged out by the operating system so it doesn't tend to impact other processes.

The CLR, on the other hand, will release allocated memory back to the operating system if it is no longer needed. In the example above, the CLR would have released the memory once the heap had decreased.

Sometimes graphs can illustrate concepts much better, so to illustrate this point further I made some graphs. I wrote roughly equivalent C# and Java programs. The program attempts a series of object allocations, each one larger than the last. After each allocation in the series, the program drops all references to the allocated objects and forces a GC to happen. The graphs show the private bytes and working set (process memory usage from the OS point of view) and heap size (heap memory usage from the JVM or CLR point of view).

The Java program:



And the C# program:



Remember that these graphs are showing equivalent programs. In each graph you can read "private bytes" as the amount of memory the process has allocated from the operating system. The "working set" shows the portion of the memory pages in physical RAM. Note that the JVM will never release memory back to the OS even if its internal heap decreases. For the CLR real memory usage follows the heap size. These graphs also show an example of the fixed heap size difference: in the JVM graph, the program encounters an OutOfMemoryError at the end of the graph (this is where the heap size levels off).

For each graph, I used performance counters to capture the private bytes and working set data. For the JVM graph, I used JSE 5 JMX memory monitoring (MemoryMXBean) to get the heap size. For the CLR graph, I tried using the CLR performance counters to capture the heap size, but it didn't work for me. I ended up using GC.GetTotalMemory() which worked fine.

April 21, 2006
» XSD to SAX Parser Generator

Motivation

It's always a nice feeling to end the work week by doing something cool. Every software job has the fun, exciting parts that you look forward to, and the boring parts that no one wants but still have to be done. Something I try to do is to save at least one cool thing each week for Friday afternoons - leaving for the weekend on a high note always seems to make the next Monday feel better.

So today I made some time to do something I thought was pretty cool: a code generator that creates a SAX-based XML parser in Java. The input to the code generator is an XML Schema (XSD) file that describes the XML format, and the output is a bunch of Java classes that do typed XML parsing based on the schema.

For a feature I'm currently in the middle of, I needed to parse some XML that has scant documentation. Luckily for me an XML Schema existed...

Why Code Generation?

I could have used some third party XML databinding library (like Castor), but that didn't feel like a good fit. I wanted a simple and fast parser, and didn't want to pay the tax of yet another dependency for an ancillary need (my project already has dependencies to the tune of an 18MB download :-)).

Of course, I could have just written a SAX parser by hand. In fact, I did write one by hand at first. As I was writing it, I kept thinking about how much of the code was very similar, and how the code was prone to typos. The particular schema I'm parsing is kind of complex, and I wanted to be certain my parser was 100% correct.

So I decided to write a code generator instead. The generated parser wouldn't have any typos, and I could spend my time writing interesting code instead of copy-and-pasting similar blocks of SAX parser code. Also, if my project needs to generate parsers for other schemas in the future (which is likely on this project), it'll be simple - the code generator is generalized and doesn't make many assumptions about the input XSD.

Technical Description

The code generator is pretty simple. The generator itself uses SAX to parse the XSD and build an in-memory representation of the types in the schema (xs:complexType and xs:simpleType) and the relationships between the types. The type model is then fed to the codegen engine, which uses the Jakarta Velocity templating engine to create the output Java files.

This was the first time I've used Velocity, and it worked really well. When I've done code generators before, I've either done ad-hoc templates or embedded code as strings inside the generator classes. Using Velocity allowed me to cleanly separate the codegen engine and the templates themselves, and the final product is much more understandable than other codegen layers I've written before. Velocity is very easy to learn and use - highly recommended.

The code generator uses 5 different templates. 3 of them are for representing the XML data as Java objects - there's a template for first-class Java objects that correspond to xs:complexType types, a template that creates a base class for the complex types, and a template for the xs:simpleTypes that I wanted to represent as classes. Usually the xs:simpleTypes can be modeled as primitives, but occasionally (like xs:enumeration, for instance) it makes more sense to have them be classes. The remaining 2 templates cover the parser class itself and a class containing constants that appear in the XML (like element and attribute names).

An interesting implementation note - I originally tried writing the codegen with very fine-grained templates. That designed used basically a template for each code block that was repeated. This didn't work out well - a lot of the templating logic was in the code generator instead of in the template. Once I moved to coarse-grained templates (a template per class), the code generator got a lot cleaner. This required using things like Velocity #foreach constructs inside the templates.

The most complicated part of the generator is the part that models the XML schema types and the relationships between them. I spent the longest amount of time on this, but once it was right everything else fell into place.

Conclusion

It feels great to feed an XSD into my code generator and see the parser code get spit out. If you want something in between XML databinding and writing parsers by hand, code generation of parsers is a good way to go.