### Initialize PluginManager Source: https://pf4j.org/doc/getting-started.html Basic setup for loading and starting plugins using the DefaultPluginManager. ```java public static void main(String[] args) { ... PluginManager pluginManager = new DefaultPluginManager(); pluginManager.loadPlugins(); pluginManager.startPlugins(); ... } ``` -------------------------------- ### Plugin Dependency Specification Examples Source: https://pf4j.org/doc/plugins.html Examples demonstrating how to specify plugin dependencies in metadata, including version ranges and multiple dependencies. Ensure correct syntax for version matching. ```properties Plugin-Dependencies: pluginB ``` ```properties Plugin-Dependencies: pluginB@1.0 ``` ```properties Plugin-Dependencies: pluginB@>=1.0.0 ``` ```properties Plugin-Dependencies: pluginB@>=1.0.0 & <2.0.0 ``` ```properties Plugin-Dependencies: pluginB@>=1.0.0 & <=2.0.0 ``` ```properties Plugin-Dependencies: pluginB@>=1.0.0 & <=2.0.0, pluginC@>=0.0.1 & <=0.1.0 ``` -------------------------------- ### Load and start plugins synchronously Source: https://pf4j.org/doc/async.html Standard approach for loading and starting plugins using the DefaultPluginManager. ```java // create the plugin manager final PluginManager pluginManager = new DefaultPluginManager(); // load the plugins pluginManager.loadPlugins(); // start (active/resolved) the plugins pluginManager.startPlugins(); // retrieves the extensions for Greeting extension point List greetings = pluginManager.getExtensions(Greeting.class); ``` -------------------------------- ### View Plugin Directory Structure Source: https://pf4j.org/doc/packaging.html Examples of the directory structure for plugins using different packaging formats. ```bash $ tree plugins plugins ├── disabled.txt ├── enabled.txt ├── demo-plugin1-2.4.0.zip └── demo-plugin2-2.4.0.zip ``` ```bash $ tree plugins plugins ├── disabled.txt ├── enabled.txt ├── demo-plugin1-2.4.0.jar └── demo-plugin2-2.4.0.jar ``` ```bash $ tree plugins plugins ├── disabled.txt ├── enabled.txt ├── demo-plugin1-2.4.0.jar └── demo-plugin2-2.4.0.zip ``` -------------------------------- ### Define Plugin Manifest Source: https://pf4j.org/doc/getting-started.html Example of a MANIFEST.MF file used to describe plugin metadata. ```text Manifest-Version: 1.0 Archiver-Version: Plexus Archiver Created-By: Apache Maven Built-By: decebal Build-Jdk: 1.6.0_17 Plugin-Class: org.pf4j.demo.welcome.WelcomePlugin Plugin-Dependencies: x, y, z Plugin-Id: welcome-plugin Plugin-Provider: Decebal Suiu Plugin-Version: 0.0.1 ``` -------------------------------- ### Load and start plugins asynchronously Source: https://pf4j.org/doc/async.html Asynchronous approach using AsyncPluginManager to load and start plugins, returning CompletionStage for non-blocking operations. ```java // create the plugin manager final AsyncPluginManager pluginManager = new DefaultAsyncPluginManager(); // load the plugins CompletionStage stage = pluginManager.loadPluginsAsync(); stage.thenRun(() -> System.out.println("Plugins loaded")); // optional // start (active/resolved) the plugins stage.thenCompose(v -> pluginManager.startPluginsAsync()); stage.thenRun(() -> System.out.println("Plugins started")); // optional // block and wait for the future to complete (not the best approach in real applications) stage.toCompletableFuture().get(); // retrieves the extensions for Greeting extension point List greetings = pluginManager.getExtensions(Greeting.class); ``` -------------------------------- ### Example META-INF/services/org.pf4j.demo.api.Greeting format Source: https://pf4j.org/doc/serviceloader.html This is the standard Java Service Provider format for `META-INF/services`, which PF4J can also read. ```text # Generated by PF4J org.pf4j.demo.HowdyGreeting org.pf4j.demo.WhazzupGreeting # pf4j extension ``` -------------------------------- ### Example META-INF/extensions.idx format Source: https://pf4j.org/doc/serviceloader.html This is the default format used by PF4J for storing extension indexes. ```text org.pf4j.demo.HowdyGreeting org.pf4j.demo.WhazzupGreeting ``` -------------------------------- ### Initialize PluginManager and Retrieve Extensions Source: https://pf4j.org/doc/system-extension.html Standard initialization sequence for the PluginManager including loading and starting plugins before retrieving extensions. ```java public static void main(String[] args) { PluginManager pluginManager = new DefaultPluginManager(); pluginManager.loadPlugins(); pluginManager.startPlugins(); List greetings = pluginManager.getExtensions(Greeting.class); for (Greeting greeting : greetings) { System.out.println(">>> " + greeting.getGreeting()); } } ``` -------------------------------- ### Minimalist Extension Retrieval Source: https://pf4j.org/doc/system-extension.html Simplified initialization for system extensions by skipping explicit plugin loading and starting steps. ```java public static void main(String[] args) { PluginManager pluginManager = new DefaultPluginManager(); List greetings = pluginManager.getExtensions(Greeting.class); for (Greeting greeting : greetings) { System.out.println(">>> " + greeting.getGreeting()); } } ``` -------------------------------- ### Generate PF4J Project with Maven Source: https://pf4j.org/dev/quickstart.html Use the PF4J Maven archetype to bootstrap a new project. Ensure Maven is installed and configured before execution. ```bash mvn archetype:generate \ -DarchetypeGroupId=org.pf4j \ -DarchetypeArtifactId=pf4j-quickstart \ -DarchetypeVersion=3.6.0 \ -DgroupId=com.mycompany \ -DartifactId=myproject ``` -------------------------------- ### Define a PF4J Plugin Class Source: https://pf4j.org/doc/plugins.html Create a `Plugin` class to handle plugin lifecycle events like start, stop, and delete. This is optional if you only need to load classes without lifecycle management. ```java import org.pf4j.Plugin; import org.pf4j.PluginException; import org.pf4j.PluginWrapper; public class MyPlugin extends Plugin { public MyPlugin(PluginWrapper wrapper) { super(wrapper); } @Override public void start() throws PluginException { // This method is called by the application when the plugin is started. } @Override public void stop() throws PluginException { // This method is called by the application when the plugin is stopped. } @Override public void delete() throws PluginException { // This method is called by the application when the plugin is deleted. } } ``` -------------------------------- ### Customizing DefaultPluginManager for JAR plugins Source: https://pf4j.org/doc/custom-manager.html This example shows how to create a custom plugin manager by extending DefaultPluginManager. It specifically configures the plugin loader to only handle JAR plugins and the descriptor finder to read from the JAR's manifest file. ```java PluginManager pluginManager = new DefaultPluginManager() { @Override protected PluginLoader createPluginLoader() { // load only jar plugins return new JarPluginLoader(this); } @Override protected PluginDescriptorFinder createPluginDescriptorFinder() { // read plugin descriptor from jar's manifest return new ManifestPluginDescriptorFinder(); } }; ``` -------------------------------- ### Run the Generated Application Source: https://pf4j.org/dev/quickstart.html Navigate to the project directory and execute the provided run script. ```bash cd myproject chmod u+x run.sh ./run.sh ``` -------------------------------- ### Enable Development Mode via System Property Source: https://pf4j.org/doc/development-mode.html Set the runtime mode to development by passing a system property to the application launcher. ```text -Dpf4j.mode=development ``` -------------------------------- ### Run PF4J Demo Application Source: https://pf4j.org/doc/demo.html Execute the demo application using the provided shell or batch scripts based on the operating system. ```shell ./run-demo.sh (for Linux/Unix) ./run-demo.bat (for Windows) ``` -------------------------------- ### Configure enabled.txt for Plugin Loading Source: https://pf4j.org/doc/disable-plugins.html Create an enabled.txt file in the plugins folder to specify exactly which plugins should be loaded. If this file exists, disabled.txt is ignored. ```text ######################################## # - load only these plugins # - add one plugin id on each line # - put this file in plugins folder ######################################## welcome-plugin ``` -------------------------------- ### Implement SingletonExtensionFactory Source: https://pf4j.org/doc/extension-instantiation.html Use SingletonExtensionFactory to ensure that the same extension instance is returned for every request. ```java new DefaultPluginManager() { @Override protected ExtensionFactory createExtensionFactory() { return SingletonExtensionFactory(); } }; ``` -------------------------------- ### Configure disabled.txt for Plugin Exclusion Source: https://pf4j.org/doc/disable-plugins.html Create a disabled.txt file in the plugins folder to specify which plugins should be excluded from loading. This file is only processed if enabled.txt is absent. ```text ######################################## # - load all plugins except these # - add one plugin id on each line # - put this file in plugins folder ######################################## welcome-plugin ``` -------------------------------- ### Implement Plugin and Extension Source: https://pf4j.org/doc/getting-started.html Implementation of a plugin class and an extension using the @Extension annotation. ```java public class WelcomePlugin extends Plugin { public WelcomePlugin(PluginWrapper wrapper) { super(wrapper); } @Extension public static class WelcomeGreeting implements Greeting { public String getGreeting() { return "Welcome"; } } } ``` -------------------------------- ### Configure Parent-First Loading Strategy Source: https://pf4j.org/doc/class-loading.html Override createPluginClassLoader in DefaultPluginManager to implement the APD (Application-Plugin-Dependencies) strategy. ```java new DefaultPluginManager() { @Override protected PluginClassLoader createPluginClassLoader(Path pluginPath, PluginDescriptor pluginDescriptor) { return new PluginClassLoader(pluginManager, pluginDescriptor, getClass().getClassLoader(), ClassLoadingStrategy.APD); } }; ``` -------------------------------- ### Define plugin.properties Source: https://pf4j.org/doc/getting-started.html Configuration file content for properties-based plugin descriptors. ```properties plugin.class=org.pf4j.demo.welcome.WelcomePlugin plugin.dependencies=x, y, z plugin.id=welcome-plugin plugin.provider=Decebal Suiu plugin.version=0.0.1 ``` -------------------------------- ### Extension Retrieval Output Source: https://pf4j.org/doc/getting-started.html Expected console output after retrieving extensions. ```text >>> Welcome >>> Hello ``` -------------------------------- ### Load Extensions in Application Source: https://pf4j.org/doc/extensions.html Retrieve and execute extensions using the PluginManager during application runtime. ```java import javax.swing.JDialog; import javax.swing.JMenu; import javax.swing.JMenuBar; import org.pf4j.DefaultPluginManager; import org.pf4j.PluginManager; public static void main(String[] args) { // Init the plugin environment. // This should be done once during the boot process of the application. final PluginManager pluginManager = new DefaultPluginManager(); pluginManager.loadPlugins(); pluginManager.startPlugins(); // Launch Swing application. java.awt.EventQueue.invokeLater(new Runnable() { public void run() { // Build the menu bar by using the available extensions. JMenuBar mainMenu = new JMenuBar(); for (MainMenuExtensionPoint extension : pluginManager.getExtensions(MainMenuExtensionPoint.class)) { extension.buildMenuBar(mainMenu); } // Create and show a dialog with the menu bar. JDialog dialog = new JDialog(); dialog.setTitle("Example dialog"); dialog.setSize(450,300); dialog.setJMenuBar(mainMenu); dialog.setVisible(true); } }); } ``` -------------------------------- ### Enable ServiceLoaderExtensionFinder in DefaultPluginManager Source: https://pf4j.org/doc/serviceloader.html Override `createExtensionFinder` in `DefaultPluginManager` to add the `ServiceLoaderExtensionFinder`. This allows PF4J to discover extensions from `META-INF/services`. ```java final PluginManager pluginManager = new DefaultPluginManager() { protected ExtensionFinder createExtensionFinder() { DefaultExtensionFinder extensionFinder = (DefaultExtensionFinder) super.createExtensionFinder(); extensionFinder.addServiceProviderExtensionFinder(); return extensionFinder; } }; ``` -------------------------------- ### Configure Maven for Snapshot Repositories Source: https://pf4j.org/dev/maven.html Add this repository configuration to your pom.xml to access the latest PF4J SNAPSHOT versions from Sonatype. ```xml sonatype-nexus-snapshots https://oss.sonatype.org/content/repositories/snapshots false true ``` -------------------------------- ### Configure Maven Compiler Plugin for PF4J Source: https://pf4j.org/doc/getting-started.html Add this configuration to the maven-compiler-plugin to ensure the ExtensionAnnotationProcessor is executed during the build. ```xml org.apache.maven.plugins maven-compiler-plugin 2.5.1 org.pf4j.processor.ExtensionAnnotationProcessor ``` -------------------------------- ### Plugin Metadata in MANIFEST.MF Source: https://pf4j.org/doc/plugins.html Add this content to the META-INF/MANIFEST.MF file of your plugin to define its metadata. Ensure all required fields are present. ```properties Plugin-Class: org.pf4j.demo.welcome.WelcomePlugin Plugin-Id: welcome-plugin Plugin-Version: 0.0.1 Plugin-Requires: 1.0.0 Plugin-Dependencies: x, y, z Plugin-Description: My example plugin Plugin-Provider: Decebal Suiu Plugin-License: Apache License 2.0 ``` -------------------------------- ### Plugin Metadata with Maven Assembly Plugin Source: https://pf4j.org/doc/plugins.html Utilize the maven-assembly-plugin to package your plugin with dependencies and include metadata. This configuration ensures all necessary components are bundled correctly. ```xml org.apache.maven.plugins maven-assembly-plugin jar-with-dependencies ${project.artifactId}-${project.version}-plugin false false true true org.pf4j.demo.welcome.WelcomePlugin welcome-plugin 0.0.1 1.0.0 x, y, z My example plugin Decebal Suiu Apache License 2.0 make-assembly package single ``` -------------------------------- ### DefaultPluginManager component configuration Source: https://pf4j.org/doc/custom-manager.html This snippet demonstrates how DefaultPluginManager configures its components, such as PluginDescriptorFinder, PluginRepository, and PluginLoader, using compound implementations to support multiple plugin types. ```java public class DefaultPluginManager extends AbstractPluginManager { // other methods @Override protected PluginDescriptorFinder createPluginDescriptorFinder() { return new CompoundPluginDescriptorFinder() .add(new PropertiesPluginDescriptorFinder()) .add(new ManifestPluginDescriptorFinder()); } @Override protected PluginRepository createPluginRepository() { return new CompoundPluginRepository() .add(new DefaultPluginRepository(getPluginsRoot(), isDevelopment())) .add(new JarPluginRepository(getPluginsRoot())); } @Override protected PluginLoader createPluginLoader() { return new CompoundPluginLoader() .add(new DefaultPluginLoader(this, pluginClasspath)) .add(new JarPluginLoader(this)); } } ``` -------------------------------- ### Retrieve Extensions Source: https://pf4j.org/doc/getting-started.html Access all registered extensions for a specific extension point. ```java List greetings = pluginManager.getExtensions(Greeting.class); for (Greeting greeting : greetings) { System.out.println(">>> " + greeting.getGreeting()); } ``` -------------------------------- ### Define optional plugin dependency Source: https://pf4j.org/doc/plugins.html Use a question mark suffix to mark a plugin dependency as optional. ```text Plugin-Dependencies: pluginB? ``` ```text Plugin-Dependencies: pluginB?@1.0 ``` -------------------------------- ### Implement an Extension Source: https://pf4j.org/doc/extensions.html Use the @Extension annotation to mark a class as a loadable implementation of an extension point. ```java import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import org.pf4j.Extension; @Extension public class MyMainMenuExtension implements MainMenuExtensionPoint { public void buildMenuBar(JMenuBar menuBar) { JMenu exampleMenu = new JMenu("Example"); exampleMenu.add(new JMenuItem("Hello World")); menuBar.add(exampleMenu); } } ``` -------------------------------- ### Extension retrieval behavior Source: https://pf4j.org/doc/extension-instantiation.html By default, calling getExtensions multiple times results in the creation of a new instance for each call. ```java plugin.getExtensions(MyExtensionPoint.class); plugin.getExtensions(MyExtensionPoint.class); ``` -------------------------------- ### Abstract methods for AbstractPluginManager Source: https://pf4j.org/doc/custom-manager.html These are the abstract methods that need to be implemented when creating a custom plugin manager by extending AbstractPluginManager. They define the core components of the plugin management system. ```java public abstract class AbstractPluginManager implements PluginManager { protected abstract PluginRepository createPluginRepository(); protected abstract PluginFactory createPluginFactory(); protected abstract ExtensionFactory createExtensionFactory(); protected abstract PluginDescriptorFinder createPluginDescriptorFinder(); protected abstract ExtensionFinder createExtensionFinder(); protected abstract PluginStatusProvider createPluginStatusProvider(); protected abstract PluginLoader createPluginLoader(); // other non abstract methods } ``` -------------------------------- ### Plugin Metadata in plugin.properties Source: https://pf4j.org/doc/plugins.html Define plugin metadata in a 'plugin.properties' file located in the root of your plugin folder or ZIP archive. This is a simple key-value format for configuration. ```properties plugin.class=org.pf4j.demo.welcome.WelcomePlugin plugin.id=welcome-plugin plugin.version=0.0.1 plugin.requires=1.0.0 plugin.dependencies=x, y, z plugin.description=My example plugin plugin.provider=Decebal Suiu plugin.license=Apache License 2.0 ``` -------------------------------- ### Define Extension Point Source: https://pf4j.org/doc/getting-started.html Create an extension point by extending the ExtensionPoint interface marker. ```java public interface Greeting extends ExtensionPoint { String getGreeting(); } ``` -------------------------------- ### PluginClassLoader Constructors Source: https://pf4j.org/doc/class-loading.html Constructors for initializing a PluginClassLoader with default or custom loading strategies. ```java // Default constructor (using PDA strategy) public PluginClassLoader(PluginManager pluginManager, PluginDescriptor pluginDescriptor, ClassLoader parent) // Constructor with strategy public PluginClassLoader(PluginManager pluginManager, PluginDescriptor pluginDescriptor, ClassLoader parent, ClassLoadingStrategy classLoadingStrategy) ``` -------------------------------- ### Custom PluginLoader Interface Source: https://pf4j.org/doc/class-loading.html Interface definition for implementing custom plugin loading logic. ```java public interface PluginLoader { boolean isApplicable(Path pluginPath); ClassLoader loadPlugin(Path pluginPath, PluginDescriptor pluginDescriptor); } ``` -------------------------------- ### Identify Plugin for a Class Source: https://pf4j.org/doc/class-loading.html Determine which plugin loaded a specific class instance using the plugin manager. ```java pluginManager.whichPlugin(MyClass.class); ``` -------------------------------- ### Define an Extension Point Source: https://pf4j.org/doc/extensions.html Create an interface extending ExtensionPoint to define the contract for application extensions. ```java import javax.swing.JMenuBar; import org.pf4j.ExtensionPoint; interface MainMenuExtensionPoint extends ExtensionPoint { void buildMenuBar(JMenuBar menuBar); } ``` -------------------------------- ### Define required plugins for an extension Source: https://pf4j.org/doc/extensions.html Use the plugins attribute in the @Extension annotation to ensure an extension is only loaded if the specified plugins are available at runtime. ```java @Extension(plugins = {ContactsPlugin.ID, CalendarPlugin.ID}) public class CalendarContactsFormExtension implements ContactsFormExtension { public JPanel getPanel() { // some implementation... } public void load(ContactsEntry entry) { // some implementation... } public void load(ContactsEntry save) { // some implementation... } } ``` ```java @Extension(plugins = {ContactsPlugin.ID, CalendarPlugin.ID}) public class ContactsCalendarFormExtension implements CalendarFormExtension { public JPanel getPanel() { // some implementation... } public void load(CalendarEntry entry) { // some implementation... } public void load(CalendarEntry save) { // some implementation... } } ``` -------------------------------- ### Add PF4J Dependency to Maven pom.xml Source: https://pf4j.org/dev/maven.html Include this dependency in your pom.xml to use the PF4J library. Replace ${pf4j.version} with the latest PF4J version. ```xml org.pf4j pf4j ${pf4j.version} ``` -------------------------------- ### Retrieve Runtime Mode Source: https://pf4j.org/doc/development-mode.html Access the current runtime mode programmatically from the PluginManager or within a Plugin implementation. ```java PluginManager.getRuntimeMode() ``` ```java getWrapper().getRuntimeMode() ``` -------------------------------- ### Customize ExtensionFactory in DefaultPluginManager Source: https://pf4j.org/doc/extension-instantiation.html Override the createExtensionFactory method within a DefaultPluginManager subclass to provide a custom factory implementation. ```java new DefaultPluginManager() { @Override protected ExtensionFactory createExtensionFactory() { return MyExtensionFactory(); } }; ``` -------------------------------- ### Plugin Metadata with Maven JAR Plugin Source: https://pf4j.org/doc/plugins.html Configure the maven-jar-plugin in your pom.xml to include plugin metadata in the JAR archive. This method allows for programmatic definition of plugin attributes. ```xml org.apache.maven.plugins maven-jar-plugin true true org.pf4j.demo.welcome.WelcomePlugin welcome-plugin 0.0.1 1.0.0 x, y, z My example plugin Decebal Suiu Apache License 2.0 ``` -------------------------------- ### Add PF4J Testing Dependency to Maven POM Source: https://pf4j.org/doc/testing.html Include this dependency in your Maven POM file to access PF4J testing utilities. Ensure the version matches your PF4J library version. ```xml org.pf4j pf4j ${pf4j.version} test-jar test ``` -------------------------------- ### Order Extensions with Ordinal Source: https://pf4j.org/doc/extensions.html Control the loading sequence of extensions by specifying an ordinal value in the @Extension annotation. ```java @Extension(ordinal = 1) public class FirstMainMenuExtension implements MainMenuExtensionPoint { public void buildMenuBar(JMenuBar menuBar) { JMenu menu = new JMenu("First"); menu.add(new JMenuItem("Hello World")); menuBar.add(menu); } } ``` ```java @Extension(ordinal = 2) public class SecondMainMenuExtension implements MainMenuExtensionPoint { public void buildMenuBar(JMenuBar menuBar) { JMenu menu = new JMenu("Second"); menu.add(new JMenuItem("Hello World")); menuBar.add(menu); } } ``` -------------------------------- ### Override PluginDescriptorFinder Source: https://pf4j.org/doc/getting-started.html Customizing the plugin descriptor discovery by overriding the factory method. ```java protected PluginDescriptorFinder createPluginDescriptorFinder() { return new PropertiesPluginDescriptorFinder(); } ``` -------------------------------- ### Explicitly register an extension point Source: https://pf4j.org/doc/extensions.html Use the points attribute in the @Extension annotation when an extension class does not directly implement the org.pf4j.ExtensionPoint interface. ```java @Extension(points = {MainMenuExtensionPoint.class}) public class Plugin1MainMenuExtension extends MainMenuAdapter { public void buildMenuBar(JMenuBar menuBar) { // some implementation... } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.