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
- Make the handler class concrete, non-abstract, with a public no-arg constructor.
- Use the WebSocketHandler instance variant (Spark.webSocket("/path", handler)) so Spark doesn't reflectively instantiate the class.
- If the handler needs dependencies, wrap a pre-built instance in a WebSocketHandlerWrapper instead of passing the class.
- 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
- Make WebSocket handler classes public, concrete, with public no-arg constructors.
- Avoid DI-constructed handler classes; pass dependencies via static config or instance wrappers.
- Add a unit test that calls newInstance() on every registered handler class.
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
- WebSockets are only supported in the embedded server
- HttpServletRequest cannot be null.
- This must be done after route mapping has begun
- Must provide a keystore file to run secured
- Server has not been properly initialized
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)