Unloadable Plugins

From VuzeWiki
Jump to: navigation, search

Unloadable plugins are more user-friendly as they can be updated by Azureus without Azureus having to restart (and lose all those good peer relationships it's spent time cultivating).

Making a plugin unloadable is pretty simple, you just need to implement the

   UnloadablePlugin

interface instead of the

   Plugin

interface. This forces you to implement a new method, ?unload?:

   public void
   unload()
       throws PluginException;

which will be called by Azureus when it unloads the plugin (in order to replace it with a new version for example). The job of the ?unload? method is to allow the plugin to unhook itself cleanly from Azureus (note that if your plugin loads native code (DLL etc) then it can?t be unloaded as the JVM doesn?t currently support this).

So the unload method must remove any listeners it has added to the core. For example, if the plugin did

   plugin_interface.getDownloadManager().addListener( some_listener_object )

then 'unload' would need to call

   plugin_interface.getDownloadManager().removeListener ( some_listener_object )

This forces you to use non-anonymous listeners in general so you can remove them properly.

If the plugin had created a config model:

   UIManager            ui_manager = plugin_interface.getUIManager();
   config_model = 
       ui_manager.createBasicPluginConfigModel( "TorrentGuard" );

then the unload method would need to destroy it

   config_model.destroy();

The same is true for all listeners added to the core, and any other artifacts that it has created that the core knows about (e.g. menus, table columns, status bar entries)

Note that the unload method can be called without 'initialize' being called beforehand, so you need to deal with the fact that the things you are 'unhooking' from the core haven't actually been hooked yet.

Testing Unloading[edit]

You can manually unload and reload a plugin by going to Tools->Options->Plugins and selecting the plugin in the list - then hit the 'unload selected' button at the bottom of the table. This will unload the plugin. To reload it you then need to hit 'scan for new plugins' - this will locate the plugin but leave it in an unloaded state (it will appear with a read-dot next to it). Now select that entry and hit 'load selected'.

Note that if you are testing the plugin in Eclipse then there are some additional things to be aware of. As the plugin classes won't have been loaded via Azureus via a separate class loader, they won't actually get unloaded. Given that you are running in debug mode though any compatible changes that you made to the plugin code while it is running will automatically be picked up by the JVM anyway, so that in itself isn't a problem. What is though is that any static variables/initialization code (singletons for example) that your plugin uses WON'T be reset/rerun when you reload the plugin. Of course it is usually a good design goal to avoid having static stuff anyway, but if you do then you will need to manually tear these down in the 'unload' method to allow realistic testing.

If you have a JVM profiler (such as YourKit) then a good way to check that you have unloaded properly is to perform the unload and then look for remaining plugin-specific classes/instances that are still loaded. If there are any check out their reference graphs to see if you forgot to unhook something.