Не удается отправить объект через ObjectInputStream в Java

#java #objectinputstream #objectoutputstream #eofexception

#java #objectinputstream #objectoutputstream #исключение eofexception

Вопрос:

Я пишу приложение, которое использует потоки вывода и ввода объекта. Однако у меня проблема, потому что я не могу отправить свой объект должным образом. Я записываю его в stream, и сервер выдает мне исключение class not found , хотя и клиент, и сервер имеют точно такую же копию этого класса (единственное отличие — имя пакета) с одинаковым серийным идентификатором. Вот мой класс:

 import java.io.Serializable;

public class Message implements Serializable {

/**
 * 
 */
private static final long serialVersionUID = 1L;
private String username = null;
private String hashedPassword = null;
private Integer code = null;
private String from = null;
private String to = null;
private Object data = null;

public Message() {

}

public Message(Integer code) {
    this.code = code;
}

public Message(Integer code, Object data) {
    this.code = code;
    this.data = data;
}

public Message(String username, String hashedPassword, Integer code,
        String from, String to, Object data) {
    this.username = username;
    this.hashedPassword = hashedPassword;
    this.code = code;
    this.from = from;
    this.to = to;
    this.data = data;
}

public Integer getCode() {
    return code;
}
    //other getters and setters
}
  

Это класс, объект которого я хочу отправить. Вот клиентский код:

(Это wirtten только для тестирования)

 public static void main(String[] args) {
        try {
            Socket s = new Socket("localhost", 5656);
            ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());

            Message m = new Message("user3", "123", 100, "2011-06-11 22:22:22",
                "2011-06-11 22:22:22", "test");
        oos.writeObject(m);
        oos.flush();


        ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
        Message n = (Message) ois.readObject();
        System.out.print(n.toString());

        oos.close();
        ois.close();

    } catch (Exception e) {
        e.printStackTrace();
    }
  

и вот часть серверного кода (да, он многопоточный):

 package systemZarzadzaniaReporterami.serwer;

import java.beans.ExceptionListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.sql.SQLException;

public class ClientHandler extends Thread {

private ExceptionListener exceptionListener;

private Socket socket;
private String ip;

public ClientHandler(ExceptionListener exceptionListener, Socket socket) {
    this.exceptionListener = exceptionListener;
    this.socket = socket;
    ip = socket.getInetAddress().getHostAddress();
}

public void run() {
    Message in = null;
    ObjectInputStream inputStream = null;
    ObjectOutputStream outputStream = null;

    try {
    //  ClientListener.CONNECTION_COUNTER  ;

        inputStream = new ObjectInputStream(socket.getInputStream());

        in = (Message) inputStream.readObject();
        MessageProcessor messageProcessor = new MessageProcessor();

        System.out.print(in.getUsername());

        outputStream = new ObjectOutputStream(socket.getOutputStream());

        Message out = messageProcessor.process(in, ip);
                System.out.print(in.getCode().toString());      
        outputStream.writeObject(out);
        outputStream.flush();
    } catch (IOException e) {
        e.printStackTrace();
        exceptionListener.exceptionThrown(new ServerException(Codes.ERR_CONNECTION_ERROR));
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (SQLException e) {
        e.printStackTrace();
        exceptionListener.exceptionThrown(new ServerException(Codes.ERR_MYSQL_ERROR));
    } finally {
        if (inputStream != null)
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
                exceptionListener.exceptionThrown(new ServerException(Codes.ERR_CONNECTION_ERROR));
            }
        if (outputStream != null)
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
                exceptionListener.exceptionThrown(new ServerException(Codes.ERR_CONNECTION_ERROR));
            }
        if (socket != null)
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
                exceptionListener.exceptionThrown(new ServerException(Codes.ERR_CONNECTION_ERROR));
            }
    //  ClientListener.CONNECTION_COUNTER--;
    }
}

}
  

Сейчас я в замешательстве. Потому что я понятия не имею, почему это происходит.

Что наиболее важно, на мой взгляд, что следующий код хорошо работает, когда я заменяю Message на string .

Комментарии:

1. имя пакета является частью полного имени классов. Пакеты по сути являются пространствами имен , которые необходимы для уникальной идентификации классов в модулях. Если пакеты отличаются, компилятор не может узнать ваши намерения.

2. Спасибо! Это идеальное объяснение.

Ответ №1:

единственное отличие заключается в имени пакета

Это не сработает. Имя класса (включая имя пакета) должно быть одинаковым с обеих сторон.

Комментарии:

1. О, боже. Действительно? Итак, я должен создать пакет, который будет содержать сериализуемые классы, и прикрепить этот пакет как к клиенту, так и к серверу?

2. Да, я бы использовал один и тот же JAR с обеих сторон.

Ответ №2:

единственное отличие заключается в имени пакета

Тогда они не являются одним и тем же классом. Убедитесь, что у вас есть точно один и тот же класс с обеих сторон. Это означает тот же пакет.