forked from jnode/jnode
- Notifications
You must be signed in to change notification settings - Fork 0
Plugin System
opencode-agent[bot] edited this page May 10, 2026
·
2 revisions
JNode uses an OSGi-like plugin/extension architecture where each functional unit is a plugin with an XML descriptor defining its dependencies, exports, and extension points.
The plugin system is JNode's primary modularity mechanism. Every subsystem — filesystem drivers, network protocols, video drivers, shell commands — is packaged as a plugin. Plugins have:
- Identity — unique ID, version, provider
- Dependencies —
<requires>/<import>declarations - Exports — packages visible to other plugins
- Extensions — implementations registered at named extension points
- Lifecycle — loaded, started, stopped by the PluginManager
| Class / File | Role |
|---|---|
core/src/core/org/jnode/plugin/Plugin.java | Base class for all plugins |
core/src/core/org/jnode/plugin/PluginDescriptor.java | Describes a plugin (parsed from XML) |
core/src/core/org/jnode/plugin/PluginManager.java | Manages plugin lifecycle |
core/src/core/org/jnode/plugin/PluginRegistry.java | Registry of all known plugins |
core/src/core/org/jnode/plugin/Extension.java | A plugin's contribution to an extension point |
core/src/core/org/jnode/plugin/ExtensionPoint.java | A named hook where extensions register |
core/src/core/org/jnode/plugin/ConfigurationElement.java | XML config data within an extension |
core/src/core/org/jnode/plugin/PluginClassLoader.java | Per-plugin classloader |
core/src/core/org/jnode/plugin/manager/DefaultPluginManager.java | Default lifecycle implementation |
core/src/core/org/jnode/plugin/model/PluginDescriptorModel.java | XML descriptor parser |
core/src/core/org/jnode/plugin/model/PluginsClassLoader.java | Parent classloader for all plugin classloaders |
Each plugin has an XML file in <subproject>/descriptors/:
<pluginid="org.jnode.driver.video.vga"name="JNode Video Standard VGA driver"version="@VERSION@"license-name="lgpl"provider-name="JNode.org">
<!-- Dependencies on other plugins -->
<requires>
<importplugin="org.jnode.awt"/>
<importplugin="org.jnode.driver.bus.pci"/>
<importplugin="org.jnode.driver.video.vgahw"/>
</requires>
<!-- Packages this plugin makes visible to dependents -->
<runtime>
<libraryname="jnode-gui.jar">
<exportname="org.jnode.driver.video.vga.*"/>
</library>
</runtime>
<!-- Extensions contributed to other plugins' extension points -->
<extensionpoint="org.jnode.driver.bus.pci.device-factories">
<device-factoryclass="org.jnode.driver.video.vga.VGADriver"/>
</extension>
</plugin>| Element | Purpose |
|---|---|
<plugin> | Root: id, name, version, provider |
<requires> / <import> | Declares dependencies |
<runtime> / <library> | JAR files this plugin provides |
<export> | Packages visible to importing plugins |
<extension-point> | Defines a hook for other plugins to extend |
<extension> | Contributes to another plugin's extension point |
<fragment> | Fragment that attaches to a host plugin |
InitJarProcessorextracts plugin JARs and descriptors from the init-jarPluginDescriptorModelparses each XML descriptorPluginRegistrystores all descriptorsDefaultPluginManager.startSystemPlugins()sorts by dependency order and activates each plugin
BootClassLoader (VM built-in classes)
└── PluginsClassLoader (shared parent for all plugins)
├── PluginClassLoader [org.jnode.driver]
├── PluginClassLoader [org.jnode.fs]
├── PluginClassLoader [org.jnode.driver.video.vga]
└── ...
Each PluginClassLoader:
- Can see classes from its own JAR
- Can see classes from plugins listed in
<requires>/<import> - Cannot see classes from other plugins (isolation)
Extension points are the primary mechanism for loose coupling:
- Plugin A declares
<extension-point id="org.jnode.driver.bus.pci.device-factories"> - Plugin B contributes
<extension point="org.jnode.driver.bus.pci.device-factories"> - At runtime, Plugin A queries its extension point to discover all contributors
ExtensionPoint.getExtensions()returns allExtensionobjects- Each
ExtensionhasConfigurationElements with class names and parameters
This is how drivers register themselves: the PCI bus plugin defines an extension point for device factories, and each driver plugin contributes a factory.
| File | Purpose |
|---|---|
all/conf/default-plugin-list.xml | Plugins included in a standard build |
all/conf/full-plugin-list.xml | All available plugins |
The plugin list also declares the main class to launch:
<manifest>
<attributekey="Main-Class"value="org.jnode.shell.CommandShell"/>
</manifest>- Build-time pre-loading —
BootImageBuilderpre-loads plugin descriptors and bakes thePluginRegistryinto the boot image. The registry field inMain.javais set at build time. - No dynamic loading at runtime — Unlike Eclipse OSGi, JNode's plugin system is primarily static. All plugins are loaded at boot from the init-jar.
- Fragment vs. Plugin — A
FragmentDescriptorattaches to a host plugin and shares its classloader. Used for classpath extensions. - Version string —
@VERSION@in descriptors is replaced at build time by Ant. - AutoUnzipPlugin — A special plugin type that auto-extracts ZIP content (used for classpath resources).
- Circular dependencies — Not supported. The build will fail if plugins have circular imports.
- Architecture — Where plugins fit in the system layers
- Boot-Sequence — How plugins are loaded during boot
- Build-System — How plugin descriptors are processed
- Driver-Framework — Drivers are plugins with extension points
- Network Device Plugin — Example plugin for network device drivers