Plugin Framework for Java (PF4J)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

164 lines
6.9 KiB

<img src="pf4j-logo.svg" width="250"/>
12 years ago
Plugin Framework for Java (PF4J)
=====================
8 years ago
[![Join the chat at https://gitter.im/decebals/pf4j](https://badges.gitter.im/decebals/pf4j.svg)](https://gitter.im/decebals/pf4j?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
7 years ago
[![Travis CI Build Status](https://travis-ci.org/pf4j/pf4j.png)](https://travis-ci.org/pf4j/pf4j)
7 years ago
[![Coverage Status](https://coveralls.io/repos/pf4j/pf4j/badge.svg?branch=master&service=github)](https://coveralls.io/github/pf4j/pf4j?branch=master)
[![Maven Central](http://img.shields.io/maven-central/v/org.pf4j/pf4j.svg)](http://search.maven.org/#search|ga|1|pf4j)
12 years ago
A plugin is a way for a third party to extend the functionality of an application. A plugin implements extension points
declared by application or other plugins. Also a plugin can define extension points.
7 years ago
**NOTE:** Starting with version 0.9 you can define an extension directly in the application jar (you're not obligated to put the extension in a plugin - you can see this extension as a default/system extension). See [WhazzupGreeting](https://github.com/pf4j/pf4j/blob/master/demo/app/src/main/java/org/pf4j/demo/WhazzupGreeting.java) for a real example.
11 years ago
12 years ago
Features/Benefits
12 years ago
-------------------
11 years ago
With PF4J you can easily transform a monolithic java application in a modular application.
6 years ago
PF4J is an open source (Apache license) lightweight (around __50 KB__) plugin framework for java, with minimal dependencies (only slf4j-api) and very extensible (see `PluginDescriptorFinder` and `ExtensionFinder`).
11 years ago
11 years ago
Practically PF4J is a microframework and the aim is to keep the core simple but extensible. I try to create a little ecosystem (extensions) based on this core with the help of the comunity.
For now are available these extensions:
7 years ago
- [pf4j-update](https://github.com/pf4j/pf4j-update) (update mechanism for PF4J)
- [pf4j-spring](https://github.com/pf4j/pf4j-spring) (PF4J - Spring Framework integration)
- [pf4j-wicket](https://github.com/pf4j/pf4j-wicket) (PF4J - Wicket integration)
- [pf4j-web](https://github.com/pf4j/pf4j-web) (PF4J in web applications)
12 years ago
No XML, only Java.
12 years ago
12 years ago
You can mark any interface or abstract class as an extension point (with marker interface ExtensionPoint) and you specified that an class is an extension with @Extension annotation.
7 years ago
Also, PF4J can be used in web applications. For my web applications when I want modularity I use [pf4j-wicket](https://github.com/pf4j/pf4j-wicket).
12 years ago
12 years ago
Components
-------------------
12 years ago
- **Plugin** is the base class for all plugins types. Each plugin is loaded into a separate class loader to avoid conflicts.
6 years ago
- **PluginManager** is used for all aspects of plugins management (loading, starting, stopping). You can use a built-in implementation as `JarPluginManager`, `ZipPluginManager`, `DefaultPluginManager` (it's a `JarPluginManager` + `ZipPluginManager`) or you can implement a custom plugin manager starting from `AbstractPluginManager` (implement only factory methods).
8 years ago
- **PluginLoader** loads all information (classes) needed by a plugin.
12 years ago
- **ExtensionPoint** is a point in the application where custom code can be invoked. It's a java interface marker.
8 years ago
Any java interface or abstract class can be marked as an extension point (implements `ExtensionPoint` interface).
12 years ago
- **Extension** is an implementation of an extension point. It's a java annotation on a class.
12 years ago
6 years ago
**PLUGIN** = a container for **EXTENSION POINTS** and **EXTENSIONS** + lifecycle methods (start, stop, delete)
6 years ago
A **PLUGIN** is similar with a **MODULE** from other systems. If you don't need lifecycle methods (hook methods for start, stop, delete) you are not forced to supply a plugin class (the `PluginClass` property from the plugin descriptor is optional). You only need to supply some description of plugin (id, version, author, ...) for a good tracking (your application wants to know who supplied the extensions or extensions points).
6 years ago
12 years ago
How to use
-------------------
7 years ago
It's very simple to add pf4j in your application.
12 years ago
6 years ago
Define an extension point in your application/plugin using **ExtensionPoint** interface marker:
12 years ago
```java
public interface Greeting extends ExtensionPoint {
12 years ago
8 years ago
String getGreeting();
12 years ago
}
```
12 years ago
6 years ago
Create an extension using `@Extension` annotation:
7 years ago
6 years ago
```java
@Extension
6 years ago
public class WelcomeGreeting implements Greeting {
6 years ago
public String getGreeting() {
return "Welcome";
}
}
```
Create (it's optional) a `Plugin` class if you are interested for plugin's lifecycle events (start, stop, ...):
```java
public class WelcomePlugin extends Plugin {
12 years ago
public WelcomePlugin(PluginWrapper wrapper) {
super(wrapper);
12 years ago
6 years ago
// you can use "wrapper" to have access to the plugin context (plugin manager, descriptor, ...)
}
12 years ago
6 years ago
@Override
public void start() {
System.out.println("WelcomePlugin.start()");
12 years ago
}
6 years ago
@Override
public void stop() {
System.out.println("WelcomePlugin.stop()");
}
@Override
public void delete() {
System.out.println("WelcomePlugin.delete()");
}
}
```
6 years ago
In above code I created a plugin (welcome) that comes with one extension for the `Greeting` extension point.
12 years ago
7 years ago
You can distribute you plugin as a jar file (the simple solution). In this case add the plugin's metadata in `MANIFEST.MF` file of jar:
12 years ago
9 years ago
```
7 years ago
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: decebal
Build-Jdk: 1.6.0_17
Plugin-Class: org.pf4j.demo.welcome.WelcomePlugin
Plugin-Dependencies: x, y, z
Plugin-Id: welcome-plugin
Plugin-Provider: Decebal Suiu
Plugin-Version: 0.0.1
9 years ago
```
6 years ago
In above manifest I described a plugin with id `welcome-plugin` (mandatory attribute), with class `org.pf4j.demo.welcome.WelcomePlugin` (optional attribute), with version `0.0.1` (mandatory attribute) and with dependencies
to plugins `x, y, z` (optional attribute).
7 years ago
Now you can play with plugins and extensions in your code:
```java
7 years ago
public static void main(String[] args) {
7 years ago
...
7 years ago
// create the plugin manager
6 years ago
PluginManager pluginManager = new JarPluginManager(); // or "new ZipPluginManager() / new DefaultPluginManager()"
7 years ago
// start and load all plugins of application
pluginManager.loadPlugins();
pluginManager.startPlugins();
7 years ago
// retrieve all extensions for "Greeting" extension point
List<Greeting> greetings = pluginManager.getExtensions(Greeting.class);
for (Greeting greeting : greetings) {
System.out.println(">>> " + greeting.getGreeting());
}
7 years ago
// stop and unload all plugins
pluginManager.stopPlugins();
pluginManager.unloadPlugins();
...
}
```
7 years ago
The output is:
8 years ago
```
7 years ago
>>> Welcome
9 years ago
```
7 years ago
PF4J is very customizable and comes with a lot of goodies. Please read the documentation to discover yourself the power of this library.
9 years ago
7 years ago
Documentation
---------------
7 years ago
Documentation is available on [pf4j.org](http://www.pf4j.org)
12 years ago
Demo
7 years ago
---------------
7 years ago
Demo applications are available in [demo](https://github.com/pf4j/pf4j/tree/master/demo) folder