ObjectInputStreamからオブジェクトを読み取るときにClassNotFoundExceptionが発生します。送信されているオブジェクトは、読み取りコードが参照している「WorkUnit」をサブクラス化しています。受信側は特定の実装について知らないため、不平を言っているように見えます。オブジェクトのスーパークラス、つまり受信側の「WorkUnit」のみを参照しているのに、なぜそれを気にするのでしょうか。
ストリームから読み取るコード:
private Object readObject() {
Object object = null;
try {
object = objectIn.readObject();
} catch (SocketException | EOFException e) {
// Socket was forcedly closed. Probably means client was
// disconnected
System.out.println("[NetworkHandler] SOCKET CLOSED");
shouldContinue = false;
if (!isClient)
server.clientDisconnected(clientID);
} catch (ClassNotFoundException | IOException e) {
// If shouldContinue is true, we haven't said that we want to close
// the connection
if (shouldContinue) {
e.printStackTrace();
System.err
.println("[NetworkHandler] Error: Couldn't read object correctly");
}
}
return object;
}
ワークユニットの実装:
import java.util.LinkedList;
import java.util.List;
import Application.WorkUnit;
public class WorkUnitImplementation extends WorkUnit<Integer, Integer> {
private static final int INPUT_LENGTH = 1000;
public WorkUnitImplementation() {
super();
setInputLength(INPUT_LENGTH);
}
@Override
public Integer doWork(Integer input) {
wait(50);
return (input % 2 == 1) ? input : null;
}
@Override
public List<Integer> inputFactory(int begin, int end) {
List<Integer> result = new LinkedList<>();
for (int i = begin; i < end; i++) {
result.add(i);
}
return result;
}
private void wait(int time) {
try {
Thread.sleep(time);
} catch (Exception e) {
}
}
}
ワークユニットを送信するコード:
public void uploadWorkUnit(WorkUnit workUnit) {
try {
objectOut.writeObject(new UploadWorkUnit(workUnit));
objectOut.flush();
System.out.println("[NetworkHandler] Uploaded workUnit");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
例外トレース:
java.lang.ClassNotFoundException: WorkUnitImplementation
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:622)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1593)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1514)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at Networking.NetworkHandler.readObject(NetworkHandler.java:188)
at Networking.NetworkHandler.run(NetworkHandler.java:90)
at java.lang.Thread.run(Thread.java:722)
[NetworkHandler]エラー:オブジェクトを正しく読み取ることができませんでした