0

I have a bean class on a Client side that stores user input data and send it through a socket to server. Server has identical bean class.

Server receives object, but when I try to assign what was received to an instance of the bean class, it results in following error:

java.lang.ClassCastException: ie.gmit.sw.client.methods.Client cannot be cast to ie.gmit.sw.server.methods.Client

Class with an error:

public class DriveableImpl implements Driveable{

    private Client client; 
    private ObjectOutputStream out; 
    private ObjectInputStream in; 

    public DriveableImpl() {
        client = new Client(); 
    }

    // Method that receives connection socket and open in/out streams for current session
    @Override
    public void connect(Socket socket){
        try {
            out = new ObjectOutputStream(socket.getOutputStream());
            in = new ObjectInputStream(socket.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean login() throws Exception {

        // Program crash here
        client = (Client) in.readObject();
        System.out.println(client.toString());

        return false;
    }
}

I use InvocationHandler to invoke methods implemented in class above:

public class MethodInvoker implements InvocationHandler{

    private Object returnObject = null; // object that will hold any returns from invoked methods
    private final Driveable userInterface; 


    protected MethodInvoker(Driveable ui) {
        this.userInterface = ui;
    }
    public Object invoke(Object proxy, Method method, Object[] args)
                  throws IllegalAccessException, IllegalArgumentException,
                  InvocationTargetException{

        System.out.println("BEFORE");
        returnObject = method.invoke(userInterface, args);
        System.out.println(method.getName());
        System.out.println("AFTER");

        return returnObject; // could problem be possibly here?
    }
}

I am really not sure what's going on here, as it works in simple design of a Client-Server app. I am posting, in my opinion, program parts that are relevant to an error, but I will modify post if any requests occur.

Thank you!

1 Answer 1

2

Note the Serialization Error:

It clearly states that you have 2 different classes (maybe they look exactly the same) but they are in different packages:

ie.gmit.sw.**client**.methods
ie.gmit.sw.**server**.methods

This means, that from the point of view of Java they're completely unrelated

ie.gmit.sw.client.methods.Client cannot be cast to ie.gmit.sw.server.methods.Client

That's the reason of why you have a class cast exception

In Java the Same Class means that it resides in the same package and has the same name. So you should have the same class in both server and client. There are two ways to achieve this:

  • Just put the same class twice - once in client and once in a server. In your case it means - rename the package to be something common. This is a bad approach because of code duplication

  • Place the objects that will pass the serialization into the third "common" module (jar will be produced out of it) and when you run the client and server make them dependent on this module. So physically you'll have only one copy of class "Client".

Sign up to request clarification or add additional context in comments.

8 Comments

I understand now what is going on. Any suggestions how to fix it? I've tried to use private static final long serialVersionUID = 777L; on both sides to identify objects.
Sure, just use the same class all the way both on client and on server. In general code duplication is a bad practice. So you should just reuse the existing class
Regarding the serialVersionUID - it won't help. If only can help when you have different versions of the same class. And "same" in java means: an identical package, and an identical class name
How can I achieve one class being used on both Client and Server if Server side suppose to run as separate program on Windows Servers and Client should be able to connect from anywhere else. It is a multi threaded banking system college project designed using OOP principals. Am I missing some part of a theory about OOP design?
Ok, I am getting an idea now. Would inheriting different versions from abstract bean class which sits at the ie.gmit.sw. on both sides be good idea?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.