For AI agents: a documentation index is available at /llms.txt. Markdown versions of pages are available by appending .md to any documentation URL.
Skip to main content

Set up a plugin project

Configure the build for a Besu plugin project, implement the BesuPlugin interface, and register the plugin so Besu can discover it at startup.

Prerequisites

  • Java 25+. You can install Java using brew install openjdk@25 or manually install the Java JDK.
  • Gradle.

Steps

1. Configure your build

Besu provides a Gradle plugin to simplify the plugin developer experience, enabling you to bootstrap a new plugin project easily. The plugin:

  • Adds the Maven repositories required to fetch Besu dependencies.
  • Pre-populates the compile classpath with everything Besu provides, using the Besu BOM and an artifact catalog.
  • Produces a slim distribution ZIP that excludes JARs already on Besu's classpath.

In a new plugin project, apply the Gradle plugin (net.consensys.besu-plugin-distribution), and set the Besu version you want to compile your plugin against:

build.gradle
plugins {
id 'net.consensys.besu-plugin-distribution' version '0.2.1'
}

besuPlugin {
besuVersion = '26.6.0'
}
note

The Gradle plugin resolves the matching Besu API JARs as compile-time dependencies, so your plugin builds against that version's API surface.

Multi-module projects

In a multi-module project, apply net.consensys.besu-plugin-library to modules that are shared libraries rather than plugins themselves. Apply net.consensys.besu-plugin-distribution only to modules that directly expose BesuPlugin implementations.

library/build.gradle
plugins {
id 'net.consensys.besu-plugin-library' version '0.2.1'
}

Library modules are excluded from the plugin distribution ZIP.

Declare extra dependencies

Only declare dependencies that Besu does not already provide. The Gradle plugin pre-populates the classpath from the Besu BOM and artifact catalog, so most Besu-related libraries are already available without an explicit declaration.

warning

Bundling a JAR that Besu already provides causes classloading conflicts at runtime and may prevent your plugin from loading.

Configure the build manually

If you prefer not to use the Gradle plugin, add besu-plugin-api to your build, matching the Besu version you are targeting:

build.gradle
dependencies {
compileOnly 'org.hyperledger.besu:besu-plugin-api:26.6.0'
}

Use compileOnly because besu-plugin-api is provided by Besu at runtime and must not be bundled in your JAR. You are responsible for managing all other Besu dependencies and configuring the packaging task to produce a slim distribution.

2. Generate the Gradle wrapper

Generate the Gradle wrapper so the project builds with a consistent Gradle version. This creates the gradlew script used to build and deploy the plugin:

gradle wrapper

3. Implement the plugin class

Create a class that implements BesuPlugin. The three required methods are register, start, and stop.

Besu calls register(ServiceManager) early in startup. ServiceManager is the interface through which your plugin accesses all Besu services. This is the only time it is provided, so store it in a field for later use.

The getName method is optional; it defaults to the fully qualified class name, but overriding it with a short string gives your plugin a readable identifier.

ExamplePlugin.java
package example;

import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.ServiceManager;

public class ExamplePlugin implements BesuPlugin {
private ServiceManager serviceManager;

@Override
public String getName() {
return "example";
}

@Override
public void register(final ServiceManager serviceManager) {
this.serviceManager = serviceManager;
}

@Override
public void start() {}

@Override
public void stop() {}
}

4. Register the plugin for discovery

Besu discovers plugin classes using Java's ServiceLoader. Register your plugin by including a service provider entry for BesuPlugin. You can generate the entry using Google's @AutoService annotation processor:

ExamplePlugin.java
import com.google.auto.service.AutoService;
import org.hyperledger.besu.plugin.BesuPlugin;

@AutoService(BesuPlugin.class)
public class ExamplePlugin implements BesuPlugin { ... }

The annotation processor generates the META-INF/services entry at compile time.

Create a service file manually

If you prefer not to use the annotation processor, you can manually create the following file under src/main/resources:

META-INF/services/org.hyperledger.besu.plugin.BesuPlugin

The file must contain the fully qualified class name of each BesuPlugin implementation, one per line:

example.ExamplePlugin

Next steps