Zing
Zing is an idea which came out of my frustration with different bots out there.
Note: Zing is retired as the ChatterBot project appears to be doing it better.
On the IRC side, PircBot gives us a reasonable IRC client library, and PPF gives us a lot of plugins for that library. But what if you want to use XMPP instead? Should we be forced to write the same plugins over and over just because we want to use them on a different chat system? Of course not!
I have written IRC bots in the past. I have written XMPP bots in the past. So this project plans to bring it together into a common framework on top of which bot plugins can be written for use with multiple chat services.
So I started with abstracting away the chat service, and got the basics working. But what about the plugin framework? After looking at three different options (NetBeans Platform, JPF and OSGi) I ended up settling with OSGi.
OSGi
Two weeks ago, OSGi was just a bunch of letters to me, but I've been learning a lot in the past week. Basically it's a system whereby special metadata in jar files (which makes them "bundles") tells the container what depends on what, and allows the container to be strict about what classes each jar file loads.
A good example is, if you define the service interface in a package, and then define your implementation in a different package, you can export only the package containing the interface, thus forcing the caller to go through the container to get a reference. The container holds all sorts of magic which loads the real implementation but forces all access through a proxy. So you can't even cast to the implementation -- you can't even load that class.
What this ends up meaning is that (a) you are practically forced to use interfaces, and properly split your components between interface and implementation, and (b) you know exactly which bundles depend on which other bundles, and when you are forced to make conscious decisions to add dependencies, things magically keep themselves under control. It's something I have been using IDE modules to do for ages, but in this case it's enforced by the container.
OSGi also gives you a lot of stuff for free. Things we get for free which are useful for a bot framework:
- APIs for preference storage
- APIs for user administration
- APIs for persistent services
- Ability to add bundle repositories
- Automatic update of bundles
The last two are what I really like. Imagine having a command where you can search for new plugins for your bot, and it goes out to the web to find one, installs it and starts the plugin. And all this without restarting the bot? Awesome. Plugin gets updated? Just tell the container to update its bundle, and it stops and starts it for you.