14

I have 2 java netbeans projects, one is the Server other is the Client. I have a Message class that I have created which I want to pass to the server and back the other way to the client after modification done at the server. I have included the class Message in both projects. I use ObjectOutputStream and ObjectInputStream to pass the object. The connection between the server and the client is ok and the object passes through but at the server when I read the object from the ObjectInputStream using readObject() method I type cast it to the Message class. But an ClassNotFoundException is thrown at the server. It cant find the Message class. How can I resolve this?

Code for the client:

public void startClient() {
    try {
        // Create the socket
        Socket clientSocket = new Socket(HOST, PORT);
        // Create the input & output streams to the server
        ObjectOutputStream outToServer = new ObjectOutputStream(clientSocket.getOutputStream());
        ObjectInputStream inFromServer = new ObjectInputStream(clientSocket.getInputStream());

        // Read modify
        // TODO here

        /* Create The Message Object to send */
        LinkedList<Message> msgList = new LinkedList<>();
        Message msg = new Message();
        msg.setMessage("Kasun");
        msg.setIndex(1);
        msg.setAverage(5.5f);
        msgList.push(msg);

        /* Send the Message Object to the server */
        outToServer.writeObject(msgList);            

        /* Retrive the Message Object from server */
        LinkedList<Message> inFromServerList = new LinkedList<>();
        Message msgFrmServer = null;
        inFromServerList = (LinkedList<Message>)inFromServer.readObject();
        msgFrmServer = inFromServerList.pop();

        /* Print out the recived Message */
        System.out.println("Message: " + msgFrmServer.getMessage());
        System.out.println("Index: " + msgFrmServer.getIndex());
        System.out.println("Average: " + msgFrmServer.getAverage());


        clientSocket.close();

    } catch (Exception e) {
        System.err.println("Client Error: " + e.getMessage());
        System.err.println("Localized: " + e.getLocalizedMessage());
        System.err.println("Stack Trace: " + e.getStackTrace());
    }
}

Code for the Server

public void startServer() {

    try {
        ServerSocket welcomeSocket = new ServerSocket(PORT);

        while (true) {    
            // Create the Client Socket
            Socket clientSocket = welcomeSocket.accept();
            System.out.println("Socket Extablished...");
            // Create input and output streams to client
            ObjectOutputStream outToClient = new ObjectOutputStream(clientSocket.getOutputStream());
            ObjectInputStream inFromClient = new ObjectInputStream(clientSocket.getInputStream());

            // Read modify
            // TODO here

            /* Create Message object and retrive information */
            LinkedList<Message> inList = new LinkedList<>();
            Message inMsg = null;
            inList = (LinkedList<Message>)inFromClient.readObject();
            inMsg = inList.pop();

            /* Modify the message object */
            inMsg.setMessage(inMsg.getMessage().toUpperCase());
            inMsg.setIndex(5);
            inMsg.setAverage(10.5f);

            /* Send the modified Message object back */
            outToClient.writeObject(inMsg);        

        }

    } catch (Exception e) {
        System.err.println("Server Error: " + e.getMessage());
        System.err.println("Localized: " + e.getLocalizedMessage());
        System.err.println("Stack Trace: " + e.getStackTrace());
        System.err.println("To String: " + e.toString());
    }
}

The exception thrown at the "server"

java.lang.ClassNotFoundException: rusl.online.examination.system.client.utility.Message

Would I have to use java RMI? Is there a solution for this without using RMI?

meJustAndrew
  • 6,011
  • 8
  • 50
  • 76
Kasun Kodagoda
  • 3,956
  • 5
  • 31
  • 54

2 Answers2

7

Make sure that Message on server side is rusl.online.examination.system.client.utility.Message. It seems not to be the case.

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
  • It worked, :) and found another error in the process. I tried the same method before i posted the question here. but oddly it didn;t work.. it worked this time.. Thanks a lot :) – Kasun Kodagoda Oct 07 '13 at 05:57
1

If you are sending objects of a class over the socket. In order to reproduce the object at the other end, you have to cast the object. For that you will require the class definition on both ends.

Make sure you properly import the same Message class for server program as well, which you used to create the message.

Sorter
  • 9,704
  • 6
  • 64
  • 74
  • The class definition is required prior to the cast. It is required to deserialize the object itself. – user207421 Oct 07 '13 at 05:21
  • And he must have imported it properly, otherwise it wouldn't have compiled, so he couldn't have executed, so he couldn't have got this exception. Answer is not correct. – user207421 May 13 '21 at 03:54
  • user207421 The message classes could be 2 classes with the same name but different versions uuid. This seems to have been the case since the answer from Evgeniy Dorofeev points out that it's likely a class mismatch approved by the author. Also since he deserializes a linked list with the message inside the class is not needed for deserialization. The class cast exception is likely thrown at the pop method call of the linked list and the implicit cast by the generic linked list – RedCrafter LP Oct 28 '22 at 14:59