Thin JAR plugin support for PF4J with Maven dependency resolution.
A proof-of-concept for pf4j/pf4j#208 - plugins as Maven artifacts with automatic dependency resolution.
Instead of packaging plugins as fat JARs or ZIPs with bundled dependencies, this approach allows plugins to be specified as Maven coordinates. Dependencies are resolved and downloaded automatically at runtime using Maven Resolver.
Traditional PF4J:
plugins/
my-plugin.jar (fat jar with all dependencies inside)
PF4J Maven:
plugins.txt:
com.example:my-plugin:jar:plugin:1.0.0
# Dependencies resolved automatically from Maven repositories
- Plugins specified as Maven coordinates (
groupId:artifactId:jar:classifier:version) - Automatic transitive dependency resolution
- Uses local Maven repository (
~/.m2/repository) and Maven Central - Caches resolved artifacts to avoid redundant downloads
- Application reads plugin coordinates from
plugins.txt MavenPluginManagerresolves each artifact using Maven Resolver- Plugin JAR is copied to
plugins/<artifactId>/ - Dependencies (excluding
providedandtestscope) are copied toplugins/<artifactId>/lib/ - Standard PF4J loading takes over
// Use the builder to create MavenPluginManager
PluginManager pluginManager = MavenPluginManagerBuilder.create().build();
pluginManager.loadPlugins();
pluginManager.startPlugins();
List<Greeting> greetings = pluginManager.getExtensions(Greeting.class);
for (Greeting greeting : greetings) {
System.out.println(">>> " + greeting.getGreeting());
}The builder supports various configuration options:
PluginManager pluginManager = MavenPluginManagerBuilder.create()
.pluginsRoot(Paths.get("my-plugins")) // custom plugins directory
.localRepository(Paths.get("/custom/m2/repo")) // custom local Maven repo
.addRemoteRepository("jitpack", "https://jitpack.io") // additional repo
.includeMavenCentral(true) // include Maven Central (default)
.processLooseJars(true) // process loose JARs (default)
.skipExistingDependencies(true) // skip if lib/ exists (default)
.build();For advanced customization, extend MavenPluginManager:
class CustomPluginManager extends MavenPluginManager {
@Override
protected PluginFactory createPluginFactory() {
return new CustomPluginFactory();
}
}plugins.txt:
org.pf4j.demo:pf4j-maven-demo-plugin1:jar:plugin:1.0.0-SNAPSHOT
# org.pf4j.demo:pf4j-maven-demo-plugin2:jar:plugin:1.0.0-SNAPSHOT
A working demo is available in the demo folder.
Quick run:
./run-demo.sh # Linux/Mac
run-demo.bat # WindowsOutput:
>>> Whazzup
>>> Welcome
pf4j-maven/ # Core library
MavenPluginManager
MavenPluginManagerBuilder
MavenPluginLoader
MavenUtils
demo/
app/ # Demo application
api/ # Shared plugin API
plugins/ # Demo plugins
plugin1/ # welcome-plugin (uses commons-lang)
plugin2/ # hello-plugin
- Java 8+
- Maven 3.6+
- PF4J - Plugin Framework for Java
- Issue #208 - Original proposal for this feature