I'm also tired of writing the boilerplate in Java necessary to use a pipe. Here is a helper class, preceded by something that uses it:
private static <OBJECT_TYPE extends Serializable> OBJECT_TYPE copySerializable3(
final OBJECT_TYPE object) {
PipeHelper<OBJECT_TYPE> pipeHelper = new PipeHelper<OBJECT_TYPE>() {
@Override
protected void write(PipedOutputStream pipeOutput) throws Exception {
ObjectOutputStream objectOutput = new ObjectOutputStream(pipeOutput);
objectOutput.writeObject(object);
objectOutput.close();
}
@Override
protected OBJECT_TYPE read(PipedInputStream pipeInput) throws Exception {
ObjectInputStream objectInput = new ObjectInputStream(pipeInput);
@SuppressWarnings("unchecked")
OBJECT_TYPE copy = (OBJECT_TYPE) objectInput.readObject();
objectInput.close();
return copy;
}
};
try {
return pipeHelper.run();
} catch (Exception ex) {
throw new RuntimeException(String.format("Unable to copy the object '%s'", object), ex); //$NON-NLS-1$
}
}
abstract class PipeHelper<RESULT_TYPE> {
public RESULT_TYPE run() throws Exception {
final Exception[] writerException = { null };
final PipedInputStream pipeInput = new PipedInputStream();
try {
final PipedOutputStream pipeOutput = new PipedOutputStream(pipeInput);
try {
Thread writerThread = new Thread(this.getClass().getName()) {
@Override
public void run() {
try {
write(pipeOutput);
} catch (Exception ex) {
writerException[0] = ex;
}
}
};
writerThread.start();
try {
RESULT_TYPE result = read(pipeInput);
if (null != writerException[0]) {
throw writerException[0];
}
return result;
} finally {
writerThread.join();
}
} finally {
pipeOutput.close();
}
} finally {
pipeInput.close();
}
}
protected abstract RESULT_TYPE read(PipedInputStream pipeInput) throws Exception;
protected abstract void write(PipedOutputStream pipeOutput) throws Exception;
}