Undertow - null pointer when creating a websocket endpoint
meetoblivion Mar 9, 2014 9:13 AMHi
So I'm creating a websocket endpoint in Undertow. I get this null pointer exception:
Mar 09, 2014 9:02:07 AM org.xnio.ChannelListeners invokeChannelListener
ERROR: XNIO001007: A channel event listener threw an exception
java.lang.NullPointerException
at io.undertow.websockets.jsr.annotated.AnnotatedEndpoint$AnnotatedEndpointFrameHandler.handleBinaryMessage(AnnotatedEndpoint.java:373)
at io.undertow.websockets.jsr.annotated.AnnotatedEndpoint$AnnotatedEndpointFrameHandler.access$1100(AnnotatedEndpoint.java:126)
at io.undertow.websockets.jsr.annotated.AnnotatedEndpoint$AnnotatedEndpointFrameHandler$6.complete(AnnotatedEndpoint.java:332)
at io.undertow.websockets.jsr.annotated.AnnotatedEndpoint$AnnotatedEndpointFrameHandler$6.complete(AnnotatedEndpoint.java:329)
at io.undertow.websockets.core.BufferedBinaryMessage.read(BufferedBinaryMessage.java:76)
at io.undertow.websockets.jsr.annotated.AnnotatedEndpoint$AnnotatedEndpointFrameHandler.onBinary(AnnotatedEndpoint.java:329)
at io.undertow.websockets.core.AbstractReceiveListener.handleEvent(AbstractReceiveListener.java:24)
at io.undertow.websockets.core.AbstractReceiveListener.handleEvent(AbstractReceiveListener.java:15)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:615)
at io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:601)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:87)
at org.xnio.nio.WorkerThread.run(WorkerThread.java:531)
I'm thinking I missed something in the setup, but not quite sure (and the error doesn't give much info).
My server endpoint is setup like this:
@ServerEndpoint("/socket")
public class WebsocketEndpoint extends Endpoint {
@Override
public void onOpen(Session session, EndpointConfig endpointConfig) {
session.addMessageHandler(new MessageHandler.Whole<ByteBuffer>() {
@Override
public void onMessage(ByteBuffer byteBuffer) {
System.out.println("New message: "+byteBuffer.asCharBuffer().array());
}
});
}
@Override
public void onClose(Session session, CloseReason closeReason) {
super.onClose(session, closeReason);
}
@Override
public void onError(Session session, Throwable thr) {
super.onError(session, thr);
}
}
I'm starting undertow like this:
XnioWorker worker = this.createWorker();
DeploymentInfo deploymentInfo = new DeploymentInfo()
.setClassLoader(ClassLoader.getSystemClassLoader())
.setContextPath("/")
.setClassIntrospecter(TestClassIntrospector.INSTANCE)
.addServletContextAttribute(WebSocketDeploymentInfo.ATTRIBUTE_NAME,
new WebSocketDeploymentInfo()
.setBuffers(new ByteBufferSlicePool(100, 1000))
.setWorker(worker)
.addEndpoint(WebsocketEndpoint.class)
.addListener(new WebSocketDeploymentInfo.ContainerReadyListener() {
@Override
public void ready(ServerWebSocketContainer container) {
deployment = container;
}
})
)
.setDeploymentName("mydeployment");
DeploymentManager deploymentManager = Servlets.defaultContainer().addDeployment(deploymentInfo);
deploymentManager.deploy();
Undertow server = null;
try {
server = Undertow.builder()
.addHttpListener(9991,"0.0.0.0")
.setHandler(deploymentManager.start())
.build();
server.start();
} catch (ServletException e) {
e.printStackTrace();
}
The client is a Java SE client, just deploying it inside a JUnit test.
@Test
public void testSoemthing() throws Exception {
URI uri = URI.create("ws://localhost:9991/socket");
Session session = ContainerProvider.getWebSocketContainer().connectToServer(QDXClientEndpoint.class,uri);
System.out.println("Is open"+session.isOpen());
RemoteEndpoint.Basic basicRemote = session.getBasicRemote();
String message= "Hello world!";
ByteBuffer buffer = ByteBuffer.wrap(message.getBytes(Charset.defaultCharset()));
basicRemote.sendBinary(buffer);
session.close();
}
where my client endpoint is annotated:
@ClientEndpoint
public class QDXClientEndpoint {
@OnOpen
public void onOpen(Session session) {
}
@OnMessage
public void processMessage(String message) {
System.out.println("Received message in client: " + message);
}
@OnError
public void processError(Throwable t) {
t.printStackTrace();
}
}