This is a kind of an extension of my question here.
I have 3 classes.
My main:
import java.io.*;
public class ConnectionManager {
public static void main(String argv[]) {
try {
PipedOutputStream pout = new PipedOutputStream();
PipedInputStream pin = new PipedInputStream(pout);
Sender s = new Sender(pout,true);
Receiver r = new Receiver(pin,true);
System.out.println("Starting threads");
s.start();
r.start();
} catch (Exception e) {System.out.println(e);}
}
}
My Sender/Producer class:
import java.io.*;
public class Sender extends Thread {
ObjectOutputStream oos;
boolean primitive;
public Sender(OutputStream os, boolean primitive) {
try {
oos = new ObjectOutputStream(os);
this.primitive = primitive;
} catch (Exception e) {System.out.println(e);}
}
public void run() {
try {
System.out.println("Sending a message");
Thread.sleep(1000);
oos.writeInt(99);
oos.flush();
System.out.println("Message sent, terminating");
oos.close();
} catch (Exception e) {System.out.println("Sender: " + e);}
}
}
My Receiver/Consumer class:
import java.io.*;
public class Receiver extends Thread {
ObjectInputStream ois;
boolean primitive;
public Receiver(InputStream is, boolean primitive) {
try {
ois = new ObjectInputStream(is);
this.primitive = primitive;
} catch (Exception e) {System.out.println(e);}
}
public void run() {
try {
System.out.println("waiting for a message");
int x = ois.readInt();
System.out.println("message received: " + x);
ois.close();
} catch (Exception e) {System.out.println("Receiver: " + e);}
}
}
Produces this output:
Starting threads
Sending a message
waiting for a message
Receiver: java.io.IOException: Write end dead
Sender: java.io.IOException: Read end dead
I read in this page that I'm getting these exceptions because I wasn't closing the pipes. But even if I do, I still get them. How can I fix this?
edit: the reason I'm casting the type of the stream objects from, say, PipedInputStream to InputStream and then constructing a new ObjectInputStream using InputStream is because I want to be able to send and receive data of various types, not just int or bytes.
I stay corrected; and following the advise by EJP; here is a working solution.
import java.io.*;
public class ConnectionManager {
public static void main(String argv[]) throws Exception {
PipedOutputStream pout = new PipedOutputStream();
PipedInputStream pin = new PipedInputStream(pout);
Sender s = new Sender(pout);
Receiver r = new Receiver(pin);
System.out.println("Starting threads");
s.start();
r.start();
}
}
class Sender extends Thread {
private final OutputStream os;
Sender(OutputStream os) { this.os = os; }
public void run() {
try(ObjectOutputStream oos = new ObjectOutputStream(os)) {
oos.writeInt(99);
System.out.println("Message sent, terminating");
} catch (Exception e) {
System.out.println("Sender: " + e);
e.printStackTrace();
}
}
}
class Receiver extends Thread {
private final InputStream is;
Receiver(InputStream is) {this.is = is; }
public void run() {
try(ObjectInputStream ois = new ObjectInputStream(is)) {
System.out.println("waiting for a message");
int x = ois.readInt();
System.out.println("message received: " + x);
} catch (Exception e) {
System.out.println("Receiver: " + e);
e.printStackTrace();
}
}
}
Should print:
Starting threads
Message sent, terminating
waiting for a message
message received: 99
Notes: the core point is to create the ObjectInputStreams within the run methods. Beyond that: removed the things not necessary (that boolean primitive; but added try-with-resources and printing stack traces).