2009-10-17

Those of you that know what IRC is are probably already thinking I'm off my rocker, given the title of this post. And I probably am. I decided to try my hand at writing an IRC server in a single Java file. I've got it to the point that people can connect to it, join channels, set the channel topic, send messages (and receive them) at channels, send private messages, and change nicks, so I figured I'd blog about it and include a link to it if anyone wants to use it. It's not intended to become a production IRC server; I'm mostly writing it so that I can test out an IRC bot that I'm writing when I don't have an internet connection.

Anyway, here's the source code for the server. Download it, compile it with "javac Connection.java", and then run it with "java Connection <hostname>", replacing <hostname> with your computer's hostname. If you're not sure what your computer's hostname is, just use localhost as the hostname. Then, open your favorite IRC client, connect to "127.0.0.1:6667", and join any channel you want. You can switch nicks, set the channel's topic (even though you're not a channel op), and other users can connect, join channels, and chat with you. Sending messages directly between users also works. Modes do not, however (channels always act as if they are mode +nt, no matter what you set their mode to be, but anyone can change the topic even though the channels have +t present). I'm hoping to add more functionality to this server soon.

This is something I just found out, and I figured I'd blog about it for those that might come across this in the future.

I'm writing some code in a project (JZBot specifically, http://jzbot.googlecode.com) that uses java.lang.reflect.Proxy. At one point, I was calling a method on a proxy instance, and it was throwing a NullPointerException. The weird thing about this was that the NullPointerException was being thrown from within the proxy instance itself, not from the InvocationHandler that it is supposed to call. Other methods on the proxy worked, indicating that there wasn't some error with the invocation handler somehow being set to null.

Eventually, I found the problem: I had declared the method on the interface that the proxy implemented to return a boolean, but the invocation handler was returning null. The auto-unboxing that was being done by the proxy instance internally was messing things up. I changed the method's return type to void (which is what it should have been), and everything worked.

This is yet another example of where to watch out for autoboxing and unboxing. Admittedly, it would be more helpful if the NPE had a message stating something like, for example, "null can't be unboxed to a boolean", which would most likely have saved me quite a bit of time. Oh well.