Jan 242006

Another year of rejections from JavaOne and I’ve finally written them back asking for comments on the selection process. The thing that is hardest to swallow about JavaOne and their selection is that the topics I submit are definitely viable and important topics. I’m not just saying that either, because both topics I’ve submitted have either gone on to be published in well known journals or have been accepted to other conferences.

So, there are a couple of situations:

  1. My submission is lacking in descriptiveness and therefore the selection committee rejects it because they don’t understand what the presentation is about
  2. The JavaOne selection and therefore the entire conference has given up on the hard problems or challenging topics
  3. The JavaOne selection ignores anything that isn’t desktop, the latest JDK, the latest J2EE or the latest open source frameworks

I hate to think that JavaOne has given up on the challenging topics, but if you know me then you know I rarely cover the basics but love to work on and talk about the tough problems. So, it is possible that these topics just aren’t geared towards JavaOne. I really hope that isn’t the case.

What it really comes down to is either my submission is poor or JavaOne is only interested in the latest topics. I’m not against the latest and greatest thing out in the OS world nor the latest and greatest J2EE container or application but I’m just not going to present on those because they aren’t solving the tough problems like distribution, versioning, dependencies, deployment, configuration, runtime management, configuration migration, application migration, and much more. So, if JavaOne is truly gearing things towards the latest and greatest, I’ll just have to wait until the latest and greatest starts solving all the problems I’m attacking.

Jan 172006

Versioning keeps coming up everywhere in Java. Probably because the Java language is used to run huge applications and guess what, some things change and others don’t (or at least not at the same rate). Not to mention that Java is just awful at versioning of anything.

One thing I’ve come to realize over the last several years is that certain objects should not be serialized. This class of Objects include any class that does readResolves for object replacement. Most people are thinking, “wait, the new JDK 1.5 enums and all those cool type safe enums we’ve been using for ages fall into that category,” and they’d be correct. There are a number of issues with using readResolve in serialization but for the most part returning null or throwing exceptions is the biggest problem especially when clients are expecting results.

When using the type safe enum pattern and the serialized version comes across the wire but your local version of the type safe enum doesn’t have the enum value that was serialized you have two choices:

  • Throw an exception
  • Return null from readResolve

Neither of these cases is ideal. You could also create a new instance of the enum class and add it to the local storage mechanism (usually a Map). However, when the enum contains multiple member variables that are usually statically initialized, you’re screwed.

JDK 1.5 takes the first solution and throws this exception:

This and the returning null solution, which will ivetiably result in a NullPointerException, are both bad options. But, if you’ve made the choice to use enumerations and serialize them, you might hit these cases.

One problem with JDK 1.5 is that all enums are automatically serializable and developers have no choice in the matter. This means that the first novice developer or even a seasoned developer that hasn’t been bitten with the errors mentioned above will decide to pass an enum across the wire; you just can’t avoid it unless you dictate that JDK 1.5 enums are off limits. You can still use enumerations though, just make sure they don’t implement Serializable.

All of this only occurs when enums change. If you have an enum called Foo that looks like:

Then you realize that you also need a THREE:

You update the server and the clients you know about. However, you missed one and the client calls a service on the server, which returns Foo.THREE. The client is going to throw the exception above. Likewise, you probably ended up reving clients who really didn’t care that there was a new value of Foo solely because you don’t want runtime exceptions. This is just unnecessary and can be fixed by simply converting Foo to a POJO or better yet in this case a String. This way clients never throw exceptions when deserializing Foo.

Jan 162006

I just finished a large refactoring of the Savant dialect code in order to add support for dialect dependencies. Since it is always ideal to break down pieces of functionality into logical units and then introduce well defined dependencies, I went ahead and did that with Savant dialects.

I was thinking of using traditional getter/setter or constructor DI for this thing, but the more that I thought about it, the more it didn’t seem to fit. In order for those types of systems to work you need a rather complex configuration and usually some id mechanism to identify dependencies. You can also use type DI that does all of the work based on the types of parameters passed to constructors and JavaBean properties. Dialects shouldn’t be required to define dependencies on a specific class since they might not have that class in their classpath. Likewise, a large configuration file seemed to be messy and would really clutter things up (although it might work in the future if I need to give that a shot).

Instead, I added a method that takes a Map, which contains the dependencies to the Dialect interface. This seems best and most practical for now. Now I just have to tackle the versioning problem and then get back to writing dialects. Hopefully now with all this refactoring and dialect dependencies support, new dialects will be much easier to unit test.

Jan 162006

I’m being kind hardcore with the separation of dialects in Savant (a dialect is a collection of plugins – for example there is a Java dialect with a compile plugin). The reason being is that I feel dialects should not interfere with each other in the same manner that web applications should not.

Java has never been particularly good at versioning and I’m only taking on one small piece of the problem by ensuring that dialects can use their own versions of JARs without influencing others (that is unless the JAR is part of the core Savant runtime). The next part is to tackle the issue of versioning plugins and dialects.

A dialect should be able to identify what version it is and a project should be able to declare a hardcoded version it requires. Likewise, a project should be able to specify a version range as well as the latest version available. This will ensure that the dialects can change and projects will continue to build as long as the version they were first created against still exists. This will also allow backwards incompatible changes in dialects to occur.