apache/shenyu · error · ShenyuException

Class missing annotation ShenyuServerEndpoint! class name:

Error message

Class missing annotation ShenyuServerEndpoint! class name: 

What it means

ShenyuServerEndpointerExporter.registerEndpoint() requires each candidate class to be annotated with @ShenyuServerEndpoint. When AnnotatedElementUtils.findMergedAnnotation returns null, the class cannot be converted into a websocket ServerEndpointConfig for gateway registration, so a ShenyuException naming the offending class is thrown.

Solutions

  1. Annotate the websocket endpoint class with @ShenyuServerEndpoint("/your/path") in addition to @ServerEndpoint.
  2. Check the exception's 'class name:' suffix to find the offending class and confirm it is the intended endpoint.
  3. Narrow the scanned base packages so unrelated beans are not passed to registerEndpoint.
  4. If the class is intentionally not an endpoint, remove it from the beans passed to the exporter.

Example fix

// before
@ServerEndpoint("/websocket/echo")
public class EchoServer { ... }
// after
@ServerEndpoint("/websocket/echo")
@ShenyuServerEndpoint("/websocket/echo")
public class EchoServer { ... }
Defensive patterns

Strategy: validation

Validate before calling

Class<?> pojo = ...;
if (AnnotatedElementUtils.findMergedAnnotation(pojo, ShenyuServerEndpoint.class) == null) {
    throw new IllegalArgumentException(pojo.getName() + " must be annotated with @ShenyuServerEndpoint");
}

Type guard

boolean isShenyuEndpoint(Class<?> c) {
    return AnnotatedElementUtils.findMergedAnnotation(c, ShenyuServerEndpoint.class) != null;
}

Try / catch

try {
    exporter.registerEndpoint(pojo);
} catch (ShenyuException e) {
    LOG.error("Endpoint registration failed: {}", e.getMessage());
}

Prevention

When it happens

Trigger: registerEndpoint(pojo) is called (directly or via registerEndpointsBeans scanning) with a bean class that lacks the @ShenyuServerEndpoint annotation — e.g. a plain @ServerEndpoint JSR-356 class or an arbitrary bean picked up by the endpoint scan.

Common situations: Developers annotating websocket handlers only with javax/jakarta @ServerEndpoint and forgetting the ShenYu-specific @ShenyuServerEndpoint; passing non-endpoint helper beans into registerEndpoint; bean scanning picking up unrelated classes in the configured base packages.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at shenyu-client/shenyu-client-websocket/shenyu-client-spring-websocket/src/main/java/org/apache/shenyu/client/spring/websocket/init/ShenyuServerEndpointerExporter.java:79

    protected void initServletContext(final ServletContext servletContext) {
        if (Objects.isNull(this.serverContainer)) {
            this.serverContainer = (ServerContainer) servletContext.getAttribute("jakarta.websocket.server.ServerContainer");
        }
    }

    @Override
    protected boolean isContextRequired() {
        return false;
    }

    /**
     * Register endpoint.
     * @param pojo pojo
     */
    public void registerEndpoint(final Class<?> pojo) {
        ShenyuServerEndpoint annotation = AnnotatedElementUtils.findMergedAnnotation(pojo, ShenyuServerEndpoint.class);
        if (Objects.isNull(annotation)) {
            throw new ShenyuException("Class missing annotation ShenyuServerEndpoint! class name: " + pojo.getName());
        }

        String path = annotation.value();
        Class<? extends ServerEndpointConfig.Configurator> configuratorClazz = annotation.configurator();
        ServerEndpointConfig.Configurator configurator = null;
        if (!configuratorClazz.equals(ServerEndpointConfig.Configurator.class)) {
            try {
                configurator = annotation.configurator().getConstructor().newInstance();
            } catch (ReflectiveOperationException ex) {
                LOG.error("ShenyuServerEndpoint configurator init fail! Class name: {}, configurator name: {}", pojo.getName(), annotation.configurator().getName());
                throw new ShenyuException(ex);
            }
        }
        ServerEndpointConfig sec = ServerEndpointConfig.Builder.create(pojo, path)
                .decoders(Arrays.asList(annotation.decoders()))
                .encoders(Arrays.asList(annotation.encoders()))
                .subprotocols(Arrays.asList(annotation.subprotocols()))
                .configurator(configurator).build();

View on GitHub (pinned to 567142e072)