ServiceLoader
Starting with version 0.12 PF4J comes with a better support for ServiceLoader
.
PF4J can read META-INF/services
(Java Service Provider mechanism) as extensions, so,
if you have a modular application based on java.util.ServiceLoader
class you can replace entirely the ServiceLoader.load()
calls from your application with PluginManager.getExtensions()
and migrate smooth from ServiceLoader to PF4J.
Also you have the possibility to change the ExtensionStorage
used in ExtensionAnnotationProcessor
.
By default we use the format with META-INF/extensions.idx
:
org.pf4j.demo.HowdyGreeting
org.pf4j.demo.WhazzupGreeting
but you can use a more standard location and format, META-INF/services/<extension-point>
, used by Java Service Provider
(see java.util.ServiceLoader
) via ServiceProviderExtensionStorage
implementation.
In this case the format of META-INF/services/org.pf4j.demo.api.Greeting
is:
# Generated by PF4J
org.pf4j.demo.HowdyGreeting
org.pf4j.demo.WhazzupGreeting # pf4j extension
where the org.pf4j.demo.HowdyGreeting
entry is legacy (it’s not generated by PF4J) but it’s seen as
an extension of Greeting
by PF4J (at runtime).
You can plug your custom ExtensionStorage
implementation in ExtensionAnnotationProcessor
in two possible modes:
- set the annotation procesor option with key
pf4j.storageClassName
- set the system property with key
pf4j.storageClassName
For example if I want to use ServiceProviderExtensionStorage
then the value for the pf4j.storageClassName
key must be
org.pf4j.processor.ServiceProviderExtensionStorage
NOTE: ServiceLoaderExtensionFinder
, the class that lookups for extensions stored in META-INF/services
folder, is
not added/enabled by default. To do this please override createExtensionFinder
from DefaultPluginManager
:
protected ExtensionFinder createExtensionFinder() {
DefaultExtensionFinder extensionFinder = super.createExtensionFinder();
extensionFinder.addServiceProviderExtensionFinder();
return extensionFinder;
}