I have a Trade
object with the code below and it implements the Serializable
interface but since it contains javafx properties , I get this java.io.NotSerializableException
and hence failed to properly do writeObject()
and readObject()
. My ultimate goal is to be able to write and read this object using ObjectOutputStream
and ObjectInputStream
I read the 3 links:
NotSerializableException on SimpleListProperty
Since my Trade
class is running a ScheduledService
to pick up the closing price from Google Finance, I know that I need to call startService()
within the readObject()
to ensure that when the readObject()
method is called and the object is deserialized, the thread will restart again.
Furthermore, I understand that I need to I need to define these 2 private methods within my Trade
Class.
private void writeObject(ObjectOutputStream out) throws IOException
{
out.defaultWriteObject();
// What else should I write in here?
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
{
// our "pseudo-constructor"
in.defaultReadObject();
// Not sure what else I need to write in here
// now we are a "live" object again, so let's run rebuild and start
startService();
}
Question: I have read the 3rd link above and I am still confused about what else should go into these two private methods above ?
Because my trade object has quite a lot of properties, but all it really needs
are just buySell,transactionDate,symbol, double volume, double price
to construct an object. Should I set the rest of the properties to transient
then?
public class Trade implements Serializable{
// properties
private Long creationTime;
private int counter;
private ObjectProperty<LocalDate> transactionDate;
private StringProperty symbol;
private StringProperty details;
private StringProperty buySell;
private DoubleProperty volume;
private DoubleProperty price;
private ReadOnlyDoubleWrapper transactionFee;
private final ReadOnlyDoubleWrapper closingPrice;
private final PauseTransition delay;
private ReadOnlyBooleanWrapper caution;
private final ScheduledService<webScraping> stockService = new ScheduledService<webScraping>() {
// web scrape google finance data
...
}
// constructor
public Trade(BuySell buySell, LocalDate transactionDate, String symbol, double volume, double price){
...
startService();
creationTime = Calendar.getInstance().getTimeInMillis();
}
// getters and setters and instance methods that return the properties themselves
public Long getCreationTime(){
return this.creationTime;
}
private Object writeReplace() {
return new TradeProxy(this);
}
private void readObject(ObjectInputStream stream)
throws InvalidObjectException {
throw new InvalidObjectException("Proxy required");
}
...
private static class TradeProxy implements Serializable{
private String buySell;
private LocalDate transactionDate;
private String stockTicker;
private double price;
private double volume;
private Long creationTime;
private TradeProxy(Trade trade){
this.buySell = trade.getBuySell();
this.transactionDate = trade.getTransactionDate();
this.stockTicker = trade.getStockTicker();
this.price = trade.getPrice();
this.volume = trade.getVolume();
this.creationTime = trade.getCreationTime();
}
private void writeObject(ObjectOutputStream s ) throws IOException{
s.defaultWriteObject();
}
private Object readResolve() throws ObjectStreamException{
return new Trade(this.buySell,this.transactionDate, this.symbol, this.volume, this.price);
}
}
}
UPDATE: I have updated my code. But since creationTime
is not an argument of the Trade
's constructor, I do not know how to serialize/deserialize it in my case. To be more precise, if I create a Trade
object at time say creationTime = 1443444301488
, I want this object be serialized and when I read in the object and deserialize it, I want to the creationTime to be exactly the same as what it was (i.e. 1443444301488) and I don't know how to achieve this. This is the problem that I am facing now.