Friday, January 25, 2008

Java Packages and Dependency Management

I used to think Java's packages were a great thing. They solved the problem of naming conflicts and enforce a consistent system of organizing source code on disk for everything written in Java. That view came from working on some C/C++ codebases where boundaries of name-spaces were haphazard or nonexistant and the conceptual organization of the source bore no relation to the location in the file system of the various modules that made up the program. Tracing an execution path through the code was next to impossible and the build process a nightmare.

I had a friend, an experienced C++ developer who said he always felt straight-jacketed by Java packages. He didn't want to be forced to organize his files in the same way he organized his packages. I never understood why anyone would want the freedom to create the type of disaster I had seem before. But there's a part of the picture I was missing. Packages also imply something about dependencies.

Good guidelines on packaging are remarkably hard to come by. But, at minimum, a well designed package structure will minimize dependencies between packages and avoid circular dependencies. I've come to follow other rules of thumb about inter-package dependencies. Everyone can depend on a util package. But a util package should have no dependencies inside the project. Domain model classes should be defined abstractly and be free of outside dependencies.

Inversion of control is when code at a lower level of abstraction depends on code at a higher level of abstraction. The domain model is defined at a high level, with little or no implementation detail. In fact, much of my domain models are just interfaces. Lower level packages do the grunt work with specializations of the domain model artifacts.

Recently, I worked on a project with a Swing UI, which I hadn't done in years. I created a ui package to hold all the Swing related kerfuffle. I started noticing that I had a lot of actions. These little 20 line subclasses of AbstractAction define the event handlers used by controls throughout the UI and seem to multiply like rabbits. Mixed in with the rest of the UI classes, classes that formed the windows, panels, dialogs, and other on-screen widgetry of my app, the actions were hard to find and just cluttered up the place. I wanted, for strictly organization reasons, to move them out of the way.

Of course, the actions depend on the UI widgets they invoke and the UI widgets depend on the actions. So, if I put my actions in a separate package, I'd have a big ugly circular dependency staring me right in the face. I go sick of looking at the action classes, so I did it anyway. Where dependencies and name-spaces are concerned, they're all in one conceptual unit. But on disk, and therefore necessarily in the package hierarchy, they're in two different places.

Since becoming more aware of the role dependencies play in packaging, I've notice more little conflicts of interest like this. I still prefer the enforced file system structure of packages to total chaos, but I now recognize my friend's point.

It would be an interesting extension to the language to be able to explicitly declare that package X was allowed to depend on packages Y, Z, and util. Any other dependency could generate a compiler warning. There are static code analyzers that will do just that. (JDepends for example.) It would be even better if the IDE was aware of such things and could issue a warning as you added a suspicious dependency.

Wednesday, January 23, 2008

Visual computing platforms

processing: an open source programming language and environment for people who want to program images, animation, and interactions. Processing was initiated by Ben Fry and Casey Reas. vvvv: a toolkit for real time video synthesis.
prefuse: software tools for data visualization.
AIR: programmatically access Adobe's Flash engine + webkit

Link to Manageability blog

Manageability blog has a blurb about the demise of the Chandler project asking whether Python was to blame. From there, there's some interesting looking links about the architecture of Eclipse. Actually, Ted Neward's comments were better than the original post.

Thursday, January 17, 2008

Java Integer.decode broken

If you're aware of two's compliment representation of integers, you can probably guess the output of the following line of Java:

System.out.println(Integer.toHexString(-1));

Sure enough, you get this:

ffffffff

Knowing that, what do you think the result of this line might be?

System.out.println(Integer.decode("0xffffffff"));

Would you believe NumberFormatException: For input string: "ffffffff"? The reason is that decode works on signed values. Ugly with a capital Ug. Decode works as expected on hexadecimal values in which the most significant bit is clear. But here, that high bit is set. The decode function expects a negative hex value where ever you'd use a negative decimal value.

Now, what would be a proper punishment for the kind of protohuman homunculus who would use a sign with a hexadecimal number? Fifty lashes with a wet noodle for the addled mind that thought this was a good idea:

Integer.toHexString(Integer.decode("-0x1"));
ffffffff

Most sane programmers find this highly annoying. There's a bug dated in 1999, (and several dupes) in the Java bug database for this, and its counterpart bug in Long. What an embarrassment.

One work-around (for integers) is to use a Long when you expect a hex number with the sign bit set.

int thisIsTotallyWeak = Long.decode("0xffffffff").intValue();