### Good Logging Practices Example Source: https://docs.siea.dev/jonion/other/logging Shows effective logging within plugin start and stop methods, including using placeholders for dynamic information, logging exceptions, and providing context. This example adheres to best practices for clarity and debugging. ```java @Override public void start() { PluginDescriptor meta = getMetaData(); getLogger().info("Starting {} v{}", meta.getPluginId(), meta.getVersion()); try { PluginConfig config = getDefaultConfig(); String message = config.getString("message", "Default"); getLogger().debug("Loaded configuration: message={}", message); // Plugin logic... getLogger().info("Plugin {} started successfully", meta.getPluginId()); } catch (Exception e) { getLogger().error("Failed to start plugin {}", meta.getPluginId(), e); throw e; } } @Override public void stop() { getLogger().info("Stopping plugin {}", getMetaData().getPluginId()); // Cleanup logic... getLogger().info("Plugin stopped"); } ``` -------------------------------- ### Comprehensive Plugin Error Handling Example Source: https://docs.siea.dev/jonion/other/error-handling Demonstrates handling configuration errors and unexpected exceptions within a plugin's start method, including validation and logging. ```java @Override public void start() { try { PluginConfig config = getDefaultConfig(); // Validate configuration if (config.getString("required-key") == null) { throw new ConfigException("Required configuration key is missing"); } // Use configuration String value = config.getString("required-key"); getLogger().info("Starting with value: {}", value); } catch (ConfigException e) { getLogger().error("Configuration error in plugin {}", getId(), e); // Handle error appropriately } catch (Exception e) { getLogger().error("Unexpected error in plugin {}", getId(), e); // Handle unexpected errors } } ``` -------------------------------- ### Start Plugin with Metadata Logging Source: https://docs.siea.dev/jonion/creating-a-plugin/plugin-meta-data Log plugin details such as ID, version, description, and authors during the plugin's start phase. Also checks for and logs the number of dependencies. ```java @Override public void start() { PluginDescriptor meta = getMetaData(); getLogger().info("Starting {} v{}", meta.getPluginId(), meta.getVersion()); getLogger().info("Description: {}", meta.getDescription()); getLogger().info("Authors: {}", String.join(", ", meta.getAuthors())); // Check dependencies List deps = meta.getDependencies(); if (!deps.isEmpty()) { getLogger().info("Dependencies: {}", deps.size()); } } ``` -------------------------------- ### Example JSON Descriptor Format Source: https://docs.siea.dev/jonion/advanced/descriptors-and-descriptor-finders This is an example of a JSON file that could be used as a plugin descriptor. It includes essential information like name, version, main class, and dependencies. ```json { "name": "my-plugin", "version": "1.0.0", "description": "My plugin", "main": "com.example.MyPlugin", "authors": ["YourName"], "license": "MIT", "dependencies": { "other-plugin": true } } ``` -------------------------------- ### Using Default Plugin Manager Source: https://docs.siea.dev/jonion/creating-a-plugin-system/setting-up-a-plugin-manager Demonstrates the basic setup for loading and managing plugins using Jonion's default implementation. Ensure plugins extend `SimplePlugin`. ```java import dev.siea.jonion.manager.DefaultPluginManager; import dev.siea.jonion.impl.SimplePlugin; import java.nio.file.Paths; public class Main { public static void main(String[] args) { // Create plugin manager (loads plugins from "plugins" directory) DefaultPluginManager pluginManager = new DefaultPluginManager(); // Start all plugins pluginManager.start(); // Your application logic here... // Stop all plugins when shutting down pluginManager.stop(); } } ``` ```java import dev.siea.jonion.impl.SimplePlugin; public class MyPlugin extends SimplePlugin { @Override public void start() { getLogger().info("Plugin started!"); } @Override public void stop() { getLogger().info("Plugin stopped!"); } } ``` -------------------------------- ### Accessing and Using the Logger in a Plugin Source: https://docs.siea.dev/jonion/other/logging Demonstrates how to get the logger instance within a plugin and log messages at various levels. Ensure you have the necessary SLF4J imports. ```java import org.slf4j.Logger; @Override public void start() { Logger logger = getLogger(); logger.info("Plugin started!"); logger.warn("This is a warning"); logger.error("An error occurred", exception); logger.debug("Debug information"); } ``` -------------------------------- ### Read Generic Configuration Values Source: https://docs.siea.dev/jonion/creating-a-plugin/plugin-configurations Use the generic `get()` method to retrieve configuration values of any type. A default value can also be provided. ```java // Generic Object value = config.get("key"); Object value = config.get("key", defaultValue); ``` -------------------------------- ### Implementing a Custom Plugin Descriptor Finder Source: https://docs.siea.dev/jonion/advanced/descriptors-and-descriptor-finders Implement the `PluginDescriptorFinder` interface to support custom descriptor formats like JSON. This example shows the basic structure for reading and parsing a JSON descriptor. ```java import dev.siea.jonion.descriptor.PluginDescriptor; import dev.siea.jonion.descriptor.DefaultPluginDescriptor; import dev.siea.jonion.descriptor.finder.PluginDescriptorFinder; import dev.siea.jonion.depedency.PluginDependency; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; public class JsonDescriptorFinder implements PluginDescriptorFinder { @Override public PluginDescriptor findPluginDescriptor(Path path) { // Read JSON file from JAR // Parse JSON and extract plugin information // Return a PluginDescriptor // Example structure: String pluginId = "my-plugin"; // from JSON String description = "My plugin"; // from JSON String version = "1.0.0"; // from JSON String pluginClass = "com.example.MyPlugin"; // from JSON List authors = new ArrayList<>(); // from JSON String license = "MIT"; // from JSON DefaultPluginDescriptor descriptor = new DefaultPluginDescriptor( pluginId, description, version, pluginClass, authors, license ); // Add dependencies if any // descriptor.addDependency(new PluginDependency("other-plugin", true)); return descriptor; } } ``` -------------------------------- ### Creating a Custom Plugin Base Class Source: https://docs.siea.dev/jonion/creating-a-plugin-system/setting-up-a-plugin-manager Defines a custom plugin base class that extends Jonion's `Plugin`. Subclasses will override `start` and `stop` methods. ```java package com.example.api; import dev.siea.jonion.Plugin; public class MyPlugin extends Plugin { public void start() { // To be overridden by subclasses } public void stop() { // To be overridden by subclasses } } ``` -------------------------------- ### Example of Circular Dependencies Source: https://docs.siea.dev/jonion/creating-a-plugin/plugin-dependencies Illustrates a circular dependency scenario where Plugin A depends on Plugin B, and Plugin B depends on Plugin A. This configuration will cause both plugins to fail loading. ```yaml # Plugin A name: plugin-a dependencies: plugin-b: true # Plugin B name: plugin-b dependencies: plugin-a: true ``` -------------------------------- ### Get Plugins by State Source: https://docs.siea.dev/jonion/advanced/plugin-states Retrieve lists of plugins that are currently in a specific state, such as LOADED or FAILED. This allows for batch operations or status checks on multiple plugins simultaneously. ```java import dev.siea.jonion.manager.PluginManager; PluginManager manager = getPluginWrapper().getPluginManager(); // Get all loaded plugins List loadedPlugins = manager.getPlugins(PluginState.LOADED); // Get all failed plugins List failedPlugins = manager.getPlugins(PluginState.FAILED); ``` -------------------------------- ### Check for Loaded Plugin Dependency at Runtime Source: https://docs.siea.dev/jonion/creating-a-plugin/plugin-dependencies In your plugin's start method, use the PluginManager to check if a specific dependency is loaded. This allows for conditional logic based on dependency availability. ```java @Override public void start() { PluginManager manager = getPluginWrapper().getPluginManager(); PluginWrapper optional = manager.getPlugin("optional-plugin"); if (optional != null) { getLogger().info("Optional plugin found!"); } else { getLogger().info("Optional plugin not found."); } } ``` -------------------------------- ### Get Metadata from Another Plugin Source: https://docs.siea.dev/jonion/creating-a-plugin/plugin-meta-data Access metadata of another plugin by its ID using the PluginManager. Retrieves the PluginDescriptor for the specified plugin and logs its version if found. ```java import dev.siea.jonion.manager.PluginManager; import dev.siea.jonion.PluginWrapper; PluginManager manager = getPluginWrapper().getPluginManager(); PluginWrapper otherPlugin = manager.getPlugin("other-plugin-id"); if (otherPlugin != null) { PluginDescriptor otherMeta = otherPlugin.getPluginDescriptor(); getLogger().info("Other plugin version: {}", otherMeta.getVersion()); } ``` -------------------------------- ### Main Plugin Class Source: https://docs.siea.dev/jonion/creating-a-plugin/plugin-introduction The core class for your Jonion plugin, extending the base plugin class. It includes methods for starting and stopping the plugin, logging messages, and loading configuration. ```java package com.example.plugins; import com.example.api.MyPlugin; import dev.siea.jonion.configuration.PluginConfig; public class MyPlugin extends MyPlugin { @Override public void start() { getLogger().info("MyPlugin started!"); // Load configuration PluginConfig config = getDefaultConfig(); String message = config.getString("message", "Hello from MyPlugin!"); getLogger().info(message); } @Override public void stop() { getLogger().info("MyPlugin stopped!"); } } ``` -------------------------------- ### Using a Custom Descriptor Finder Source: https://docs.siea.dev/jonion/advanced/descriptors-and-descriptor-finders Initialize the `MyPluginManager` with your custom descriptor finder implementation to load plugins using your defined format. ```java MyPluginManager manager = new MyPluginManager( Paths.get("plugins"), new JsonDescriptorFinder() ); ``` -------------------------------- ### Maven Multi-Module Project Structure Source: https://docs.siea.dev/jonion/introduction/installation Illustrates a recommended multi-module Maven project layout for Jonion integration, featuring separate API and App modules. ```bash my-project/ ├── pom.xml # Parent POM ├── api/ │ ├── src │ └── pom.xml # API module with plugin interfaces └── app/ ├── src └── pom.xml # App module that depends on API ``` -------------------------------- ### Specifying a Custom Plugin Directory Source: https://docs.siea.dev/jonion/creating-a-plugin-system/setting-up-a-plugin-manager Demonstrates how to configure the `MyPluginManager` to load plugins from a directory other than the default 'plugins'. ```java // Use a custom directory MyPluginManager manager = new MyPluginManager(Paths.get("my-plugins")); ``` -------------------------------- ### Using Custom Plugin Manager in Main Class Source: https://docs.siea.dev/jonion/creating-a-plugin-system/setting-up-a-plugin-manager Shows how to instantiate and use the custom `MyPluginManager` in the application's main class. This integrates the custom plugin system into the application lifecycle. ```java package com.example.app; import java.nio.file.Paths; public class Main { public static void main(String[] args) { MyPluginManager pluginManager = new MyPluginManager(); pluginManager.start(); // Your application logic... pluginManager.stop(); } } ``` -------------------------------- ### Build Plugin JAR with Maven Source: https://docs.siea.dev/jonion/creating-a-plugin/plugin-introduction Command to clean and package your Jonion plugin project into a JAR file using Maven. The resulting JAR is typically placed in the application's plugin directory. ```bash mvn clean package ``` -------------------------------- ### Define Default Plugin Configuration Source: https://docs.siea.dev/jonion/creating-a-plugin/plugin-configurations Create a `config.yml` file in your plugin's resources directory to define default configuration values. This file will be automatically managed by Jonion. ```yaml message: "Welcome to MyPlugin!" number: 42 enabled: true ``` -------------------------------- ### Access and Use Plugin Configuration Source: https://docs.siea.dev/jonion/creating-a-plugin/plugin-configurations Retrieve the default configuration using `getDefaultConfig()` and access values with specified defaults. Remember to call `save()` after modifying configuration. ```java import dev.siea.jonion.configuration.PluginConfig; @Override public void start() { PluginConfig config = getDefaultConfig(); // Read values with defaults String message = config.getString("message", "Default message"); int number = config.getInt("number", 10); boolean enabled = config.getBoolean("enabled", true); // Save default config if it doesn't exist getDefaultConfig().save(); // Modify and save config.set("message", "Updated message"); config.save(); } ``` -------------------------------- ### Access Multiple Configuration Files Source: https://docs.siea.dev/jonion/creating-a-plugin/plugin-configurations Obtain `PluginConfig` instances for both the default configuration file (`config.yml`) and custom configuration files by specifying their names. ```java // Default config (config.yml) PluginConfig defaultConfig = getDefaultConfig(); // Custom config file PluginConfig customConfig = getConfig("custom-config.yml"); ``` -------------------------------- ### Read String Configuration Values Source: https://docs.siea.dev/jonion/creating-a-plugin/plugin-configurations Use `getString()` to read string values from the configuration. Provide a default value to ensure a fallback if the key is not found. ```java // Strings String value = config.getString("key"); String value = config.getString("key", "default"); ``` -------------------------------- ### Standard Log Levels in SLF4J Source: https://docs.siea.dev/jonion/other/logging Illustrates the usage of all standard SLF4J log levels, from trace to error, including logging exceptions. Use these levels appropriately to categorize log messages. ```java getLogger().trace("Very detailed information"); getLogger().debug("Debug information"); getLogger().info("Informational message"); getLogger().warn("Warning message"); getLogger().error("Error message"); getLogger().error("Error with exception", exception); ``` -------------------------------- ### Declare Required Dependencies Source: https://docs.siea.dev/jonion/creating-a-plugin/plugin-dependencies Specify dependencies that are mandatory for your plugin to load. If any of these are missing, your plugin will not be loaded. ```yaml dependencies: database-plugin: true api-plugin: true ``` -------------------------------- ### Creating a Custom Plugin Manager Source: https://docs.siea.dev/jonion/creating-a-plugin-system/setting-up-a-plugin-manager Implements a custom `PluginManager` by extending `AbstractPluginManager`. This allows for custom plugin lifecycle management and descriptor finding. ```java package com.example.app; import com.example.api.MyPlugin; import dev.siea.jonion.PluginWrapper; import dev.siea.jonion.descriptor.finder.YamlDescriptorFinder; import dev.siea.jonion.lifecycle.PluginState; import dev.siea.jonion.manager.AbstractPluginManager; import java.nio.file.Path; import java.nio.file.Paths; import java.util.concurrent.atomic.AtomicInteger; public class MyPluginManager extends AbstractPluginManager { public MyPluginManager() { this(Paths.get("plugins")); } public MyPluginManager(Path directory) { super(directory, new YamlDescriptorFinder()); } public void start() { AtomicInteger failedCount = new AtomicInteger(); getPlugins().forEach(pluginWrapper -> { try { if (pluginWrapper.getState().equals(PluginState.LOADED)) { ((MyPlugin) pluginWrapper.getPlugin()).start(); } } catch (Throwable e) { pluginWrapper.setState(PluginState.FAILED); logger.error("Failed to start plugin: {}", pluginWrapper.getPluginDescriptor().getPluginId(), e); failedCount.getAndIncrement(); } }); logger.info("Successfully started {} plugins. {} failed.", getPlugins().size() - failedCount.get(), failedCount.get()); } public void stop() { getPlugins().forEach(pluginWrapper -> { try { if (pluginWrapper.getState().equals(PluginState.LOADED)) { ((MyPlugin) pluginWrapper.getPlugin()).stop(); } } catch (Throwable e) { logger.error("Failed to stop plugin: {}", pluginWrapper.getPluginDescriptor().getPluginId(), e); } }); unloadPlugins(); } } ``` -------------------------------- ### Check for Failed Plugins Source: https://docs.siea.dev/jonion/other/error-handling Retrieve and log a list of plugins that failed to load using the PluginManager. ```java import dev.siea.jonion.lifecycle.PluginState; import dev.siea.jonion.manager.PluginManager; PluginManager manager = getPluginWrapper().getPluginManager(); List failedPlugins = manager.getPlugins(PluginState.FAILED); if (!failedPlugins.isEmpty()) { getLogger().warn("{} plugins failed to load", failedPlugins.size()); failedPlugins.forEach(plugin -> { getLogger().warn("Failed plugin: {}", plugin.getPluginDescriptor().getPluginId()); }); } ``` -------------------------------- ### Handle Plugin Loading Exceptions Source: https://docs.siea.dev/jonion/other/error-handling Catch specific exceptions like PluginLoadException, MissingDependencyException, and CircularDependencyException when manually loading plugins. ```java import dev.siea.jonion.exceptions.PluginLoadException; import dev.siea.jonion.exceptions.MissingDependencyException; import dev.siea.jonion.exceptions.CircularDependencyException; import dev.siea.jonion.PluginWrapper; try { pluginWrapper.load(); } catch (PluginLoadException e) { logger.error("Failed to load plugin: {}", pluginWrapper.getPluginDescriptor().getPluginId(), e); } catch (MissingDependencyException e) { logger.error("Missing required dependency: {}", e.getMessage()); } catch (CircularDependencyException e) { logger.error("Circular dependency detected: {}", e.getMessage()); } ``` -------------------------------- ### Declare Optional Dependencies Source: https://docs.siea.dev/jonion/creating-a-plugin/plugin-dependencies Specify dependencies that are beneficial but not critical. Your plugin will load even if these optional dependencies are not present. ```yaml dependencies: optional-feature: false ``` -------------------------------- ### Plugin Descriptor (plugin.yml) Source: https://docs.siea.dev/jonion/creating-a-plugin/plugin-introduction Defines metadata for your Jonion plugin, including its name, version, description, main class, and authors. This file is required for Jonion to recognize and load your plugin. ```yaml name: my-plugin version: 1.0.0 description: My first Jonion plugin main: com.example.plugins.MyPlugin authors: - YourName ``` -------------------------------- ### Handle Configuration Errors Source: https://docs.siea.dev/jonion/other/error-handling Catch ConfigSaveException and ConfigException when saving or encountering issues with plugin configurations. ```java import dev.siea.jonion.exceptions.ConfigException; import dev.siea.jonion.exceptions.ConfigSaveException; import dev.siea.jonion.configuration.PluginConfig; try { PluginConfig config = getDefaultConfig(); config.set("key", "value"); config.save(); } catch (ConfigSaveException e) { getLogger().error("Failed to save configuration", e); } catch (ConfigException e) { getLogger().error("Configuration error", e); } ``` -------------------------------- ### Add Jonion Dependency to API Module (Maven) Source: https://docs.siea.dev/jonion/introduction/installation Shows how to add the Jonion library as a dependency in your API module's pom.xml. Ensure you replace `${jonionversion}` with the latest version. ```xml dev.siea.jonion Jonion ${jonionversion} ``` -------------------------------- ### Access Plugin Metadata Source: https://docs.siea.dev/jonion/creating-a-plugin/plugin-meta-data Retrieve core metadata fields like ID, version, description, authors, license, and main class from your plugin's PluginDescriptor. ```java import dev.siea.jonion.descriptor.PluginDescriptor; PluginDescriptor meta = getMetaData(); String id = meta.getPluginId(); String version = meta.getVersion(); String description = meta.getDescription(); List authors = meta.getAuthors(); String license = meta.getLicense(); String pluginClass = meta.getPluginClass(); ``` -------------------------------- ### Write Configuration Values Source: https://docs.siea.dev/jonion/creating-a-plugin/plugin-configurations Modify configuration values using the `set()` method and ensure changes are persisted by calling `save()`. ```java // Writing config.set("key", value); config.save(); ``` -------------------------------- ### Save Modified Configuration Source: https://docs.siea.dev/jonion/creating-a-plugin/plugin-configurations It is crucial to call the `save()` method after making any modifications to configuration values to ensure they are written to the file. ```java config.set("message", "New message"); config.set("number", 100); config.save(); // Don't forget to save! ``` -------------------------------- ### Read Numeric Configuration Values Source: https://docs.siea.dev/jonion/creating-a-plugin/plugin-configurations Access integer, long, double, float, short, and byte values from the configuration. Default values can be provided for each numeric type. ```java // Numbers int value = config.getInt("key"); int value = config.getInt("key", 0); long value = config.getLong("key", 0L); double value = config.getDouble("key", 0.0); float value = config.getFloat("key", 0.0f); short value = config.getShort("key", (short) 0); byte value = config.getByte("key", (byte) 0); ``` -------------------------------- ### Check Plugin State Source: https://docs.siea.dev/jonion/advanced/plugin-states Retrieve a plugin by its name and check its current lifecycle state using a switch statement. This is useful for conditional logic based on whether a plugin is loaded, failed, created, or unloaded. ```java import dev.siea.jonion.PluginWrapper; import dev.siea.jonion.lifecycle.PluginState; import dev.siea.jonion.manager.PluginManager; PluginManager manager = getPluginWrapper().getPluginManager(); PluginWrapper wrapper = manager.getPlugin("my-plugin"); if (wrapper != null) { PluginState state = wrapper.getState(); switch (state) { case LOADED: getLogger().info("Plugin is loaded and ready"); break; case FAILED: getLogger().warn("Plugin failed to load"); break; case CREATED: getLogger().info("Plugin wrapper created but not loaded"); break; case UNLOADED: getLogger().info("Plugin has been unloaded"); break; } } ``` -------------------------------- ### Customizing YAML Descriptor File Name Source: https://docs.siea.dev/jonion/advanced/descriptors-and-descriptor-finders Use this snippet to specify a custom file name for YAML descriptor files when initializing the plugin manager. ```java import dev.siea.jonion.descriptor.finder.YamlDescriptorFinder; import java.nio.file.Paths; MyPluginManager manager = new MyPluginManager( Paths.get("plugins"), new YamlDescriptorFinder("my-plugin.yml") ); ``` -------------------------------- ### Read Boolean Configuration Values Source: https://docs.siea.dev/jonion/creating-a-plugin/plugin-configurations Retrieve boolean values from the configuration using `getBoolean()`. A default value can be specified. ```java // Booleans boolean value = config.getBoolean("key"); boolean value = config.getBoolean("key", false); ``` -------------------------------- ### Declare Plugin Dependencies in plugin.yml Source: https://docs.siea.dev/jonion/creating-a-plugin/plugin-dependencies Declare required and optional plugin dependencies in your plugin.yml file. Set to 'true' for required dependencies and 'false' for optional ones. ```yaml name: my-plugin version: 1.0.0 main: com.example.plugins.MyPlugin dependencies: required-plugin: true # Required - plugin won't load without this optional-plugin: false # Optional - plugin will load even if missing ``` -------------------------------- ### Manually Set Plugin State Source: https://docs.siea.dev/jonion/advanced/plugin-states Allows for manual adjustment of a plugin's state. Use with caution, as incorrect manual state changes can disrupt the plugin manager's internal consistency. ```java PluginWrapper wrapper = manager.getPlugin("my-plugin"); wrapper.setState(PluginState.FAILED); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.