PF4J: Plugin Framework for Java. Plugin Systems for Backend

Transcript:

Let's address an elephant in the room. Backend development never ceases to amaze us. It's never what we think it is. For example, do you ever think that backend development is not only about service-oriented architecture, monoliths, or microservices, but can also be a system with plugins like your IDE?

About the Speaker and PF4J
Hi, my name is Pasha Finkelshteyn. I work as a developer advocate for BellSoft, and today we are diving into plugin systems for backend development. The tool we will be discussing is called PF4JPlugin Framework for Java. You might assume that a framework is something huge, like Spring Framework, but PF4J is actually very lightweight, only around 100kB.

What is a Plugin?
A plugin is a part of your application that can be developed by a third party. It doesn't matter whether the developer is within your organization or an external contributor. For example, imagine a web application that supports only Epub file uploads, but you want to allow others to add support for PDFs, Mobi, Markdown, etc. Instead of developing these features yourself, you create an extension point—a defined interface where custom code can be invoked.

Extension Points and Plugin Lifecycle
An extension point is simply an interface with specific methods, such as getPath(), that plugins must implement. But a plugin is more than just an extension point—it has a lifecycle: it loads, starts, runs, and shuts down. PF4J is built around three core concepts: extension points, plugins, and extensions.

PF4J and Spring
PF4J supports various technologies, including PF4J Spring, which allows integration with Spring application context. This means plugins can access and inject Spring beans. While PF4J itself is more suited for desktop applications, PF4J Spring makes it useful for web applications as well.

Code Example Overview
To demonstrate PF4J, I prepared a PF4J demo project containing:

  • A "commons" module, which defines an extension point interface called PhraseExtensionPoint.
  • Two plugins: "bye-plugin" and "hello-plugin", both implementing phraseOfTheDay(), returning "Bye!" and "Hello!" respectively.

Building and Packaging Plugins
Each plugin has a build.gradle.kts file specifying dependencies, including pf4j, annotation processing, and the "commons" module. The plugin metadata (e.g., Plugin-Id, Plugin-Version, Plugin-Provider) is stored in the manifest file. After building, plugins are packaged as JAR files and copied to a plugins directory.

Integrating Plugins in a Spring Application
The main Spring application includes:

  • PhraseController, which collects and returns phrases from all loaded plugins.
  • SpringPluginManager, which loads plugins and makes them Spring-aware.
  • The pluginManager ensures that all plugins are available before being accessed by the application.

Running the Application
Once the application starts, making a request to /phrase returns "Hello!" and "Bye!", proving that the plugins work as expected.

Conclusion
PF4J allows you to build flexible applications where you deploy only the necessary features while keeping a monolithic or modular codebase. Plugins can even include their own libraries and dependencies without breaking the main application. This makes it an excellent approach for scalable and customizable systems.

I hope you now have a basic understanding of PF4J. Feel free to ask any questions. See you next time!

Summary

PF4J (Plugin Framework for Java) is a lightweight framework that allows developers to create modular applications using plugins. It enables the integration of custom code into applications through extension points, with support for lifecycle management and Spring integration for dependency injection. PF4J is useful for both desktop and web applications, offering flexibility in scaling and extending functionality without altering the core system.

Social Media

Videos
card image
Aug 6, 2025
GraalVM for Java Developers: The Ultimate Beginner’s Guide

What is GraalVM and how can it improve your Java applications? In just 10 minutes, this video explains the three main components of GraalVM — the JIT compiler, Native Image, and Polyglot API. Learn how to boost performance, reduce startup time, and combine multiple languages in one app. Whether you’re building microservices, serverless apps, or just exploring modern JVM tooling, this is your quick-start guide to GraalVM.

Videos
card image
Jul 15, 2025
Java Downgrade Challenge: From JDK 8 to 1.1 (Part 2)

In Part 2 of the Java Downgrade Challenge, we continue our journey — now from Java 8 all the way to Java 1.1. No streams, no lambdas, no generics, no collections — and at one point, we even boot up Windows 98. If you thought Part 1 was painful, this one unwinds Java history line by line. By the end, the familiar Java from today will be almost gone.

Further watching

Videos
card image
Aug 27, 2025
Buildpacks for Spring Boot

Buildpacks for Spring Boot: no Dockerfiles, no hassle — just production-ready container images in one command. Tired of maintaining Dockerfiles? In this tutorial, you’ll learn how to use buildpacks to create optimized Spring Boot containers — fast, secure, and cloud-ready — with just one command. We’ll show what happens under the hood: automatic dependency detection, layered image creation, memory tuning, SBOM generation, and how to tweak builds with just a few plugin options. Need faster startup, smaller image size, or JFR monitoring? Buildpacks can handle it — and we’ll show you how.

Videos
card image
Aug 20, 2025
Flyway in Spring Boot: Step-by-Step tutorial with Maven

Learn how to use Flyway in Spring Boot with Maven for smooth and reliable database migrations. In this hands-on tutorial, we cover everything from setting up PostgreSQL in Docker, configuring Flyway in your application, writing versioned and repeatable migrations, to using Flyway in CI/CD pipelines with GitHub Actions. Whether you’re new to Flyway or want to master schema version control in Spring Boot, this video will guide you step by step.

Videos
card image
Aug 14, 2025
Stop Using DTOs – A Cleaner Way for Your Java APIs

Still creating DTOs for every API in your Spring Boot project? You might be overcomplicating things. In this video, we show why DTOs aren’t always necessary and how to replace them with @JsonIgnore, @JsonView, and Jackson Mixins. You’ll see real examples of hiding sensitive fields, creating role-based views, and cutting boilerplate — all while keeping your API safe, clean, and easy to maintain.