# How to Use JMX Support for Runtime Configuration Management in Owner

> Master JMX support in Owner for runtime configuration management. Effortlessly read and update properties via JConsole without application restarts.

- Repository: [Matteo Baccan/owner](https://github.com/matteobaccan/owner)
- Tags: how-to-guide
- Published: 2026-03-07

---

**Owner enables runtime configuration management via JMX by exposing configuration interfaces as DynamicMBeans, allowing you to read and modify properties through standard JMX consoles like JConsole without application restarts.**

The Owner library (matteobaccan/owner) provides built-in JMX support for runtime configuration management. When the JDK supplies `javax.management.DynamicMBean`, Owner automatically wraps configuration objects with a JMX delegate, making every property accessible as a manageable attribute and every operation invocable through standard JMX tooling.

## Enabling JMX Support in Your Configuration Interface

To expose a configuration object via JMX, your interface must extend the appropriate Owner mix-ins. The `Accessible` interface marks the config as visible to JMX, while `Mutable` and `Reloadable` enable runtime modification and hot-reloading capabilities.

```java
import org.aeonbits.owner.Config;
import org.aeonbits.owner.Mutable;
import org.aeonbits.owner.Accessible;
import org.aeonbits.owner.Reloadable;

public interface ServerConfig extends Mutable, Accessible, Reloadable {
    @Key("server.port")
    @DefaultValue("8080")
    int port();

    @Key("server.host")
    @DefaultValue("localhost")
    String host();
}

```

## Registering the Configuration MBean

After creating the configuration instance with `ConfigFactory.create()`, register it on the platform `MBeanServer`. The generated proxy already implements `DynamicMBean` via the internal `JMXSupport` delegate, so no additional wrapper is required.

```java
import org.aeonbits.owner.ConfigFactory;
import javax.management.*;
import java.lang.management.ManagementFactory;

public class JmxRegistration {
    public static void main(String[] args) throws Exception {
        ServerConfig cfg = ConfigFactory.create(ServerConfig.class);
        
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
        ObjectName name = new ObjectName(
            "org.aeonbits.owner:type=configuration,name=ServerConfig");
        
        mbs.registerMBean(cfg, name);
        System.out.println("MBean registered. Connect with JConsole to manage.");
        
        // Keep alive for demonstration
        Thread.sleep(Long.MAX_VALUE);
    }
}

```

## Runtime Management with JConsole

Once registered, the configuration appears under the `org.aeonbits.owner` domain in any JMX client. Connect with **JConsole**, **VisualVM**, or **Java Mission Control** to perform the following actions:

- **Read attributes**: View current values of `port` and `host` via `getAttribute`
- **Modify values**: Use `setAttribute` to change `port` to `9090`; the change reflects immediately in the live `cfg` instance
- **Invoke operations**: Call `reload()` to refresh from underlying sources, or `setProperty("key", "value")` for dynamic updates

All modifications trigger `PropertyChangeEvent` notifications to any listeners registered on the configuration object.

## Complete Implementation Example

The official test suite provides a concise demonstration in [`JMXExample.java`](https://github.com/matteobaccan/owner/blob/main/JMXExample.java) ([source](https://github.com/matteobaccan/owner/blob/master/owner/src/test/java/org/aeonbits/owner/examples/JMXExample.java)). Below is a trimmed version you can run directly:

```java
import org.aeonbits.owner.*;
import javax.management.*;
import java.lang.management.ManagementFactory;

public class JmxDemo {
    public interface DemoConfig extends Mutable, Accessible, Reloadable {
        @Key("app.timeout")
        @DefaultValue("30")
        int timeout();

        @Key("app.name")
        @DefaultValue("Demo")
        String name();
    }

    public static void main(String[] args) throws Exception {
        DemoConfig cfg = ConfigFactory.create(DemoConfig.class);
        
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
        ObjectName on = new ObjectName(
            "org.aeonbits.owner:type=configuration,name=DemoConfig");
        mbs.registerMBean(cfg, on);

        System.out.println("JMX MBean registered – attach JConsole now.");
        while (true) {
            Thread.sleep(1000);
        }
    }
}

```

## How JMX Support Works Under the Hood

The JMX integration relies on two core components in the Owner codebase:

**`JMXSupport` Delegate**  
Located in [`owner/src/main/java/org/aeonbits/owner/JMXSupport.java`](https://github.com/matteobaccan/owner/blob/main/owner/src/main/java/org/aeonbits/owner/JMXSupport.java) (lines 31‑86), this class implements `DynamicMBean`. It forwards standard JMX operations to the underlying `PropertiesManager`:
- `getAttribute` retrieves values from the property store
- `setAttribute` delegates to `PropertiesManager.setProperty()`, firing `PropertyChangeEvent`s
- `invoke` handles operations like `reload()` by calling `PropertiesManager.reload()`
- `getMBeanInfo` exposes metadata based on the interface methods and annotations

**`DefaultFactory` Integration**  
In [`owner/src/main/java/org/aeonbits/owner/DefaultFactory.java`](https://github.com/matteobaccan/owner/blob/main/owner/src/main/java/org/aeonbits/owner/DefaultFactory.java), the factory checks for the presence of `javax.management.DynamicMBean` on the classpath. When available, it automatically attaches a `JMXSupport` instance to every generated configuration proxy, ensuring the object is ready for MBean registration without additional user code.

## Key Source Files and References

| File | Role | Link |
|------|------|------|
| [`owner/src/main/java/org/aeonbits/owner/JMXSupport.java`](https://github.com/matteobaccan/owner/blob/main/owner/src/main/java/org/aeonbits/owner/JMXSupport.java) | Implements the JMX delegate (`DynamicMBean` operations) | [JMXSupport.java](https://github.com/matteobaccan/owner/blob/master/owner/src/main/java/org/aeonbits/owner/JMXSupport.java) |
| [`owner/src/main/java/org/aeonbits/owner/DefaultFactory.java`](https://github.com/matteobaccan/owner/blob/main/owner/src/main/java/org/aeonbits/owner/DefaultFactory.java) | Detects JMX availability and attaches `JMXSupport` to configs | [DefaultFactory.java](https://github.com/matteobaccan/owner/blob/master/owner/src/main/java/org/aeonbits/owner/DefaultFactory.java) |
| [`owner/src/test/java/org/aeonbits/owner/examples/JMXExample.java`](https://github.com/matteobaccan/owner/blob/main/owner/src/test/java/org/aeonbits/owner/examples/JMXExample.java) | Minimal runnable demo | [JMXExample.java](https://github.com/matteobaccan/owner/blob/master/owner/src/test/java/org/aeonbits/owner/examples/JMXExample.java) |
| [`owner/src/test/java/org/aeonbits/owner/jmx/JMXMBeanTest.java`](https://github.com/matteobaccan/owner/blob/main/owner/src/test/java/org/aeonbits/owner/jmx/JMXMBeanTest.java) | Unit tests verifying attribute access and reload via JMX | [JMXMBeanTest.java](https://github.com/matteobaccan/owner/blob/master/owner/src/test/java/org/aeonbits/owner/jmx/JMXMBeanTest.java) |

## Summary

Owner’s JMX support for runtime configuration management provides zero‑boilerplate exposure of configuration objects as standard MBeans:

- **Automatic MBean readiness**: When `javax.management.DynamicMBean` is available, `DefaultFactory` automatically attaches a `JMXSupport` delegate to every config instance.
- **Runtime visibility**: Extending `Accessible`, `Mutable`, and `Reloadable` exposes attributes and operations to JConsole and other JMX clients.
- **Live updates**: Changes made via `setAttribute` or `invoke("setProperty")` immediately affect the running application and fire `PropertyChangeEvent`s.
- **Hot reloading**: The `reload` operation re‑reads underlying configuration sources without restarting the JVM.

## Frequently Asked Questions

### What interfaces must a configuration extend to support JMX management?

Your configuration interface must extend `org.aeonbits.owner.Accessible` to expose the config as a JMX MBean. To enable runtime modification, also extend `Mutable`. For hot-reloading capabilities via JMX, extend `Reloadable`. Most use cases implement all three: `public interface MyConfig extends Mutable, Accessible, Reloadable`.

### How does Owner automatically expose a configuration as a DynamicMBean?

When `ConfigFactory.create()` generates a proxy instance, `DefaultFactory` checks for the presence of `javax.management.DynamicMBean` on the classpath. If available, it instantiates `JMXSupport` (from [`owner/src/main/java/org/aeonbits/owner/JMXSupport.java`](https://github.com/matteobaccan/owner/blob/main/owner/src/main/java/org/aeonbits/owner/JMXSupport.java)) and attaches it as a delegate to the proxy. This delegate implements `getAttribute`, `setAttribute`, `invoke`, and `getMBeanInfo`, forwarding calls to the underlying `PropertiesManager`.

### Can I modify configuration values through JConsole, and will the application see the changes immediately?

Yes. When you use `setAttribute` in JConsole or invoke `setProperty` via the JMX operations, the call routes through `JMXSupport` to `PropertiesManager.setProperty()`. This updates the internal property store immediately, so subsequent calls to configuration methods (like `cfg.port()`) return the new value. The change also fires a `PropertyChangeEvent` to any registered listeners on the config object.

### Is it possible to reload configuration from source files via JMX without restarting the application?

Yes. The `Reloadable` interface exposes a `reload()` operation that is automatically mapped as a JMX operation through `JMXSupport.invoke()`. When invoked via JConsole or programmatically through the `MBeanServer`, it calls `PropertiesManager.reload()`, which re-reads the underlying configuration sources (files, URLs, system properties, etc.) and updates the configuration object in place.