Appearance
Apache Fineract Plugin JAR Extensibility Guide
Apache Fineract supports extension through plugin JARs - self-contained Spring Boot modules that are loaded at startup alongside the core application. This allows you to add custom endpoints, services, domain logic, or reporting integrations without modifying or forking the upstream codebase.
The plugin mechanism was introduced in FINERACT-1177 and builds on Spring Boot's support for external classpath entries.
Running on Finecko?
Plugin JARs require access to the container runtime and deployment pipeline. If your instance is hosted on Finecko, contact support to discuss custom module support - see Plans.
How Plugin Loading Works
Fineract uses two different loading mechanisms depending on how the application is deployed.
JAR deployment - loader.path
When running Fineract directly as a Spring Boot executable JAR, the Java system property -Dloader.path adds a directory to the classpath before startup. Any JAR files found in that directory are treated as Spring Boot classpath entries and their @Configuration, @Component, and auto-configuration classes are picked up automatically.
bash
java -Dloader.path=libs/ -jar fineract-provider.jarThis starts Fineract and loads all JARs in the libs/ directory (relative to the current working directory) as additional classpath entries. The directory does not need to exist - Fineract will start normally if it is empty or absent.
Docker image - /app/plugins/
The official apache/fineract Docker image is built with Google JIB and includes an explicit extra classpath entry for /app/plugins/* in the JIB container configuration:
groovy
// fineract-provider/build.gradle
container {
mainClass = 'org.apache.fineract.ServerApplication'
extraClasspath = ['/app/plugins/*']
...
}This means the container is pre-configured to load any JARs placed in /app/plugins/ at startup - no additional flags or entrypoint changes are needed.
Adding Plugins via Custom Docker Image
The simplest production workflow is to build a thin custom image on top of the official release:
dockerfile
FROM apache/fineract:latest
COPY my-custom-plugin.jar /app/plugins/my-custom-plugin.jar
COPY another-plugin.jar /app/plugins/another-plugin.jarBuild and run:
bash
docker build -t fineract-custom:latest .
docker run -d \
--name fineract \
-p 8443:8443 \
-e FINERACT_HIKARI_JDBC_URL=jdbc:postgresql://db:5432/fineract_tenants \
-e FINERACT_HIKARI_USERNAME=postgres \
-e FINERACT_HIKARI_PASSWORD=yourpassword \
fineract-custom:latestNo additional environment variables or startup arguments are required. The JARs in /app/plugins/ are on the classpath at launch.
Mounting Plugins at Runtime
If you want to load plugins without rebuilding the image - for example during development or testing - mount the plugin directory as a volume:
yaml
# docker-compose override
services:
fineract:
image: apache/fineract:latest
volumes:
- ./plugins:/app/plugins:roPlace your JARs in the local plugins/ directory. Fineract must be restarted for new JARs to take effect - there is no hot-reload.
Plugin Development Requirements
A plugin JAR must be a valid Spring Boot-compatible module. The key requirements:
- Packaged as a standard JAR (not an executable fat JAR)
- Any Spring
@Configurationclasses should be registered viaMETA-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.importsfor Spring Boot 3.x, orMETA-INF/spring.factoriesfor earlier Boot versions - Must not conflict with classes already present in the core
fineract-provider.jar - Dependencies that are already provided by Fineract (Spring, Hibernate, Jackson, etc.) should be scoped as
compileOnly/providedin the plugin's build file to avoid classpath conflicts
A minimal Gradle plugin module:
groovy
plugins {
id 'java'
id 'org.springframework.boot' apply false
id 'io.spring.dependency-management'
}
dependencyManagement {
imports {
mavenBom 'org.springframework.boot:spring-boot-dependencies:3.3.x'
}
}
dependencies {
compileOnly 'org.springframework.boot:spring-boot-autoconfigure'
compileOnly 'org.apache.fineract:fineract-core:1.14.0'
// your implementation dependencies
}
jar {
enabled = true
archiveClassifier = ''
}WAR Deployment Alternative (Legacy)
Fineract also ships as a WAR file. The WAR format does not natively support loader.path, but JARs can be added by exploding the WAR and placing additional JARs into WEB-INF/lib/. This approach requires manual WAR manipulation and is not recommended for production. The Spring Boot JAR or Docker deployment is the supported path for plugin use.
Intra-Repository Custom Modules
The Fineract repository also includes a custom/ directory structure for building full replacement images that include custom modules at compile time (via the fineract-custom JIB target). This approach produces a single image without a separate plugins/ directory - all modules are part of the classpath from build time. This is a more involved path suited to teams that want to maintain a full fork of the build system, rather than just dropping in JARs.
Known Community Plugins
| Plugin | Description |
|---|---|
| fineract-pentaho | Pentaho reporting integration - replaces the default reporting module with Pentaho Business Analytics |
WARNING
Third-party plugins are community projects and are not maintained by the Apache Fineract PMC. Review their compatibility with your Fineract version before deploying.
Verifying a Plugin Loaded
After starting Fineract with a plugin, check the startup logs for Spring component registration. If your plugin defines a @RestController or @Service, it will appear in the Spring application context output:
INFO o.s.b.w.embedded.tomcat.TomcatWebServer - Tomcat started on port(s): 8443 (https) with context path '/fineract-provider'
INFO o.a.f.ServerApplication - Started ServerApplication in X.XXX secondsTo confirm specific beans from your plugin are registered, you can query the Spring Boot actuator endpoint (if enabled):
bash
curl -k https://localhost:8443/fineract-provider/actuator/beans | jq '.contexts[].beans | keys[]' | grep my-pluginSkip Plugin Management Overhead with Finecko
Managing custom plugin builds, image versioning, and classpath compatibility across Fineract upgrades adds non-trivial operational complexity. Finecko provides a managed platform where custom module support can be handled without maintaining your own image build pipeline.