SonarSource/sonarqube · error · IllegalArgumentException
Can not find the MBean interface of class
Error message
Can not find the MBean interface of class
What it means
guessMBeanInterface scans the instance's implemented interfaces for one whose name ends with 'MBean'. If none is found it throws IllegalArgumentException, because StandardMBean requires such an interface.
Solutions
- Make the class implement a public interface whose name ends with 'MBean'
- Restore the MBean suffix if a rename removed it
- Ensure the interface is public (StandardMBean requirement)
- Pass the correct managed object to Jmx.register
Example fix
// before
public interface Watchdog { void check(); }
class WatchdogImpl implements Watchdog {}
// after
public interface WatchdogMBean { void check(); }
class WatchdogImpl implements WatchdogMBean {} Defensive patterns
Strategy: type-guard
Validate before calling
boolean hasMBeanInterface(Object o) {
return Arrays.stream(o.getClass().getInterfaces())
.anyMatch(i -> i.getName().endsWith("MBean"));
} Type guard
static boolean isRegisterable(Object instance) {
return Arrays.stream(instance.getClass().getInterfaces())
.anyMatch(i -> java.lang.reflect.Modifier.isPublic(i.getModifiers()) && i.getName().endsWith("MBean"));
} Try / catch
try { Jmx.register(name, instance); } catch (IllegalArgumentException e) { throw new IllegalStateException("Object " + instance + " lacks an MBean interface", e); } Prevention
- Name management interfaces with the MBean suffix
- Keep management interfaces public
- Add a unit test registering each managed bean
When it happens
Trigger: register(name, instance) where instance's class implements no interface named *MBean (or the matching interface is not public).
Common situations: Refactoring renamed the interface dropping the MBean suffix; object implements only non-public interfaces; wrong object passed to register.
Related errors
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/12fe8c60ea0c4647.
Report an issue: GitHub.
Appendix: source
Thrown at server/sonar-process/src/main/java/org/sonar/process/Jmx.java:72
* 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;
break;
}
}
if (mbeanInterface == null) {
throw new IllegalArgumentException("Can not find the MBean interface of class " + instance.getClass().getName());
}
return mbeanInterface;
}
/**
* Unregister a MBean from JMX server. Errors are ignored and logged as warnings.
*/
public static void unregister(String name) {
try {
ManagementFactory.getPlatformMBeanServer().unregisterMBean(new ObjectName(name));
} catch (Exception e) {
LoggerFactory.getLogger(Jmx.class).warn("Can not unregister MBean [{}]", name, e);
}
}
}
View on GitHub (pinned to 184c821202)