Попытка написать программу, которая позволит клиентам отправлять объект друг другу. В настоящее время я использую ObjectOuptutStream для отправки его через сокеты, и всякий раз, когда я пытаюсь прочитать или записать объект из потока объектов, он выдает исключение: java.io.NotSerializableException . Я искал в Интернете об этом исключении, и решение, которое я в основном получал, заключалось в реализации интерфейса Serializable для объекта, который вы отправляете или читаете из потока. Что я и сделал, но все равно получаю это исключение.
Вот класс объекта:
public class Event implements Serializable {
private static final long serialVersionUID = 1L;
Integer from;
Vector<Integer> timestamp;
public Event(int identifier, Vector<Integer> timestamp) {
this.from = identifier;
this.timestamp = timestamp;
}
int getFromID() {
return from;
}
Vector<Integer> getTimestamp() {
return timestamp;
}
}
Вот раздел класса Client, который пишет в другие сокеты
Random rand = new Random();
int temp;
while (eventCount < 100) {
System.out.println("Generating Event");
int choice = rand.nextInt(5);
if (choice == 0) {
temp = timestamp.get(identifier);
++temp;
timestamp.set(identifier, temp);
} else {
int randC = rand.nextInt(outputClients.size());
ClientSocket cc = outputClients.get(randC);
cc.out.writeObject(new Event(identifier, timestamp));
}
System.out.println("Done Generating Event");
}
А вот темы, которые читают объект
public class ClientConnection extends Thread {
Socket socket;
ObjectOutputStream out;
ObjectInputStream in;
Random rand = new Random();
public ClientConnection(Socket s) {
this.socket = s;
try {
out = new ObjectOutputStream (socket.getOutputStream());
in = new ObjectInputStream (socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
// execute the event
private void executeEvent(int from, Vector<Integer> x) {
int temp;
synchronized (timestamp) {
for (int i = 0; i < timestamp.size(); ++i) {
if (x.get(i) > timestamp.get(i)) {
timestamp.set(i, x.get(i));
}
}
temp = timestamp.get(from);
++temp;
timestamp.set(from, temp);
}
}
@Override
public void run () {
while (true) {
System.out.println("Reading events");
if (!isAlive) {
break;
}
try {
Event event = (Event) in.readObject();
executeEvent(event.getFromID(), event.getTimestamp());
} catch (ClassNotFoundException e) {
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(timestamp);
}
}
}
А вот класс Client для полного контекста (при условии, что все соответствующие пакеты импортированы)
public class Computer {
static final int MAX_SYSTEMS = 2; // MAX SYSTEMS
static Vector<Integer> timestamp = new Vector<Integer>();
static int[] timestamp1 = new int[MAX_SYSTEMS]; // Time-stamp
static int identifier; // Computer ID
static int eventCount = 0; // Event Counts
static boolean isAlive = true; // Check if the computer is alive
Socket sockToServer;
PrintWriter outputToServer;
BufferedReader inputFromServer;
String textFromServer;
ServerSocket ss;
static ArrayList<ClientSocket> outputClients = new ArrayList<ClientSocket>();
static ArrayList<ClientConnection> inputClients = new ArrayList<ClientConnection>();
Log log;
public static void main(String[] args) throws IOException {
new Computer("127.0.0.1", 8000);
}
public Computer(String hostname, int port) throws IOException {
// Instantiate server socket
int socketPort = port + identifier + 1;
System.out.println(socketPort);
ss = new ServerSocket(socketPort);
System.out.println("Server Socket Instantiated");
// Creating sockets (with streams) to write to stream
for (int i = 0; i < MAX_SYSTEMS; ++i) {
if (i != identifier) {
Socket thing1 = new Socket(hostname, port + i + 1);
ClientSocket cs = new ClientSocket (thing1);
outputClients.add(cs);
}
}
log.write("Client Sockets Instantiated\n");
// Create threads for reading objects and updating timestamp
for (int i = 0; i < MAX_SYSTEMS - 1; ++i) {
ClientConnection clientConn = new ClientConnection(ss.accept());
clientConn.start();
inputClients.add(clientConn);
}
log.write("Server connected to clients");
Random rand = new Random();
// Writing Events
int temp;
while (eventCount < 100) {
System.out.println("Generating Event");
int choice = rand.nextInt(5);
if (choice == 0) {
temp = timestamp.get(identifier);
++temp;
timestamp.set(identifier, temp);
} else {
int randC = rand.nextInt(outputClients.size());
ClientSocket cc = outputClients.get(randC);
cc.out.writeObject(new Event(identifier, timestamp));
}
System.out.println("Done Generating Event");
}
log.write("Computer finished generating events. Continue listening...\n");
outputToServer.println("Finish");
// Wait for Tear Down Message
while (true) {
try {
textFromServer = inputFromServer.readLine();
if (textFromServer.equals("Tear Down")) {
isAlive = false;
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
log.write("Computer shutting off....");
for (int i = 0; i < outputClients.size(); ++i) {
ClientSocket sc = outputClients.get(i);
sc.socket.close();
}
sockToServer.close();
}
// client socket class (organizing)
public class ClientSocket {
Socket socket;
ObjectOutputStream out;
ObjectInputStream in;
public ClientSocket(Socket s) {
try {
this.socket = s;
this.out = new ObjectOutputStream(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Client Socket Created");
}
}
public class Event implements Serializable {
private static final long serialVersionUID = 1L;
Integer from;
Vector<Integer> timestamp;
public Event(int identifier, Vector<Integer> timestamp) {
this.from = identifier;
this.timestamp = timestamp;
}
int getFromID() {
return from;
}
Vector<Integer> getTimestamp() {
return timestamp;
}
}
// send event thread
public class ClientConnection extends Thread {
Socket socket;
ObjectOutputStream out;
ObjectInputStream in;
Random rand = new Random();
public ClientConnection(Socket s) {
this.socket = s;
try {
out = new ObjectOutputStream (socket.getOutputStream());
in = new ObjectInputStream (socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
// execute the event
private void executeEvent(int from, Vector<Integer> x) {
int temp;
synchronized (timestamp) {
for (int i = 0; i < timestamp.size(); ++i) {
if (x.get(i) > timestamp.get(i)) {
timestamp.set(i, x.get(i));
}
}
temp = timestamp.get(from);
++temp;
timestamp.set(from, temp);
}
}
@Override
public void run () {
while (true) {
System.out.println("Reading events");
if (!isAlive) {
break;
}
try {
Event event = (Event) in.readObject();
executeEvent(event.getFromID(), event.getTimestamp());
} catch (ClassNotFoundException e) {
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(timestamp);
}
}
}
}
TL; DR Попытка чтения и записи объекта через сокеты с использованием объекта Stream (выход / вход) Stream. Когда я это делаю, я получаю NotSerializableException, хотя я реализовал интерфейс Serializable в классе, который записывался и читался из потока.
Вся помощь приветствуется!
(редактировать: stacktrace)
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: timetableexchange.Computer
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at timetableexchange.Computer$ClientConnection.run(Computer.java:239)
Caused by: java.io.NotSerializableException: timetableexchange.Computer
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at timetableexchange.Computer.<init>(Computer.java:128)
at timetableexchange.Computer.main(Computer.java:39)
java.io.NotSerializableException: timetableexchange.Computer
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at timetableexchange.Computer.<init>(Computer.java:128)
at timetableexchange.Computer.main(Computer.java:39)