How to Use JMX Support for Runtime Configuration Management in Owner

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.

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.

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 (source). Below is a trimmed version you can run directly:

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 (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 PropertyChangeEvents
  • 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, 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 Implements the JMX delegate (DynamicMBean operations) JMXSupport.java
owner/src/main/java/org/aeonbits/owner/DefaultFactory.java Detects JMX availability and attaches JMXSupport to configs DefaultFactory.java
owner/src/test/java/org/aeonbits/owner/examples/JMXExample.java Minimal runnable demo JMXExample.java
owner/src/test/java/org/aeonbits/owner/jmx/JMXMBeanTest.java Unit tests verifying attribute access and reload via 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 PropertyChangeEvents.
  • 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) 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →