2

How can I implement a plugin facility in my java program?

I am working with Java. My current project is something related to a general purpose electronics hardware, which have a custom command set.

Now there is a general GUI through which one can access the hardware. The hardware behaves in different ways in different environment, i.e. for different clients. Now the problem is that the GUI must be capable of adding plugins. Plugin means, it must be capable of giving a particular facility to a customer who has the privilege. From the customer side, the addition of plugin is to be simple, like just click on a button to add a particular facility.

The reason why I think about plugins is that more and more facility will be introduced only after delivering the core product.

Saneesh A T
  • 365
  • 1
  • 6
  • 12

4 Answers4

9

You need to provide following things:

  • create an API which your plug-ins can use to change/extend the behavior of your program (IMHO this is the trickiest part)
  • define a common entry to the plug-ins, e.g., a plug-in-specific properties file defining the entry point or extension points of your plug-in (class name of a plug-in class implementing an interface)
  • dynamically load the plug-ins from a location of your choice, e.g., all *.jar files from a specific directory (take a look at URLClassLoader)

API suggestions:

  • prefer interfaces over (abstract) classes
  • it might be useful to help the user to quickly see which interfaces she could implement (e.g. IAction, notice the leading I) and which are provided by your application for plug-in usage (e.g. WindowManager)
Mot
  • 28,248
  • 23
  • 84
  • 121
3

The main idea behind implementing plugins in any object oriented language, is to define a set of common interfaces that the plugin and related classes must implement, and then load and instantiate them via reflection...

You can use abstract factory pattern so that any objects needed by the plugin can be instantiated...

Let's say that your plugin architecture has only 3 interfaces and each plugin must provide classes that implement those interfaces, then your plugin architecture could be like this:

public interface PluginInterfaceA {
//Define API here
};

public interface PluginInterfaceB {
// Define API here
};

public interface PluginInterfaceC {
// Define API here
};

public interface PluginFactory {
/**
 * Creates plugin A object.
 */
PluginInterfaceA createPluginA();
/**
 * Creates plugin B object.
 */
PluginInterfaceB createPluginB();
/**
 * Creates plugin C object.
 */
PluginInterfaceC createPluginC();
};

And then let the plugins to define in an XML file or properties file the class name of the plugin factory for the plugin:

For instance let's say your plugin defines:

package com.my.plugin;

public class PluginAImpl implements PluginInterfaceA {
// Code for the class
};

public class PluginBImpl implements PluginInterfaceB {
// Code for the class
};

public class PluginCImpl implements PluginInterfaceC {
// Code for the class
};

public class PluginFactoryImpl implements PluginFactory {
public PluginInterfaceA createPluginA() {
  return new PluginAImpl();
}
public PluginInterfaceB createPluginB() {
  return new PluginAImpl();
}
public PluginInterfaceC createPluginC() {
  return new PluginAImpl();
}
};

And then define in the properties file // File plugin.properties provided in the plugin.jar of the plugin plugin.factory.class = com.my.plugin.PluginFactoryImpl;

In your application can do

Properties properties = new Properties();
properties.load(this.getClass().getClassLoader().getResourceAsStream("plugin.properties"));

String factoryClass = properties.get("plugin.factory.class");

PluginFactory factory = Class.forName(factoryClass);

PluginInterfaceA interfaceA = factory.createPluginA();
PluginInterfaceB interfaceB = factory.createPluginB();
PluginInterfaceC interfaceC = factory.createPluginC();

// Here invoke created classes as you like.

Thanks Pablo

  • Let's say he wants to provide a new plugin which could be an extension of `PluginAImpl` or completely new.How will the `PluginFactoryImpl` know about it without modifying the code? – Cratylus Sep 28 '11 at 19:38
  • I mean those interfaces are for classes of one kind of plugin and are related, Say for instance that a graphics editor wants support for new shape, and for that I need to provide an interface for the shape, an interface for the tool in the palette a another for the button on the UI. The each of those interfaces are related to the plugin, so the abstract factory creates groups of related classes, then I provide my factory that creates my implementation of those. In my example PluginInterfaceA, PluginInterfaceB, PluginInterfaceC are part of the same plugin, and all conform the plugin altogether. – Pablo Martin Viva Sep 28 '11 at 20:25
  • This is my point.You will need to modify the factory for each new implementation – Cratylus Sep 29 '11 at 06:59
  • Thank you Pablo... I am trying this... – Saneesh A T Sep 29 '11 at 07:22
  • No, actually yo don't have to modify the factory for each implementation of the plugin, I actually code my application to a set of abstractions with a well defined interface, and let each plugin vendor for my application to develop an implementation, so my code doesn't change when another vendor wants to add a plugin, just instantiate the vendor's factory using reflection and use the factory's interface to create abstractions for each of the components of the plugin. – Pablo Martin Viva Sep 30 '11 at 14:34
  • Since I gave the vendor plugin developer the interfaces to code against to my application only uses those interfaces and my application remains intact and flexible. – Pablo Martin Viva Sep 30 '11 at 14:34
  • Actually the factory I provide is an interface, so nothing changes fron my application point of view, you as a vendor plugin develper create a factory implementation that implements the factory interface provided by me. The only contract between my application and your plugin is the interface I gave for the factory, and you ass a plugin implementation implement the factory in such a way that your factory create instances of your own clases that implements interfaces my application gives. – Pablo Martin Viva Sep 30 '11 at 14:37
2

You can add a jar or plugin to an application at anytime. You don't have to do anything special to achieve this.

If you use OGSi you can manage this easier, support multiple version of the same jar and remove them while the application is running. I suggest looking at Apache Karaf + iPOJO

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
0

The JAR file format has its own little system for managing plugins, which is used for several parts of Java SE, including JDBC driver management. Just define a service interface, put JAR files with implementations on the classpath and load the implementations with ServiceLoader.load.

gustafc
  • 28,465
  • 7
  • 73
  • 99