I little while back I stumbled across an article that talked about one man's work of building an extendable IRC bot with OSGi.
A little more recently, I read about why GitHub encourages side projects, which includes a brief description of their chat bot.
At BUG, we use IRC to keep in touch with our customers, but we also use it to keep in touch with each other. And we have a few IRC bots hanging out in the channels, keeping us informed of things like build status and linguistic transgressions. I thought it would be fun to write a pluggable IRC bot for our platform. Ideally the bot would run constantly, and we could modify its behavior dynamically by loading and unloading OSGi bundles. We could also leverage the strengths of our platform, like easy integration with accelerometers (Surprise! there's an accelerometer in the LCD module), cameras, and electronic circuits. I also thought it would be a good way to develop my understanding of how OSGi bundles should be created and hooked together.
The project is up on our GitHub repository. Right now there is very little documentation, and some of the parts only barely work, but I've managed to hash out a few ideas already.
One of the big ideas I wanted to play with was where to draw the line between bundles. I wanted to be able to add behaviors dynamically, so obviously behaviors were candidates for becoming bundles. I created an interface for handling IRC channel messages; bundles that wish to handle these messages can create objects that implement the com.buglabs.bug.ircbot.pub.IChannelMessageConsumer interface and then register these objects as services, which are then notified when channel messages are received. This is an example of the whiteboard pattern, which occurs frequently in OSGi. I also separated the public interfaces into their own bundle. This means that the bot implementation and the behaviors both depend on this bundle, but they do not depend on each other. As a consequence, I can swap bot implementations without reloading behaviors. There are two bot implementation on GitHub, com.buglabs.bug.ircbot.impl.irclib (based on irclib) and bot-osgi/com.buglabs.bug.ircbot.impl.jerklib (based on jerklib).
I've been looking for an excuse to experiment with Mirah on the BUG, and this project has given me a chance to do that. The behavior in com.buglabs.bug.ircbot.behavior.easyshucks is implemented in Mirah and takes advantage of Mirah's use of blocks to implicitly implement interfaces that have a single method. The syntax was modeled off of isaac, an IRC DSL for Ruby, and the supporting code can be found in com.buglabs.bug.ircbot.behavior.easylistening.
This has also been a great chance to become a little more comfortable with Git. I've been doing this thing long enough to realize that Git will be replaced by something else some time in the future, but for now it seems to be one of the best things around for keeping track of source code.
I've learned a few things while working on this project, or at least had some prejudices confirmed. First, Git isn't as scary as I had lead myself to believe. I'm sure there are weird nooks and crannies that I will stumble into, but so far it has been as painless as everybody promised it would be. Second, writing OSGi bundles requires a lot of boilerplate. Even the Mirah example requires two files and a supporting package. It would be nice to find a way to make it easier to get software on to our platform without relying on code generation or copying files from existing projects. Third, while I still admire Java jar files as a method of distributing software, I think the space of possible solutions to the problems of software partitioning, distribution, and dependency management is still open to exploration. OSGi provides tools to manage some of these issues, but the amount of boilerplate required to make it all work leads me to believe that the situation can still be improved.
Ultimately this project is about having fun. I'm going to keep working on it in my spare time (or when I need a break), adding features and functionality. It would be nice to run it on a dedicated BUG and encourage people to slowly make it more useful by adding new behaviors. We'll see what happens.