SonarSource/sonarqube · error · IllegalStateException

Can not register MBean [

Error message

Can not register MBean [

What it means

Jmx.register wraps any JMX registration failure (malformed ObjectName, non-compliant MBean, already-registered name, registration rejected) into an IllegalStateException. The MBean could not be registered with the platform MBean server.

Solutions

  1. Check the ObjectName string follows 'domain:key=value' syntax
  2. Check the name is not already registered (or unregister it first)
  3. Ensure the instance implements a public interface whose name ends in MBean
  4. Inspect the wrapped cause exception for the exact JMX failure

Example fix

// before
Jmx.register("SonarWatchdog", watchdog);
// after
Jmx.register("org.sonar:type=Watchdog", watchdog);
Defensive patterns

Strategy: try-catch

Validate before calling

try { new ObjectName(name); } catch (MalformedObjectNameException e) { throw new IllegalArgumentException("bad ObjectName: " + name, e); }

Try / catch

try { Jmx.register(name, instance); } catch (IllegalStateException e) { LOGGER.warn("MBean {} not registered", name, e); }

Prevention

When it happens

Trigger: register(name, instance) with a name that is not a valid ObjectName, an object with no valid MBean interface, or a name already bound in the MBean server.

Common situations: Name missing required domain or key property (e.g. missing key in 'type='); two components trying to register the same MBean name; class missing a suitable interface.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/f6d618b24da8a368. Report an issue: GitHub.

Appendix: source

Thrown at server/sonar-process/src/main/java/org/sonar/process/Jmx.java:49

/**
 * JMX utilities to register MBeans to JMX server
 */
public class Jmx {

  private Jmx() {
    // only statics
  }

  /**
   * Register a MBean to JMX server
   */
  public static void register(String name, Object instance) {
    try {
      Class<Object> mbeanInterface = guessMBeanInterface(instance);
      ManagementFactory.getPlatformMBeanServer().registerMBean(new StandardMBean(instance, mbeanInterface), new ObjectName(name));

    } catch (MalformedObjectNameException | NotCompliantMBeanException | InstanceAlreadyExistsException | MBeanRegistrationException e) {
      throw new IllegalStateException("Can not register MBean [" + name + "]", e);
    }
  }

  /**
   * MBeans have multiple conventions, including:
   * 1. name of interface is suffixed by "MBean"
   * 2. name of implementation is the name of the interface without "MBean"
   * 3. implementation and interface must be in the same package
   * To avoid the last convention, we wrap the mbean within a StandardMBean. That
   * requires to find the related interface.
   */

  private static Class<Object> guessMBeanInterface(Object instance) {
    Class<Object> mbeanInterface = null;
    Class<Object>[] interfaces = (Class<Object>[])instance.getClass().getInterfaces();
    for (Class<Object> anInterface : interfaces) {
      if (anInterface.getName().endsWith("MBean")) {
        mbeanInterface = anInterface;

View on GitHub (pinned to 184c821202)