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
Feb 6, 2026
Backend Developer Roadmap 2026: What You Need to Know

Backend complexity keeps growing, and frameworks can't keep up. In 2026, knowing React or Django isn't enough. You need fundamentals that hold up when systems break, traffic spikes, or your architecture gets rewritten for the third time.I've been building production systems for 15 years. This roadmap covers three areas that separate people who know frameworks from people who can actually architect backend systems: data, architecture, and infrastructure. This is about how to think, not what tools to install.

Videos
card image
Jan 29, 2026
JDBC Connection Pools in Microservices. Why They Break Down (and What to Do Instead)

In this livestream, Catherine is joined by Rogerio Robetti, the founder of Open J Proxy, to discuss why traditional JDBC connection pools break down when teams migrate to microservices, and what is a more efficient and reliable approach to organizing database access with microservice architecture.

Further watching

Videos
card image
Feb 27, 2026
Spring Developer Roadmap 2026: What You Need to Know

Spring Boot is powerful. But knowing the framework isn’t the same as understanding backend engineering. In this video, I walk through the roadmap I believe matters for a Spring developer in 2026. We start with data. That means real SQL — CTEs, window functions, normalization trade-offs — and understanding what ACID and BASE actually imply for system guarantees. Spring Data JPA is useful, but you still need to know what happens underneath. Then architecture: microservices vs modular monolith, serverless, CQRS, and when HTTP, gRPC, Kafka, or WebSockets make sense. Not as buzzwords — but as design choices with trade-offs. Security and infrastructure follow: OWASP Top 10, AuthN vs AuthZ, encryption in transit and at rest, Docker, Kubernetes, Infrastructure as Code, and observability with Micrometer, OpenTelemetry, and Grafana. This roadmap isn’t about mastering every tool. It’s about knowing what affects reliability in production.

Videos
card image
Feb 18, 2026
Build Typed AI Agents in Java with Embabel

Most Java AI demos stop at prompt loops. That doesn't scale in production. In this video, we integrate Embabel into an existing Spring Boot application and build a multi-step, goal-driven agent for incident triage. Instead of manually orchestrating prompt → tool → prompt cycles, we define typed actions and let the agent plan across deterministic and LLM-powered steps. We parse structured input with Ollama, query MongoDB deterministically, classify risk using explicit thresholds, rank affected implants, generate a constrained root cause hypothesis, and produce a bounded containment plan. LLM handles reasoning. Java enforces rules. This is about controlled AI workflows on the JVM — not prompt glue code.

Videos
card image
Feb 12, 2026
Spring Data MongoDB: From Repositories to Aggregations

Spring Data MongoDB breaks down fast once CRUD meets production—real queries, actual data volumes, analytics. What looks simple at first quickly turns into unreadable repository methods, overfetching, and slow queries. In this video, I walk through building a production-style Spring Boot application using Spring Data MongoDB — starting with basic setup and repositories, then moving into indexing, projections, custom queries, and aggregation pipelines. You'll see how MongoDB's document model changes data design compared to SQL, when embedding helps, and when it becomes a liability. We cover where repository method naming stops scaling, how to use @Query safely, when to switch to MongoTemplate, and how to reduce payload size with projections and DTOs. Finally, we implement real MongoDB aggregations to calculate analytics directly in the database and test everything against a real MongoDB instance using Testcontainers. This is not another MongoDB overview. It's a practical guide to actually using Spring Data MongoDB in production without fighting the database.