Develop a Java Plugin Framework
By admin on Oct 7, 2007 in Java, open source, Programming
Recently I have to develop a plugin based application in one of my project. I was trying to see if there is any open source plugin framework that I can used. I found Java Plugin Framwork (JPF) which is a good plugin framework. However, after awhile I found that it is too complicated for my own use, and I developed a very much simplified plugin framework for my own use.
I will briefly describe how I develop the framework.
First, I have the IPlugin and IPluginContext interfaces.
public interface IPlugin {
String getName();void performAction(IPluginContext context);
}public interface IPluginContext {
IMessage getMessage();
void setMessage(IMessage message);}
In my case, I have different kinds of messages, e.g. SMS message, MMS message, etc. Each message will have its own processor. Occassionally I need to put in extra processor to process the existing messages.
For the message, I have the BaseMessage class and IMessage interface.
public class BaseMessage {
protected String aNo;
protected String bNo;
protected String content;public String getANo() {
return aNo;
}public void setANo(String aNo) {
this.aNo = aNo;
}public String getBNo() {
return bNo;
}public void setBNo(String bNo) {
this.bNo = bNo;
}public String getContent() {
return content;
}public void setContent(String content) {
this.content = content;
}
}public interface IMessage {
}
Every message will have A number, B number and the message content. SMS message does not have extra attribute but MMS message will have the fileName attribute.
public class SMSMessage extends BaseMessage implements IMessage {
}
public class MMSMessage extends BaseMessage implements IMessage {
protected String fileName;
public String getFileName() {
return fileName;
}public void setFileName(String fileName) {
this.fileName = fileName;
}
}
Every plugin shall implements the IPlugin interface.
public class SMSPlugin implements IPlugin {
public String getName() {
return “SMS Processor Plugin”;
}public void performAction(IPluginContext context) {
if (context.getMessage() instanceof SMSMessage) {
SMSMessage message = (SMSMessage) context.getMessage();
System.out.println(“Processing SMS message”);
}
}
}public class MMSPlugin implements IPlugin {
public String getName() {
return “MMS Processor Plugin”;
}public void performAction(IPluginContext context) {
if (context.getMessage() instanceof MMSMessage) {
MMSMessage message = (MMSMessage) context.getMessage();
System.out.println(“Processing MMS message”);
}
}
}public class MMSEnchPlugin implements IPlugin {
public String getName() {
return “Enhanced MMS Processor Plugin”;
}public void performAction(IPluginContext context) {
if (context.getMessage() instanceof MMSMessage) {
MMSMessage message = (MMSMessage) context.getMessage();
System.out.println(“Processing enhanced MMS message”);
}
}
}
In the application, I should define a plugin configuration file which describes the plugin name, class and library, and during application startup, I will read and load the plugin. E.g. of an plugin configuration file is as below.
<?xml version=”1.0″ encoding=”ISO-8859-1″ ?>
<application><app-name>Sample Plugin Application</app-name>
<plugin>
<name>SMS plugin</name>
<class-name>SMSPlugin</class-name>
<library>sms.jar</library>
</plugin><plugin>
<name>MMS plugin</name>
<class-name>MMSPlugin</class-name>
<library>mms.jar</library>
</plugin><plugin>
<name>Enhanced MMS plugin</name>
<class-name>MMSEnchPlugin</class-name>
<library>mmsench.jar</library>
</plugin></application>
You could use the XML configuration utility that I described in the previous articles to do that. Read the article at
XML Configuration for Java Program and
Java – Auto Reloading of Configuration File
To load the class, you can refer to my previous article, Java – dynamic loading of class and jar file
For a simple test program, see below.
public static void main(String[] args) {
// This part should be made configurable from config file
List pluginCollection = new ArrayList();
// Load SMS plugin
SMSPlugin smsPlugin = new SMSPlugin();
pluginCollection.add(smsPlugin);// Load MMS Plugin
MMSPlugin mmsPlugin = new MMSPlugin();
pluginCollection.add(mmsPlugin);// Load MMS Plugin
MMSEnchPlugin mmsEnchPlugin = new MMSEnchPlugin();
pluginCollection.add(mmsEnchPlugin);// Let said depend on user selection,
SMSMessage smsMessage = new SMSMessage();
smsMessage.setANo(“00000”);
smsMessage.setBNo(“11111”);
smsMessage.setContent(“test SMS”);MMSMessage mmsMessage = new MMSMessage();
mmsMessage.setANo(“00000”);
mmsMessage.setBNo(“11111”);
mmsMessage.setContent(“test SMS”);
mmsMessage.setFileName(“MMS file name”);MessageContext smsMessageContext = new MessageContext(smsMessage);
MessageContext mmsMessageContext = new MessageContext(mmsMessage);
for (int i = 0; i < pluginCollection.size(); i++) {
IPlugin plugin = pluginCollection.get(i);
plugin.performAction(smsMessageContext);
plugin.performAction(mmsMessageContext);
}}
I created SMS and MMS messages respectively, and pass them into different message contexts. Then I invoke the plugins to process them.
johney | Jan 14, 2009 | Reply
this is very helpful.
thanks.
James | Aug 27, 2009 | Reply
Fantastic. Must read for anyone interested in writing pluggable java applications. Thanks!