0

I am creating a group chat functionality on my app and I am having some issues. Requirements are Java and Websockets in Java(both server and the client part). I have created both server and client WebSockets and communication by itself works(sending text from client to server and visa versa), but what I want to do is send Objects through the socket and serialize it into XML. I have created the serialization and it work perfectly without the socket. The problem appears when I want to combine the two.

For now I tried embedding the encoder and decoder to socket implementation and sending Player object through the socket and got this error(whatever I tried later the error stayed the same):


java.lang.ClassNotFoundException: model/Player
Continuing ...
java.lang.NoSuchMethodException: <unbound>=XMLDecoder.new();
Continuing ...
java.lang.IllegalStateException: The outer element does not return value
Continuing ...
java.lang.IllegalStateException: The outer element does not return value
Continuing ...
java.lang.ArrayIndexOutOfBoundsException: 0
    at java.beans.XMLDecoder.readObject(Unknown Source)
    at Util.Util.getObjectFromXml(Util.java:43)
    at Util.WebDecoder.decode(WebDecoder.java:28)
    at org.apache.tomcat.websocket.pojo.PojoMessageHandlerWholeText.decode(PojoMessageHandlerWholeText.java:108)
    at org.apache.tomcat.websocket.pojo.PojoMessageHandlerWholeText.decode(PojoMessageHandlerWholeText.java:39)
    at org.apache.tomcat.websocket.pojo.PojoMessageHandlerWholeBase.onMessage(PojoMessageHandlerWholeBase.java:57)
    at org.apache.tomcat.websocket.WsFrameBase.sendMessageText(WsFrameBase.java:395)
    at org.apache.tomcat.websocket.WsFrameBase.processDataText(WsFrameBase.java:495)
    at org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:294)
    at org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:133)
    at org.apache.tomcat.websocket.WsFrameClient.processSocketRead(WsFrameClient.java:95)
    at org.apache.tomcat.websocket.WsFrameClient.resumeProcessing(WsFrameClient.java:209)
    at org.apache.tomcat.websocket.WsFrameClient.access$300(WsFrameClient.java:31)
    at org.apache.tomcat.websocket.WsFrameClient$WsFrameClientCompletionHandler.doResumeProcessing(WsFrameClient.java:186)
    at org.apache.tomcat.websocket.WsFrameClient$WsFrameClientCompletionHandler.completed(WsFrameClient.java:163)
    at org.apache.tomcat.websocket.WsFrameClient$WsFrameClientCompletionHandler.completed(WsFrameClient.java:148)
    at sun.nio.ch.Invoker.invokeUnchecked(Unknown Source)
    at sun.nio.ch.Invoker$2.run(Unknown Source)
    at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

I tried serializing the data into String sending it through the socket like text, receiving String and deserializing it on the client side of the app. The Exception persisted.

Xml decoder and encoder, they both work properly, but just in case I am wrong I'll put it here.

public class Util
{

    public static String getXmlFromObject(Object o)
    {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        XMLEncoder xmlEncoder = new XMLEncoder(baos);
        xmlEncoder.writeObject(o);
        xmlEncoder.close();
        return new String(baos.toByteArray()).replace("\n", "")+"\n";
    }

    public static Object getObjectFromXml(String xml)
    {
        ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes());
        XMLDecoder xmlDecoder = new XMLDecoder(bais);
        Object o = xmlDecoder.readObject();
        xmlDecoder.close();

        return o;
    }
}

WebSocket on the server side:

@ServerEndpoint(value="/chat", encoders= {WebEncoder.class}, decoders= {WebDecoder.class})
public class ChatWebSocket
{
    List<Session> sessions = new ArrayList<Session>();


    @OnOpen
    public void open(Session session)
    {
        sessions.add(session);
    }

    @OnClose
    public void close(Session session)
    {
        sessions.remove(session);
    }

    @OnError
    public void OnError(Session session, Throwable t)
    {
        System.out.println(session);
        sessions.remove(session);
        t.printStackTrace();

    }

    @OnMessage
    public void handleMessage(Object message, Session session)
    {

        for (Session s : sessions)
        {
            System.out.println(s);
            try
            {
                s.getBasicRemote().sendObject(message);
            } catch (IOException | EncodeException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}

WebSocket for the client side and a code snippet sending the message and for receiving it on the client side:

@ClientEndpoint(encoders= {WebEncoder.class}, decoders= {WebDecoder.class})
public class ChatWebSocketClient
{


    Session session = null;
    private MessageHandler messageHandler;

    public ChatWebSocketClient(URI endpointURI)
    {
        try
        {
            WebSocketContainer container = ContainerProvider.getWebSocketContainer();
            container.connectToServer(this, endpointURI);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    @OnOpen
    public void open(Session session)
    {
        this.session = session;
    }

    @OnClose
    public void close(Session sesion, CloseReason reason)
    {
        this.session = null;
    }

    @OnError
    public void onError(Session session, Throwable t)
    {
        t.printStackTrace();
    }

    @OnMessage
    public void OnMessage(Object message)
    {

        if (this.messageHandler != null)
        {
            this.messageHandler.handleMessage(message);
        }
    }

    public void addMessageHandler(MessageHandler msgHandler)
    {
        messageHandler = msgHandler;
    }


    public void sendMessage(Object message)
    {
        try
        {
            session.getBasicRemote().sendObject(message);
        } catch (IOException | EncodeException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }




}



final ChatWebSocketClient webSocket = new ChatWebSocketClient(new URI("ws://localhost:8080/XOX/chat"));
webSocket.addMessageHandler(new MessageHandler(){
    @Override
    public void handleMessage(Object message)
    {
        System.out.println("jsp "+message.getClass().getName());
        System.out.println("jsp "+Util.getXmlFromObject(message));
    }
});
webSocket.sendMessage(player);

  • The problem seems to be: `java.lang.ClassNotFoundException: model/Player` Is class `Player` in package `model` one that you wrote? – Abra Sep 09 '19 at 17:11
  • Yes it's a class I wrote in the package model, but in the case it is the problem I cannot understand why and how to correct it. The thing is without the socket serializing and deserializing tobject of type Player is working properly. – Andreja Zivic Sep 09 '19 at 17:30
  • Have you read the [documentation](https://docs.oracle.com/javase/8/docs/api/java/lang/ClassNotFoundException.html) for `ClassNotFoundException` ? Perhaps [How do I resolve ClassNotFoundException?](https://stackoverflow.com/questions/17408769/how-do-i-resolve-classnotfoundexception) will help. – Abra Sep 09 '19 at 17:44

0 Answers0