apache/shenyu · error · IllegalStateException

Not supported when there are multiple instances of external…

Error message

Not supported when there are multiple instances of external Tomcat.

What it means

PortUtils.getPort() discovers the embedded/external Tomcat HTTP connector port via JMX MBeans. The MBean query '*:type=Connector,*' returned more than one Connector object name, meaning multiple Tomcat instances (or connectors) are running in this JVM, so there is no single unambiguous port to return. The utility deliberately refuses to guess.

Solutions

  1. Remove or disable extra Tomcat connectors so exactly one HTTP Connector remains
  2. Configure the port explicitly in the client config (shenyu.client.<type>.props.port) instead of relying on auto-discovery
  3. Ensure only one Tomcat instance runs in the JVM; start others in separate processes
  4. Catch IllegalStateException and fall back to an explicitly configured port

Example fix

// before
int port = PortUtils.getPort();
// after
int port = props.containsKey("port")
        ? Integer.parseInt(props.getProperty("port"))
        : PortUtils.getPort();
Defensive patterns

Strategy: try-catch

Validate before calling

int connectorCount = ManagementFactory.getPlatformMBeanServer()
        .queryNames(new ObjectName("*:type=Connector,*"), null).size();
if (connectorCount > 1) { /* use explicit port from config */ }

Try / catch

int port;
try { port = PortUtils.getPort(); }
catch (IllegalStateException e) { port = Integer.parseInt(props.getProperty("port")); }

Prevention

When it happens

Trigger: Calling PortUtils.getPort() when the MBean server reports multiple 'Connector' MBeans — e.g. several external Tomcat instances in the same JVM, or multiple connectors configured in server.xml (HTTP + AJP, HTTPS + HTTP).

Common situations: Running several embedded Tomcat instances in one application; a server.xml with AJP or additional HTTPS connectors alongside the HTTP connector; deploying the ShenYu client into a shared Tomcat hosting multiple webapps with separate connectors.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

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

        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)