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/:
<plugin id="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>
<import plugin="org.jnode.awt"/>
<import plugin="org.jnode.driver.bus.pci"/>
<import plugin="org.jnode.driver.video.vgahw"/>
</requires>
<!-- Packages this plugin makes visible to dependents -->
<runtime>
<library name="jnode-gui.jar">
<export name="org.jnode.driver.video.vga.*"/>
</library>
</runtime>
<!-- Extensions contributed to other plugins' extension points -->
<extension point="org.jnode.driver.bus.pci.device-factories">
<device-factory class="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-jar -
PluginDescriptorModelparses each XML descriptor -
PluginRegistrystores all descriptors -
DefaultPluginManager.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>
<attribute key="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