I am designing a distributed system which is persisting an ArrayList of stock to a file. I am writing stock to the file and upon reading that file, I receive a null pointer exception error.
This is a field in class A:
private static StockList instance = null;
This is my method getInstance(), in class A, which retrieves a list of stock from the file.
public static StockList getInstance(){
if (instance==null){
try {
XMLDecoder d = new XMLDecoder(
new BufferedInputStream(
new FileInputStream("Stock.xml")));
instance = (StockList) d.readObject();
d.close();
} catch (IOException ex) {
instance= new StockList();
Logger.getLogger(StockList.class.getName()).log(Level.SEVERE, null, ex);
}
}
return instance;
}
This is the class A constructor, it is called if there is an IOException in getInstance():
public StockList(){
stock.put("APL", new Stock("APL","Apple","Apple",3200));
System.out.println("");
}
This is my method writeStockList, in class A, which writes the stock to the file:
public void writeStockList()
{
try {
XMLEncoder e = new XMLEncoder(
new BufferedOutputStream(
new FileOutputStream("Stock.xml")));
e.writeObject(getInstance());
e.flush();
e.close();
} catch (IOException ex) {
Logger.getLogger(StockList.class.getName()).log(Level.SEVERE, null, ex);
}
}
This is my main method, in class B, which initialises the stocklist when the server is run:
public static void main(String[] args){
try {
//Make sure all lists are initialised
StockList.getInstance();
//delete after first run
//StockList.getInstance().addStock(new Stock("APL2","Apple2","Apple",3200));
//StockList.getInstance().writeStockList();
System.out.println(StockList.getInstance().getStock("APL" ).name);
System.out.println(StockList.getInstance().getStock("APL2" ).name);
System.out.println("registered ok");
} catch (RemoteException ex) {
Logger.getLogger(ClientServer.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("finished server setup");
}
For testing purposes, the first time running the program, the following lines are uncommented:
//StockList.getInstance().addStock(new Stock("APL2","Apple2","Apple",3200));
//StockList.getInstance().writeStockList();
This should add a new stock (APL2) to the list and write it to the file.
The following line, printed correctly - proving that both stocks were found:
System.out.println(StockList.getInstance().getStock("APL" ).name);
System.out.println(StockList.getInstance().getStock("APL2" ).name);
Then when we run a second time, the above lines are commented, however the above System.out.println throws the following error:
Exception in thread "main" java.lang.NullPointerException at food.stockticker.priceserver.ClientServer.main(ClientServer.java:46)
Java Result: 1
The above should not occur as the second item was written to the file and read back into the stocklist when getInstance() was called. If I print the first item (APL), it returns it. When APL2 is printed, an error occurs.
It seems as if the Stock.xml file was either overwritten or the changes made in the first run were not written to the xml file. Any ideas?
Edit:
The XML:
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.6.0_41" class="java.beans.XMLDecoder">
<object class="food.stockticker.priceserver.StockList"/>
</java>