Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Developing application with plugin support in Java

Tags:

java

I have been researching on how to develop an application that can load plugins. So far, I've seen that this can be done by defining an Interface, and have the plugins implement it.

However, my current issue is on how to load the plugins when they're packed in Jars. Is there a "best" way to do it?

The current logic I'm thinking of is to get each plugin and inside their Jar look for the class that implements the Interface. But I don't know how to do such lookup. I think that this logic may not be a good one, but I couldn't find any useful information on this specific topic.

**Edit1: ** Adding more information: The intended plugins would be Jar files contained inside a subdirectory where the main application's Jar would be located, like this:

Application's folder
|- Main_Application.jar
|- Plugins
  |- Plugin1.jar
  |- Plugin2.jar
  |- Steve's_plugin.jar

And so on.

What I expect is that the Application will be able to load all plugins inside the folder at runtime. So in the code, it would only be aware that the plugin's folder should exist and there should be Jars inside such folder.

Let's say I have a plugin interface like this:

interface Plugin
{
    public void run();
}

Plugins would be identified by a class that implements such interface, like so

class Plugin1 implements Plugin
{
    //attributes and other methods
    @override
    public void run()
    {
        //something happens here
    }
}

class Plugin2 implements Plugin
{
    //attributes and other methods
    @override
    public void run()
    {
        //something happens here
    }
}

The Application should be compiled only once, and be able to load any Plugins added to the folder when it is executed. For the Application to be able to load any Plugin, do I need to establish rules on the contents of the Jar, like package name and the class that implements the interface? Or it is expected that the class implementing the plugin interface could be in any package within the Jar, and have any name?

This is the more generic approach to what I would like to do with such plugins. In short, I'm planning to build an Application that will have tabs, and each plugin will provide the Interface and Functionality of each tab. I'm trying this because I want to be able to maintain each tab separately, and don't want to recompile the whole application because of changes in only one component that don't affect the others at all.

like image 476
tady159 Avatar asked Aug 25 '15 13:08

tady159


People also ask

How do I add plugins to my application?

First you need an interface that all plugins need to implement, e.g. Plugin authors should then bundle their plugins into JAR files. Your applications opens the JAR file and could then use an attribute from JAR manifest or the list of all files in the JAR file to find the class that implements your Plugin interface.

What is a plugin interface in Java?

The Plugin interface is used by Java’s ServiceLoader to load the plugin and make it available to the rest of the app. Every plugin can choose to offer one of more factories. So, a plugin is not restricted to be of a certain “type”. The factory pattern used here makes it easy for the app to construct service objects on demand.

How do I build a simple plugin infrastructure in Java?

There are a few steps in building a simple plugin infrastructure in Java. To keep it simple, I wrote a quickstart on GitHub to help you get started. The project uses maven and Java 8 but the principles can be very easily extended to other build systems/jdk versions. We’ll be using Java’s ServiceLoader to do all the heavy lifting for us.

What happened to the Java plugin in JDK 9?

JRE 9 will continue to provide the Java Plugin and support launching applets on browsers that still offer standard plugin support, but is only available for limited use and not recommended. This browser plugin will be removed from the Oracle JDK and JRE in a future Java SE release.


1 Answers

Get the list of plugin jars:

File[] jars = new File("Plugins").listFiles();

Then, use the code from this answer about loading all classes from a JAR file, but run it once for each file in jars whose name ends in ".jar". At the bottom of the loop body, after

Class c = cl.loadClass(className);

continue with

if (Plugin.class.isAssignableFrom(c)) {
    Plugin plugin = (Plugin) c.newInstance();
    // And then, do something with the plugin here
}

I share @Mifeet's concerns about security - you might want to use a SecurityManager to limit what the plugin code is allowed to do.

like image 198
Aasmund Eldhuset Avatar answered Oct 14 '22 04:10

Aasmund Eldhuset