Skip to content
Open
123 changes: 123 additions & 0 deletions microkernel-architecture/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
---
title: "Microkernel architecture Pattern in Java: Extending applications through plugins"
shortTitle: Microkernel architecture
description: "The Microkernel Architecture design pattern, also known as the plug-in architecture, is ideal for product-based applications that need to extend their core functionalities through plug-ins."
category: Data access
language: en
tag:
- Data access
- Data processing
- Persistence
---

## Also known as

* Plug-in architecture

## Intent of Microkernel architecture Design Pattern

Separate an application's minimal core from optional features so functionality can be added, replaced, or removed through plugins without changing the core. This provides extensibility while keeping specialized processing isolated from general application logic.

## Detailed Explanation of Microkernel architecture Pattern with Real-World Examples

Real-world example

> An IDE can provide a basic editor as its core while installing language tools, debuggers, and integrations as plugins. Likewise, a document-processing application can route documents to format-specific converters. In an insurance claims system, plugins can encapsulate state-specific rules without complicating the core claims workflow.

In plain words

> The microkernel provides the essential services and lets independent plugins supply optional capabilities through a small shared interface. The core manages plugin registration, lifecycle, and communication, while each plugin owns its specialized behavior.

Architecture

![Microkernel architecture process flow](etc/microkernel-flow.png)

The plugin class structure is documented separately in [microkernel-architecture.png](etc/microkernel-architecture.png).
## Programmatic Example of Microkernel architecture Pattern in Java

This example is an interactive text editor. The `MicroKernel` owns the document buffer and plugin lifecycle. The `PluginCatalog` supplies plugin factories, and the `PluginRegistry` keeps track of installed plugins. To transform the document, the kernel packages the document text in a `Message` and sends it through the `IpcRouter`; the selected plugin returns the transformed text.

Every plugin follows a common contract:

```java
public interface Plugin {
String getName();
String getDescription();
void initialize(IpcRouter ipcRouter);
void onStart();
void onStop();
boolean isStarted();
String handleMessage(Message message);
}
```

The kernel routes a transformation request without depending on the implementation of the plugin:

```java
public String transformDocumentWithPlugin(String pluginName) {
Message message =
new Message("Kernel", pluginName, "TRANSFORM", documentBuffer.toString());
String transformedText = ipcRouter.sendMessage(message);

clearDocument();
documentBuffer.append(transformedText);
return "Success: Document transformed by " + pluginName;
}
```

Plugins such as `UppercasePlugin` and `RemoveSpacesPlugin` implement the contract and handle the `TRANSFORM` action independently. The catalog creates fresh plugin instances from registered factories, while the kernel initializes, starts, and unloads installed plugins.

Start the application and select **Open Text Editor**. Type a few lines, then use `:view`, `:clear`, or `:apply <plugin_name>` to interact with the document. The available plugin list is shown in the install menu.

The example registers plugin factories directly in `PluginCatalog`; a production system could instead discover plugins from configuration, Java's service loader, or a plugin container.

## When to Use the Microkernel architecture Pattern in Java

* Use when building a product with optional capabilities that vary by customer, deployment, or installation.
* Use when extensions should be developed, tested, and released independently behind a well-defined interface.
* Use when volatile custom rules or specialized processing should be isolated from general business logic.
* Avoid it when there are few optional features or when plugins need deep access to core internals; the plugin API and lifecycle add ongoing maintenance costs.

## Architecture Characteristics

* **Agility: High.** Changes can often be isolated to loosely coupled plugin modules.
* **Ease of deployment: High.** Plugins can be installed or updated separately; runtime dynamic loading depends on the implementation.
* **Testability: High.** Plugins can be tested independently, and the core can be tested against plugin contracts.
* **Performance: High.** The application can include only the features needed for a product variant, although routing and plugin boundaries still have costs.
* **Scalability: Low to moderate.** A microkernel is commonly deployed as a single application, so large-scale distribution is not its main strength.
* **Ease of development: Low to moderate.** Plugin contracts, compatibility, lifecycle, and failure handling require deliberate design.

## Real-World Applications of Microkernel architecture Pattern in Java

* IDEs such as Eclipse, which extend core editing capabilities with plugins.
* Internet browsers that add capabilities through extensions.
* Insurance claims processing systems that isolate state-specific rules from general processing.
* Operating systems and product platforms that provide optional or customer-specific modules.
* Data-processing applications that load format-specific readers, writers, or transformations.

## Benefits and Trade-offs of Microkernel architecture Pattern

Benefits:

* Keeps the core small and focused on essential responsibilities.
* Makes optional features replaceable and independently testable.
* Supports product variants without duplicating the core application.

Trade-offs:

* Plugin contracts need compatibility and versioning as the system evolves.
* Plugin discovery, loading, failure handling, and security require deliberate design in production systems.
* Indirection through a registry and message router can make execution flow less obvious than direct calls.
* A single-core deployment may limit horizontal scalability.

## Related Java Design Patterns

* [Strategy](https://java-design-patterns.com/patterns/strategy/): Plugins can provide interchangeable strategies for a core operation.
* [Factory Kit](https://java-design-patterns.com/patterns/factory-kit/): Can help create plugin implementations from configuration.
* [Dependency Injection](https://java-design-patterns.com/patterns/dependency-injection/): Can be used to assemble the core and its plugins.

## References and Credits

* Richards, Mark. *Software Architecture Patterns*. O'Reilly Media, Inc., 2015.
* [Pattern-Oriented Software Architecture, Volume 1](https://www.wiley.com/en-us/Pattern+Oriented+Software+Architecture%2C+Volume+1%3A+A+System+of+Patterns-p-9780471958697)
* [Microkernel architecture style (Microsoft Azure Architecture Center)](https://learn.microsoft.com/en-us/azure/architecture/guide/architecture-styles/microkernel)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
101 changes: 101 additions & 0 deletions microkernel-architecture/etc/microkernel-architecture.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
@startuml
title Microkernel Architecture - Class Structure

top to bottom direction
skinparam classAttributeIconSize 0
skinparam linetype ortho
skinparam nodesep 35
skinparam ranksep 45

package "Application" {
class App {
+main(args: String[]): void
}

class CommandLineInterface {
-kernel: MicroKernel
-catalog: PluginCatalog
+run(): void
}

class PluginCatalog {
-catalog: Map~String, Supplier~Plugin~~
+getAvailablePlugins(): List~String~
+createPlugin(description: String): Plugin
}
}

package "Kernel" {
class MicroKernel {
-registry: PluginRegistry
-ipcRouter: IpcRouter
-documentBuffer: StringBuilder
+loadPlugin(plugin: Plugin): void
+startPlugin(name: String): void
+unloadPlugin(name: String): void
+transformDocumentWithPlugin(name: String): String
}

class PluginRegistry {
-plugins: Map~String, Plugin~
+register(plugin: Plugin): void
+deregister(name: String): void
+getPlugin(name: String): Plugin
}

class IpcRouter {
-registry: PluginRegistry
+sendMessage(message: Message): String
}
}

package "Plugin API" {
interface Plugin {
+getName(): String
+initialize(router: IpcRouter): void
+onStart(): void
+onStop(): void
+handleMessage(message: Message): String
}

abstract class AbstractOnDemandPlugin
abstract class AbstractLifecyclePlugin
}

package "Built-in Plugins" {
class UppercasePlugin
class RemoveSpacesPlugin
class JavaLanguagePlugin
class NeonThemePlugin
}

class Message <<record>> {
sender: String
recipient: String
action: String
payload: String
}

App --> CommandLineInterface
CommandLineInterface --> MicroKernel
CommandLineInterface --> PluginCatalog
PluginCatalog ..> Plugin : creates

MicroKernel --> PluginRegistry : registers / removes by name
MicroKernel --> IpcRouter : sends messages
IpcRouter --> PluginRegistry : looks up recipient
PluginRegistry "1" --> "0..*" Plugin : maps names to instances
IpcRouter ..> Plugin : dispatches resolved instance

AbstractOnDemandPlugin ..|> Plugin
AbstractLifecyclePlugin ..|> Plugin
UppercasePlugin --|> AbstractOnDemandPlugin
RemoveSpacesPlugin --|> AbstractOnDemandPlugin
JavaLanguagePlugin --|> AbstractOnDemandPlugin
NeonThemePlugin --|> AbstractLifecyclePlugin

MicroKernel ..> Message : creates
IpcRouter ..> Message : routes
Plugin ..> Message : handles

@enduml
Binary file added microkernel-architecture/etc/microkernel-flow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
57 changes: 57 additions & 0 deletions microkernel-architecture/etc/microkernel-flow.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
@startuml
' Force straight 90-degree lines
skinparam linetype ortho

' Drastically increase separation to prevent text overlapping
skinparam nodesep 160
skinparam ranksep 160
skinparam padding 12

' Mimic the standard Java Design Patterns (URM) color scheme
skinparam rectangle {
BackgroundColor #FEFECE
BorderColor #A80036
BorderThickness 1.5
FontColor #000000
RoundCorner 8
}

skinparam arrow {
Color #A80036
Thickness 1.5
FontColor #444444
FontSize 12
}

rectangle "Plugin catalog" as Catalog
rectangle "Command-line interface" as CLI
rectangle "Microkernel" as Kernel
rectangle "Plugin registry" as Registry
rectangle "IPC router" as Router
rectangle "Installed plugin instance" as Plugin

' --- LEVEL 1 & 2: User Interface to Core ---
Catalog -right-> CLI : new plugin\ninstance
CLI -left-> Catalog : list or\ncreate

' NEW: Show the Catalog as the factory for Plugins
Catalog -down-> Plugin : instantiates\n(factory)

CLI -down-> Kernel : request document transform\ninstall, start, or remove
Kernel -up-> CLI : updated document\n& status

' --- LEVEL 2 & 3: Core to Internal Services ---
Kernel -down-> Registry : register or deregister\nby name
Kernel -down-> Router : message with\nrecipient name
Router -up-> Kernel : result or\ndelivery error

' --- LEVEL 3: Internal Service Communication ---
Router -left-> Registry : look up\nrecipient
Registry -right-> Router : matching plugin\nreference

' --- LEVEL 3 & 4: Services to Plugin ---
Registry -down-> Plugin : stores and\nresolves by name
Router -down-> Plugin : dispatch if\nstarted
Plugin -up-> Router : transformation\nresult

@enduml
104 changes: 104 additions & 0 deletions microkernel-architecture/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).

The MIT License
Copyright © 2014-2022 Ilkka Seppälä

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<artifactId>microkernel-architecture</artifactId>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<configuration>
<archive>
<manifest>
<mainClass>com.iluwatar.microkernel.App</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
<groupId>org.apache.maven.plugins</groupId>
</plugin>
<plugin>
<groupId>com.diffplug.spotless</groupId>
<artifactId>spotless-maven-plugin</artifactId>
<version>3.8.0</version> <!-- Use latest version -->
<executions>
<execution>
<goals>
<goal>check</goal> <!-- Run to check formatting -->
<goal>apply</goal> <!-- Run to format automatically -->
</goals>
</execution>
</executions>
<configuration>
<java>
<googleJavaFormat>
<version>1.28.0</version>
</googleJavaFormat>
</java>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>21</source>
<target>21</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<artifactId>junit-jupiter-engine</artifactId>
<groupId>org.junit.jupiter</groupId>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</dependency>
<dependency>
<artifactId>logback-classic</artifactId>
<groupId>ch.qos.logback</groupId>
</dependency>
</dependencies>

<modelVersion>4.0.0</modelVersion>

<parent>
<artifactId>java-design-patterns</artifactId>
<groupId>com.iluwatar</groupId>
<version>1.26.0-SNAPSHOT</version>
</parent>

</project>
Loading
Loading