ADR: Plugin Security Architecture and ClassLoader Isolation¶
Status¶
Implemented
Context¶
OmegaT’s plugin system requires a balance between security, stability, and functional requirements. Historically, Java applications have two main approaches to plugin loading:
Single Application ClassLoader: All plugins share the same namespace, allowing them to interfere with each other and causing dependency conflicts.
Per-Plugin ClassLoader Isolation: The industry standard (used by OSGi, Eclipse, IntelliJ, NetBeans), where each plugin has its own ClassLoader.
While per-plugin isolation is ideal for security (fault containment, dependency safety, and resource management), OmegaT faces specific constraints that make it impractical for all plugin types:
Language Module Resource Sharing: Language modules must share resources like dictionaries with the core library and other plugins.
Swing UIManager Registration: Theme plugins must register Look-and-Feel (LaF) classes with the global
UIManager, which requires global visibility that isolated ClassLoaders do not provide.
Decision¶
We have decided to implement a Type-Based ClassLoader Isolation strategy using an EnumMap to manage ClassLoaders.
Key Architectural Changes¶
EnumMap-Based Management: Use
EnumMap<PluginType, MainClassLoader> MAINCLASSLOADERSto assign one ClassLoader per plugin type.Grouped Isolation:
Theme plugins share one ClassLoader.
Language plugins share one ClassLoader.
Filter plugins share one ClassLoader.
Other plugin types follow this pattern.
Implementation Details¶
The implementation maps each PluginType to a specific MainClassLoader. This ensures that plugins of the same type can share necessary resources and interact with global APIs where required by their functional role.
EnumMap<PluginType, MainClassLoader> MAINCLASSLOADERS;
Memory Impact¶
Per-Type ClassLoaders: ~200KB overhead regardless of the number of plugins.
Comparison: Individual ClassLoaders would consume ~1MB for 20 plugins, while a single shared ClassLoader (deprecated) would consume ~50KB.
Consequences¶
Benefits¶
Functional Compatibility: Respects the need for resource sharing in language modules and LaF registration in themes.
Reasonable Isolation: Provides better security and stability than a single ClassLoader by separating different plugin types.
Maintainability: Provides a clean and flexible mapping between plugin types and their loading logic.
Future Flexibility: Provides a path toward stronger isolation (per-plugin) for plugin types that do not have shared resource constraints.
Trade-Offs and Risks¶
Intra-Type Interference: Plugins of the same type (e.g., two different themes) can still access each other’s classes and interfere.
Dependency Conflicts: Using different versions of the same library within plugins of the same type remains a risk.
Fault Propagation: A bug or memory leak in one plugin can still affect other plugins of the same type.
Mitigation Strategies¶
To address the remaining risks, we recommend:
Validating plugin manifests and signatures.
Manual plugin reviews for official extensions.
Future investigation into sandboxing or more granular isolation where possible.
Testing and Verification¶
The architecture was verified by:
Ensuring language modules can correctly share dictionaries.
Ensuring theme plugins can register and apply Look-and-Feel classes via
UIManager.Monitoring memory usage to ensure ClassLoader overhead remains within acceptable limits.
References¶
Developer manual: Plugin Security Architecture in OmegaT
Java
URLClassLoaderDocumentationSwing
UIManagerAPI Documentation
Date: 2025-07-01 Author: Hiroshi Miura Reviewers: OmegaT Development Team