apache/shenyu · error · IllegalStateException

Cannot get the names of MBeans controlled by the MBean…

Error message

Cannot get the names of MBeans controlled by the MBean server.

What it means

PortUtils.getPort uses the platform MBeanServer to find Tomcat Connector MBeans (`*:type=Connector,*`) and read the port. If the query returns an empty set — no external Tomcat is running in this JVM — it throws IllegalStateException before reading the connector.

Solutions

  1. Use this path only with a standalone/external Tomcat; for embedded Spring Boot rely on the `local.server.port` environment strategy instead.
  2. Configure the port explicitly in shenyu client props so MBean lookup is never used.
  3. If you expect Tomcat, verify the JVM actually hosts it and JMX MBeans are registered (no custom MBeanServer filtering).
  4. Ensure exactly one external Tomcat instance per JVM; multiple connectors also fail detection.

Example fix

// before
Integer port = PortUtils.findPort(); // MBean path fails in embedded apps
// after
Integer port = environment.containsProperty("local.server.port")
        ? environment.getProperty("local.server.port", Integer.class)
        : PortUtils.findPort();
Defensive patterns

Strategy: try-catch

Validate before calling

boolean hasTomcatConnector = !ManagementFactory.getPlatformMBeanServer()
    .queryNames(ObjectName.getInstance("*:type=Connector,*"), null).isEmpty();

Try / catch

try {
    port = PortUtils.getPort();
} catch (IllegalStateException e) {
    // no (or multiple) Tomcat Connector MBeans — fall back to config
    port = Integer.getInteger("server.port", 8080);
}

Prevention

When it happens

Trigger: getPort is called in a JVM without an external Tomcat (embedded server, non-Tomcat container, or plain unit test), so queryNames finds zero Connector MBeans.

Common situations: Spring Boot app with embedded Tomcat (MBeans named differently/not registered as expected), Jetty/Undertow deployments, tests calling findPort without any server; also related failure when multiple Tomcat instances run in one JVM (the next check throws).

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12). Data as JSON: /api/errors/dbd6f85a7c77a5a3. Report an issue: GitHub.

Appendix: source

Thrown at shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/utils/PortUtils.java:95

            NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        final Class<?> clazz = Class.forName(className);
        final Method method = clazz.getMethod("getPort");
        final Object bean = beanFactory.getBean(clazz);
        return (int) method.invoke(bean);
    }

    /**
     * get the current tomcat port number.
     * Note: This method is not supported when there are multiple instances of external Tomcat.
     *
     * @return tomcat port number
     * @throws Exception when failed to get port
     */
    public static Integer getPort() throws Exception {
        MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
        Set<ObjectName> objectNames = mBeanServer.queryNames(new ObjectName("*:type=Connector,*"), null);
        if (CollectionUtils.isEmpty(objectNames)) {
            throw new IllegalStateException("Cannot get the names of MBeans controlled by the MBean server.");
        }
        //This method is not supported when there are multiple instances of external Tomcat
        if (objectNames.size() > 1) {
            throw new IllegalStateException("Not supported when there are multiple instances of external Tomcat.");
        }
        ObjectName objectName = objectNames.iterator().next();
        String protocol = String.valueOf(mBeanServer.getAttribute(objectName, "protocol"));
        String port = String.valueOf(mBeanServer.getAttribute(objectName, "port"));
        // The property name is HTTP1.1, org.apache.coyote.http11.Http11NioProtocol under linux
        if ("HTTP/1.1".equals(protocol) || "org.apache.coyote.http11.Http11NioProtocol".equals(protocol)) {
            return Integer.parseInt(port);
        }
        throw new IllegalStateException("failed to get the HTTP port of the current tomcat");
    }

}

View on GitHub (pinned to 567142e072)