Rainy days and Java always get me down


I've Moved My Blog

It's currently located at http://www.urlinone.com/blog

I should say "I'm moving my blog." It's a pretty painful process.

Pebble has blown up on me, and it's been many months since I've been able to blog reliably. I've lost posts. And now I've got to figure out how to migrate my past blog posts from Pebble to my new destination without all the URLs changing, lest external links become 404 Not Founds.

Why does everything in the 21st century have to be a three-day project???

Matt Raible has changed BaseObject in the upcoming version of AppFuse so that equals() and hashCode() are abstract, meaning that all your AppFuse model classes will have to implement these methods. Matt suggests using Commonclipse to automatically generate these methods. It certainly beats creating them all by hand!

It's easy enough to add Commonclipse to Eclipse 3 by doing Help > Software Updates > Find and Install > Search for new features to install > Next > New Remote Site. Put Commonclipse in the Name and http://commonclipse.sourceforge.net in the URL. Click OK. Click Next.

Once Commonclipse is installed and Eclipse has restarted, do the following to get it working for AppFuse:

Window > Preferences > Java > Commonclipse. Select the General tab. Uncheck the second and third checkboxes, which are to Append super in hashCode() and Append super in equals(). Click Apply (if you like) and OK.

The body of BaseObject in AppFuse 1.5 contains actual implementations. To delegate these methods to their subclasses, change BaseObject and the methods to abstract, as in the following:

public abstract class BaseObject implements Serializable {
    public abstract String toString();
    public abstract boolean equals(Object o);
    public abstract int hashCode();
}

Now you are ready to use Commonclipse to generate the implementations for these abstract methods in your model classes. In Eclipse, open each class that is derived from BaseObject. You can have Eclipse find them all for you by clicking on the word BaseObject in the editor window and hitting the F4 key. This will open the Hierarchy view and show you all the classes that have BaseObject as a superclass.

Open each class by double-clicking it in the Hierarchy window. In the editor, right-click, go down to the Commonclipse menu item, and select the method you want generated. Unfortunately, Commonclipse makes you repeat this task for each method, and I am not aware of a keyboard shortcut, although I longed for one.

Take note of two quirks I came across with Commonclipse

  1. A couple of times, it actually modified BaseObject, rather than the class I was editing.
  2. More frequently, it would not do anything after I selected the generate menu item. There was no error message, but the method was not generated.

I think both these problems might have something to do with focus of the editor window. I think the key is to left-click in the editor window to ensure that the file you can see is also the one that has focus. (Make sure the insertion point in the editor window is flashing.) One thing I noticed is that you can single-click a class in the Hierarchy window, if the file is already open in the editor. When you do that, the editor window for that file comes to the front, but the focus is actually still in the Hierarchy window.

I'm not positive that's the root cause of the problem, but closing and reopening the file and doing any kind of editing in the file seemed to get past the do-nothing generate task.

This is the single most difficult piece of information to find on all the web.

Lemme see, what did I Google for?

  • SocketAppender layout
  • chainsaw ConversionPattern
  • source line number log4j
  • chainsaw location line number
  • jakarta apache commons-logging log4j chainsaw layout please oh please show me my freaking line numbers

I'm not sure why this is the most elusive tidbit of information on the face of the earth, but I'm going to open the kimono and let you in on the secret...

log4j.appender.chainsaw=org.apache.log4j.net.SocketAppender
log4j.appender.chainsaw.RemoteHost=localhost
log4j.appender.chainsaw.Port=4445
log4j.appender.chainsaw.locationInfo=true

Can I tell you how many variations on the ConversionPattern I tried? It's in the dozens. None of them worked.

log4j.appender.chainsaw.layout.ConversionPattern=%d{DATE} [%-5p] %c {%F:%L} - %m%n
log4j.appender.chainsaw.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.appender.chainsaw.layout.ConversionPattern=%d [%t] %-5p %c {%F:%L} - %m%n
log4j.appender.chainsaw.layout.ConversionPattern=%d [%t] (%F:%L) %-5p %c - %m%n

Pretty sick when you find out all you need is locationInfo=true.

This is why I'm JCranky.