Step 1. Add the JitPack repository to your build file
Add it in your root settings.gradle at the end of repositories:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
Add it in your settings.gradle.kts at the end of repositories:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral()
maven { url = uri("https://jitpack.io") }
}
}
Add to pom.xml
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
Add it in your build.sbt at the end of resolvers:
resolvers += "jitpack" at "https://jitpack.io"
Add it in your project.clj at the end of repositories:
:repositories [["jitpack" "https://jitpack.io"]]
Step 2. Add the dependency
dependencies {
implementation 'com.github.TonyApD:pf4j:release-3.1.0'
}
dependencies {
implementation("com.github.TonyApD:pf4j:release-3.1.0")
}
<dependency>
<groupId>com.github.TonyApD</groupId>
<artifactId>pf4j</artifactId>
<version>release-3.1.0</version>
</dependency>
libraryDependencies += "com.github.TonyApD" % "pf4j" % "release-3.1.0"
:dependencies [[com.github.TonyApD/pf4j "release-3.1.0"]]
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.
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 for a real example.
With PF4J you can easily transform a monolithic java application in a modular application.
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).
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:
No XML, only Java.
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.
Also, PF4J can be used in web applications. For my web applications when I want modularity I use pf4j-wicket.
DefaultPluginManager
, JarPluginManager
or you can implement a custom plugin manager starting from AbstractPluginManager
(implement only factory methods).ExtensionPoint
interface).It's very simple to add pf4j in your application.
Define an extension point in your application using ExtensionPoint interface marker:
public interface Greeting extends ExtensionPoint {
String getGreeting();
}
Create a plugin that contribute with an extension:
public class WelcomePlugin extends Plugin {
public WelcomePlugin(PluginWrapper wrapper) {
super(wrapper);
}
@Extension
public static class WelcomeGreeting implements Greeting {
public String getGreeting() {
return "Welcome";
}
}
}
In above code I created a plugin that comes with one extension for the Greeting
extension point.
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:
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
In above manifest I described a plugin with id welcome-plugin
, with class org.pf4j.demo.welcome.WelcomePlugin
, with version 0.0.1
and with dependencies
to plugins x, y, z
.
Now you can play with plugins and extensions in your code:
public static void main(String[] args) {
...
// create the plugin manager
PluginManager pluginManager = new DefaultPluginManager();
// start and load all plugins of application
pluginManager.loadPlugins();
pluginManager.startPlugins();
// retrieve all extensions for "Greeting" extension point
List<Greeting> greetings = pluginManager.getExtensions(Greeting.class);
for (Greeting greeting : greetings) {
System.out.println(">>> " + greeting.getGreeting());
}
// stop and unload all plugins
pluginManager.stopPlugins();
pluginManager.unloadPlugins();
...
}
The output is:
>>> Welcome
PF4J is very customizable and comes with a lot of goodies. Please read the documentation to discover yourself the power of this library.
Documentation is available on pf4j.org
Demo applications are available in demo folder