Search code examples
javatomcatwebsocketjava-8bugzilla

addMessageHandler NullPointerException with Lambda


Tomcat 8.0.21

This works:

session.addMessageHandler(new MessageHandler.Whole<String>() {
            @Override
            public void onMessage(String string) {
                try {
                    session.getBasicRemote().sendText(string);
                } catch (IOException ex) {
                    Logger.getLogger(WebSocket.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });

This doesn't:

session.addMessageHandler((MessageHandler.Whole<String>) (String string) -> {
            try {
                session.getBasicRemote().sendText(string);
            } catch (IOException ex) {
                Logger.getLogger(WebSocket.class.getName()).log(Level.SEVERE, null, ex);
            }
        });

Can I assume that this is a tomcat bug?

java.lang.NullPointerException
    at org.apache.tomcat.websocket.Util.getGenericType(Util.java:192)
    at org.apache.tomcat.websocket.Util.getGenericType(Util.java:212)
    at org.apache.tomcat.websocket.Util.getGenericType(Util.java:212)
    at org.apache.tomcat.websocket.Util.getMessageType(Util.java:171)
    at org.apache.tomcat.websocket.WsSession.addMessageHandler(WsSession.java:198)
    at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.init(WsHttpUpgradeHandler.java:138)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:696)
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1517)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1474)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

Solution

  • Not sure which version of Tomcat you are using, but it could already be fixed: https://bz.apache.org/bugzilla/show_bug.cgi?format=multiple&id=57788

    Also, the method you are calling uses raw types and does not work in all cases. From Tomcat Javadoc for addMessageHandler(MessageHandler):

    The message type will be derived at runtime from the provided MessageHandler instance. It is not always possible to do this so it is better to use addMessageHandler(Class, javax.websocket.MessageHandler.Partial) or addMessageHandler(Class, javax.websocket.MessageHandler.Whole).

    Try this instead:

    session.addMessageHandler(String.class, (String string) -> { ... } )