fognl

Get off my lawn.

Thursday, September 04, 2008

OSGi Bundle Deployer

I wrote a little tool for development with OSGi (specifically Equinox), which I've been playing a lot with lately. I thought I would post it here in case anyone found it useful. It's similar to the File Install bundle available for Apache Felix (as a commenter on this post pointed out).

The tool in question here is an OSGi bundle that manages the installation, update and un-installation of other OSGi bundles. It bears the unimaginative name of "bundle deployer".

Essentially, its job is to monitor one or more directories on the file system and install, update, or uninstall bundles being manipulated there.

Once you've configured and started it, you can install a bundle in the OSGi environment just by copying it to a monitored directory. To update an installed bundle, update the corresponding file. To uninstall it, delete the corresponding file.

I find this useful, since I've been spending a considerable amount of time updating bundles on a remote machine I'm testing on. I can just scp all of the bundle files I'm dealing with onto a specific directory on the remote machine, and they get loaded and updated automatically.

Here is the "user manual":

First: download the bundle from here:
http://fognl.com/osgi/bundle_deployer_1.0.0.jar

You can get the source from here:
http://fognl.com/osgi/bundle_deployer_1.0.0-src.zip.

Second: In your OSGi console, set a property:

osgi>setprop bundle.deployer.dir.names=/home/fred/my_bundles:/home/fred/my_other_bundles

The format of the property value is just like your OS's PATH statement. The example shown here is for Linux, with a ":" between directory names. On Windows, the path-separator character is ";", e.g:

c:\my_bundles;c:\my_other_bundles

You can also specify this property in your OSGi environment's config.ini file. If you use this bundle on Linux, you can create a config file at /etc/bundle-deployer.conf with the property in it. In this case, the bundle deployer will use property values specified there, but actual system properties you specify will take precedence.

Note: The "\" character is an escape in a properties file. So if you specify a Windows path with backslashes in a properties file or in config.ini (which is also a properties file), be sure to use two backslashes (\\) for the path separators. Better yet, just use forward slashes (e.g. c:/my_bundles). This works fine on the Windows platform too. Cmd.exe is the only component of Windows that doesn't know what to do with "/" path separators.

Once you've set this property, install and start the bundle deployer:

osgi>install file:/home/path/to/download/bundle_deployer_1.0.0.jar
Bundle id is (something)
osgi>start (something)

When the bundle deployer starts, it will scan the directories you specified, and install all of the bundles found there. After installing all of them, it starts them all. If a bundle is already installed, installing it again has no effect.

That's basically all there is to using it.

I typically configure Equinox to use this bundle in the conventional way (specifying it in the config.ini file), so that when I stop/restart Equinox, it loads this bundle (along with others that are already in use). When the bundle deployer starts, it loads the bundles I'm working on. This approach would most likely work in a production environment, but that's not the point. I think you'd want to use the recommended approach for your OSGi environment for loading a production set of bundles.

One last thing: This has only been tested with the Equinox environment, and not on Knopflerfish or Apache Felix.

Bugs

Update Exceptions: It's possible for an update operation to result in an exception in the OSGi environment where it complains about "X.jar is not a valid zip file". What's happening here is that my directory scanner notices that the file's modification time has updated and signals an "update" event to its listener, without bothering to make sure the file isn't still being updated before it fires the event. This wouldn't be hard to fix, and I'll post an update once I fix it. In the meantime, just update the file again if you get this error message.

If you see this happening frequently, you can reduce the likelihood of it happening by adjusting the bundle.deployer.sleep.interval property to a higher value. This property controls how long the bundle deployer waits between checks for updates in the monitored directories. It's specified in milliseconds. So:

osgi>setprop bundle.deployer.sleep.interval=10000

...results in a directory scan every 10 seconds (instead of the default of 2 seconds).

You can set the bundle.deployer.sleep.interval property in any of the places mentioned above (console, /etc/bundle-deployer.conf, config.ini).

The tree-chopping-itself-down bug: The bundle deployer does not exclude its own jar file from installation or update (or delete) operations. If you do something weird like putting the bundle deployer's jar file in a directory that it's monitoring, it will have no effect. If the bundle deployer isn't started already, simply copying the file into a directory won't do anything. If it is already running, it will attempt to install itself, but since it's already installed, the install operation will have no effect.

However, if you delete the bundle deployer's jar file from a directory it's monitoring, it will uninstall itself. OSGi's APIs are smart enough to prevent this from being the black-hole-inducing disaster it sounds like it would be, so I don't think there would be any serious effect. I frankly haven't tested that. This isn't really how the bundle deployer is meant to be used.

System Properties: While it's running, the bundle deployer doesn't notice changes you might make to system properties and update its configuration. You have to restart it via an update operation at the console. Not really a "bug", but something to bear in mind.

So there it is. I hope you find it useful.

The more I work with OSGi, the more I appreciate it as a server environment. It incorporates internal pub/sub messaging, dynamic load/unload of modules, the ability to monitor changes within the environment itself, and a host of other things, not to mention a legitimate component model for Java.

The next thing I plan to do is get a SQLite embedded database running on it. That should be handy.

2 Comments:

  • At 8:05 AM , Blogger Richard said...

    You should check out File Install written by Peter Kriens and now a Felix subproject:

    http://cwiki.apache.org/FELIX/apache-felix-file-install.html

     
  • At 8:59 AM , Blogger Kelly said...

    @richard: Thanks for the info. It doesn't surprise me that there's something out there like this already, since it's such a handy thing to have. Seems like every time I have a good idea, someone has already implemented it. Oh well... On to my next project, a cutting-edge "logging framework" for Java. :-)

     

Post a Comment

Subscribe to Post Comments [Atom]

<< Home