perwendel/spark · error · RuntimeException

Could not instantiate websocket handler

Error message

Could not instantiate websocket handler

What it means

WebSocketHandlerClassWrapper wraps a WebSocket handler specified as a Class and instantiates it in getHandler() via handlerClass.newInstance(). If the class cannot be instantiated — it is abstract, an interface, or has no accessible no-arg constructor — the reflective instantiation throws InstantiationException/IllegalAccessException, rethrown as RuntimeException('Could not instantiate websocket handler').

Solutions

  1. Make the handler class concrete, non-abstract, with a public no-arg constructor.
  2. Use the WebSocketHandler instance variant (Spark.webSocket("/path", handler)) so Spark doesn't reflectively instantiate the class.
  3. If the handler needs dependencies, wrap a pre-built instance in a WebSocketHandlerWrapper instead of passing the class.
  4. Ensure inner handler classes are static (or top-level) so newInstance() can construct them.

Example fix

// before
public abstract class WsHandler implements WebSocketHandler { }
Spark.webSocket("/ws", WsHandler.class); // newInstance fails
// after
public class WsHandler implements WebSocketHandler {
    public WsHandler() { }
    public void onOpen(WebSocket ws) { }
}
Spark.webSocket("/ws", WsHandler.class);
Defensive patterns

Strategy: validation

Validate before calling

Class<?> c = WsHandler.class;
if (c.isInterface() || java.lang.reflect.Modifier.isAbstract(c.getModifiers())) {
    throw new IllegalArgumentException("Handler must be a concrete class");
}
try { c.getDeclaredConstructor().setAccessible(true); } catch (NoSuchMethodException e) {
    throw new IllegalArgumentException("Handler needs a no-arg constructor");
}
Spark.webSocket("/ws", WsHandler.class);

Type guard

boolean instantiableHandler(Class<?> c) {
    return !c.isInterface() && !java.lang.reflect.Modifier.isAbstract(c.getModifiers());
}

Try / catch

try {
    Spark.webSocket("/ws", WsHandler.class);
} catch (RuntimeException e) {
    if (e.getMessage().contains("Could not instantiate websocket handler")) {
        LOG.error("Handler class must be concrete with a no-arg constructor", e);
    } else { throw e; }
}

Prevention

When it happens

Trigger: Registering a WebSocket handler class that is abstract or an interface via Spark.webSocket("/path", HandlerClass.class), or one without a public no-arg constructor.

Common situations: Passing a handler class with constructor dependencies (DI-style classes); abstract handler base classes; non-static inner classes whose constructor requires the outer instance.

Related errors


AI-assisted analysis of perwendel/spark@1973e402f5 (2026-09-10). Data as JSON: /api/errors/8a95ca161ab48a64. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/spark/embeddedserver/jetty/websocket/WebSocketHandlerClassWrapper.java:19

package spark.embeddedserver.jetty.websocket;

import static java.util.Objects.requireNonNull;

public class WebSocketHandlerClassWrapper implements WebSocketHandlerWrapper {
    
    private final Class<?> handlerClass;

    public WebSocketHandlerClassWrapper(Class<?> handlerClass) {
        requireNonNull(handlerClass, "WebSocket handler class cannot be null");
        WebSocketHandlerWrapper.validateHandlerClass(handlerClass);
        this.handlerClass = handlerClass;
    }
    @Override
    public Object getHandler() {
        try {
            return handlerClass.newInstance();
        } catch (InstantiationException | IllegalAccessException ex) {
            throw new RuntimeException("Could not instantiate websocket handler", ex);
        }
    }

}

View on GitHub (pinned to 1973e402f5)