Java - NotSerializableException on custom class - java

I have this code (sorry if I use some terms in Spanish) in Java. All is OK, until I need to write an object in a file with ObjectOutputStream, when printStackTrace says java.io.NotSerializableException.
The code is this.
package agenda;
import java.io.*;
public class Agenda implements java.io.Serializable {
public static void addContact() {
String nom, ap1, ap2, tf, em;
Contact newContact = new Contact("Nombre", "Apellido", "Apellido 2", "Telefono", "Email");
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("agenda.pzs", true)) {
oos.writeObject(newContact); // NetBeans says the error is here
} catch (IOException ex) {
ex.printStackTrace(); // This is provisional only
System.out.println("OcurriĆ³ un error inesperado.");
}
}
Sorry for my bad English.

public class Agenda implements java.io.Serializable {
public static void addContact() {
String nom, ap1, ap2, tf, em;
Contact newContact = new Contact("Nombre", "Apellido", "Apellido 2", "Telefono", "Email");
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("agenda.txt",true));
oos.writeObject(newContact);
oos.close();
} catch (IOException ex) {
ex.printStackTrace();
System.out.println("OcurriĆ³ un error inesperado.");
}
}
}
There is mistake with your bracket
and implement Serializable interface in Contact class

All objects inside Serializable class must be Serializable. this requirement is traversable - all objects below must be Serializable too..
BUT...
Assuming that Contact is a third party class or you are not allowed to modify it for any other reason, here is possible solution:
DISCLAIMER: this is tricky, if you don't know "Contact" class well it may cause many unexpected issues. You must make sure that you are able to read/write state of "Contact" class using Serializable blocks. Any change in Contact implementation must be tracked. You need a set of JUnit tests to verify if wrapper is correct.
Now get to the point:
Create ContactWrapper class that will disassemble "Contact" class to serializable class on write() and assemble this class from blocks during read(). More or less something like this:
import static org.junit.Assert.*;
import java.io.*;
import org.junit.Test;
public class Agenda {
#Test
public void addContact() throws ClassNotFoundException, FileNotFoundException, IOException {
String nom, ap1, ap2, tf, em;
Contact newContact = new Contact("Nombre", "Apellido", "Apellido 2", "Telefono", "Email");
ContactWrapper wrapper = new ContactWrapper();
wrapper.setContact(newContact);
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("agenda.pzs"));
oos.writeObject(wrapper);
} finally{
if(oos != null){
oos.close();
}
}
ObjectInputStream ois = null;
ContactWrapper wrapper_new = null;
try{
ois = new ObjectInputStream(new FileInputStream("agenda.pzs"));
wrapper_new = (ContactWrapper) ois.readObject();
} finally {
if(ois != null)
ois.close();
}
assertTrue(wrapper.equals(wrapper_new));
Contact deserializedContact = wrapper.getContact();
//Assuming that contact has corectly implemented equals()...
assertTrue(newContact.equals(deserializedContact));
}
}
================================================
import java.io.IOException;
import java.io.ObjectStreamException;
import java.io.Serializable;
public class ContactWrapper implements Serializable{
//assume not nulls here...-->equals
private String nom, ap1, ap2, tf, em;
public ContactWrapper(){
}
public void setContact(Contact contact){
//Get State of "Contact" and write it to Serializable objects
nom = contact.getNom();
ap1 = contact.getAp1();
//etc....
}
public Contact getContact(){
//create Contact from serialized objects
return new Contact(nom, ap1, ap2, tf, em);
}
private void writeObject(java.io.ObjectOutputStream out)
throws IOException{
System.out.println("write");
out.writeObject(nom);
out.writeObject(ap1);
out.writeObject(ap2);
out.writeObject(tf);
out.writeObject(em);
}
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException{
System.out.println("read");
nom = (String) in.readObject();
ap1 = (String) in.readObject();
ap2 = (String) in.readObject();
tf = (String) in.readObject();
em = (String) in.readObject();
}
private void readObjectNoData()
throws ObjectStreamException{
System.out.println("readNoData");
//set everything to null?
}
#Override
public boolean equals(Object other) {
if(this == other) return true;
if(other instanceof ContactWrapper){
ContactWrapper that = (ContactWrapper)other;
if(this.nom.equals(that.nom) &&
this.ap1.equals(that.ap1)
//...etc etc
){
return true;
}
}
return false;
}
}
Edit:
Source: http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html

Related

Appending to a Serialization file (Java)

I'm trying to append objects to a serialized file but when I read it, it only contains the most recent object instead of all of the objects:
import java.io.*;
public class Main implements Serializable {
public static void main(String[] args) throws IOException, ClassNotFoundException {
TestClass test = new TestClass();
test.username = "this one is second";
test.age = 23;
test.phone = "+1 (010) 000 0000";
test.address = "2 Main St.";
TestClass test2 = new TestClass();
test2.username = "this one is second 22222";
test2.age = 23;
test2.phone = "+1 (010) 000 0000";
test2.address = "2 Main St.";
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("C:\\Java Projects\\ObjectOutputStreamTests\\files\\test.ser"));
out.writeObject(test);
out.writeObject(test2);
out.close();
ObjectOutputStream out2 = new ObjectOutputStream(new FileOutputStream("C:\\Java Projects\\ObjectOutputStreamTests\\files\\test.ser", true)) {
#Override
protected void writeStreamHeader() throws IOException {
reset();
}
};
out2.writeObject(test);
out2.writeObject(test2);
out2.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("C:\\Java Projects\\ObjectOutputStreamTests\\files\\test.ser"));
try {
while ((in.readObject()) != null) {
TestClass testRead = (TestClass) in.readObject();
System.out.println(testRead.username);
System.out.println(testRead.age);
System.out.println(testRead.address);
System.out.println(testRead.phone);
}
} catch (EOFException e) {
System.out.println("end");
}
}
}
TestClass:
import java.io.Serializable;
public class TestClass implements Serializable {
public String username;
public int age;
public String phone;
public String address;
}
When I run this code, I get the second object (test2) printed twice, instead of the first and second object consecutively. This issue persists with more or less objects. How do I fix this?
You are reading the same Object twice for each iteration
while ((in.readObject()) != null) { // once
TestClass testRead = (TestClass) in.readObject(); // twice
You can change your code to
Object obj;
while ((obj = in.readObject()) != null) {
TestClass testRead = (TestClass) obj;
System.out.println(testRead.username);
System.out.println(testRead.age);
System.out.println(testRead.address);
System.out.println(testRead.phone);
}
Note
To get it to work I changed to
FileOutputStream f = new FileOutputStream("C:\\temp\\test.ser", true);
ObjectOutputStream out2 = new ObjectOutputStream(f)
{
#Override
protected void writeStreamHeader() throws IOException {
System.out.println("I am called");
reset();
}
}
;
out2.writeObject(test);
out2.writeObject(test2);
out2.close();

java howto load and save a ArrayList object

I've pair the code down to the methods I am having a problem, with. It 'seems' to work until I try to load the file again, and it comes up with nothing in it. (I have not fully understood how to clear the ArrayList before performing the 2nd load, but that is for later).
I am sorry if this is hidden somewhere under some other nomenclature I also have not learned yet, but this is a project that is due tomorrow and I am at my wit's end.
import java.util.*;
import java.io.*;
public class MainATM3 {
public static ArrayList<ClientAccount> accounts = new ArrayList<ClientAccount>();
public static ClientAccount editBankAccount = new ClientAccount("placeholder",1234,1);;
public static void main(String[] args) {
// Create ATM account ArrayList
ArrayList<ClientAccount> accounts = new ArrayList<ClientAccount>();
// Get Account data from files
initialLoadATMAccounts(accounts);
System.out.println("Loaded "+accounts.size());
System.out.println("before Array "+(accounts.size()));
accounts.add(0,new ClientAccount("Jess",500,1830));
accounts.add(1,new ClientAccount("Mary",1111.11,7890));
System.out.println("after Array "+(accounts.size()));
saveATMAccounts(accounts);
System.out.println("saved "+(accounts.size()));
initialLoadATMAccounts(accounts);
System.out.println("Loaded "+accounts.size());
System.out.println("Logged Out");
}
// Save ArrayList of ATM Objects //call by: saveATMAccounts(accounts);
public static void saveATMAccounts(ArrayList<ClientAccount> saveAccounts) {
FileOutputStream fout = null;
ObjectOutputStream oos = null;
try{
fout=new FileOutputStream("ATMAccounts.sav");
oos = new ObjectOutputStream(fout);
oos.writeObject(accounts);
System.out.println("objects written "+(accounts.size()));
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (fout != null) {
try {
fout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// INITIAL Load ArrayList of ATM Objects //call by: initialLoadATMAccounts(accounts);
public static void initialLoadATMAccounts(ArrayList<ClientAccount> loadAccounts){
FileInputStream fIS = null;
ObjectInputStream oIS = null;
try{
fIS=new FileInputStream("ATMAccounts.sav");
oIS = new ObjectInputStream(fIS);
ArrayList<ClientAccount> loadAccounts = (ArrayList<ClientAccount>) oIS.readObject();
oIS.close();
fIS.close();
}
catch(Exception exc){
exc.printStackTrace();
}
}
}
import java.io.Serializable;
public class ClientAccount implements Serializable {
public String accountName;
public double accountBalance;
public int accountPIN;
public ClientAccount(String accountName, double accountBalance, int accountPIN){
this.accountName=accountName;
this.accountBalance=accountBalance;
this.accountPIN=accountPIN;
}
// Account Name Methods
public String getAccountName() {
return accountName;
}
public void setAccountName(String name) {
accountName = name;
}
// Account Balance Methods
public double getAccountBalance() {
return accountBalance;
}
public void setAccountBalance(double balance) {
accountBalance = balance;
}
// PIN Methods
public int getAccountPIN() {
return accountPIN;
}
public void setAccountPIN(int newPIN) {
accountPIN = newPIN;
}
}
Instead of passing the desired array to initialLoadATMAccounts as param you should return the new, loaded array:
public static List<ClientAccount> initialLoadATMAccounts(){
FileInputStream fIS = null;
ObjectInputStream oIS = null;
try{
fIS=new FileInputStream("ATMAccounts.sav");
oIS = new ObjectInputStream(fIS);
ArrayList<ClientAccount> loadAccounts = (ArrayList<ClientAccount>) oIS.readObject();
oIS.close();
fIS.close();
return loadAccounts;
}
catch(Exception exc){
exc.printStackTrace();
}
}
BTW: A IDE like eclipse would have issued a warning where you overwrite the param loadAccounts.

NotSerializableException even after implementing Serializable

Recieving the error:
java.io.NotSerializableException
even after implementing Serializable.
I'm simply trying to serialize a Survey object. Here is my code, does anyone have an idea why I am receiving this error?
public void loadData(Survey survey, Test test, Boolean isSurvey) throws FileNotFoundException {
...
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName));
Survey s = (Survey) ois.readObject();
ois.close();
System.out.println("list size = " + s.questions);
} catch (Exception e) {
e.printStackTrace();
}
}
public void saveData(Survey survey, Test test, Boolean isSurvey, String fileName) {
...
if (isSurvey) {
try {
FileOutputStream fileOut = new FileOutputStream("surveys/" + fileName);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(survey);
out.close();
fileOut.close();
} catch (IOException ex) {
}
} else {
try {
FileOutputStream fileOut = new FileOutputStream("tests/" + fileName);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(test);
out.close();
fileOut.close();
} catch (IOException ex) {
}
}
}
EDIT: Added survey class. My Question class, Main class, and Input class both implement Serializable
package Survey;
import java.io.Serializable;
import java.util.ArrayList;
import IO.Input;
import Question.Question;
public class Survey implements Serializable{
private static final long serialVersionUID = 1L;
protected Main main = new Main();
protected Input input = new Input();
protected String name;
public ArrayList<Question> questions = new ArrayList<Question>();
public void setName() {
...
}
public void displayName() {
...
}
public void displayQuestions() {
...
}
public void mainMenu() {
...
}
public void addQuestionMenu() {
...
}
}

How to handle StreamCorruptedException when using ObjectInputStream? [duplicate]

This question already has an answer here:
StreamCorruptedException: invalid type code: AC
(1 answer)
Closed 5 years ago.
`I am new to java and getting StreamCorruptedException in the code below... In this code I am trying to read multiple objects from a file using ObjectInputStream... m not able to handle the StreamCorruptedException...the o/p I m getting is
File C098.txt already exists
Product ID:- P001
Description:- Book
Price:- Rs.200
Exception in thread "main" java.io.StreamCorruptedException: invalid type code:
AC
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1374)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at Utility.getProducts(Utility.java:57)
at Utility.main(Utility.java:23)
CODE:
import java.io.*;
import java.util.*;
class Product implements Serializable{
private static final long serialVersionUID = 1L;
String productId;
String desc;
String price;
public Product(String PId,String a_des,String a_price){
productId=PId;
desc=a_des;
price=a_price;
}
public String toString(){
return "Product ID:- "+productId+"\nDescription:- "+desc+"\nPrice:- "+price;
}
}
class Utility{
// Product objProduct;
public static void main(String args[]) throws Exception{
String cartId = "C098.txt";
Product objProduct = new Product("P001","Book","Rs.200");
addProductToCart(cartId,objProduct);
getProducts(cartId);
objProduct = new Product("P087","Laptop","Rs.45,500");
addProductToCart("C098.txt",objProduct);
getProducts(cartId);
}
public static void addProductToCart(String CId,Product p) throws Exception{
try{
boolean searchFile;
File objFile = new File(CId);
searchFile = objFile.exists();
if(searchFile)
System.out.println("File "+CId+" already exists");
else{
objFile.createNewFile();
System.out.println("File "+CId+" did not exist. It is now created");
}
FileOutputStream objFOS = new FileOutputStream(objFile,true);
ObjectOutputStream objO = new ObjectOutputStream(objFOS);
objO.writeObject(p);
objO.flush();
objO.close();
}catch(Exception e)
{
System.out.println("Exception Caught");
}
}
public static void getProducts(String CId) throws Exception{
Product objProduct1 = new Product("","","");
File objFile1 = new File(CId);
FileInputStream objFIS = new FileInputStream(objFile1);
ObjectInputStream objI = new ObjectInputStream(objFIS);
Object obj = null;
try{
while((obj=objI.readObject()) != null){
if (obj instanceof Product) {
System.out.println(((Product)obj).toString());
}
}
}catch (EOFException ex) { //This exception will be caught when EOF is reached
System.out.println("End of file reached.");
}finally {
//Close the ObjectInputStream
try{
if (objI != null)
objI.close();
}catch (IOException ex) {
ex.printStackTrace();
}
}
}
}`
The problem is because of header issue, You are appending to same file and while returning second object it throws exception because of headers issue. try to write object in different files, you can rid out of the problem.
SCE Thrown when control information that was read from an object stream violates internal consistency checks.
try
import java.io.*;
import java.util.*;
class Product implements Serializable{
private static final long serialVersionUID = 1L;
String productId;
String desc;
String price;
public Product(String PId,String a_des,String a_price){
productId=PId;
desc=a_des;
price=a_price;
}
public String toString(){
return "Product ID:- "+productId+"\nDescription:- "+desc+"\nPrice:- "+price;
}
// Product objProduct;
public static void main(String args[]) throws Exception{
String cartId = "C0982.txt";
Product objProduct = new Product("P001","Book","Rs.200");
addProductToCart(cartId,objProduct);
getProducts(cartId);
Product objProduct1 = new Product("P087","Laptop","Rs.45,500");
addProductToCart("C0981.txt",objProduct1);
getProducts("C0981.txt");
}
public static void addProductToCart(String CId,Product p) throws Exception{
try{
boolean searchFile;
File objFile = new File(CId);
searchFile = objFile.exists();
if(searchFile)
System.out.println("File "+CId+" already exists");
else{
objFile.createNewFile();
System.out.println("File "+CId+" did not exist. It is now created");
}
FileOutputStream objFOS = new FileOutputStream(objFile,true);
ObjectOutputStream objO = new ObjectOutputStream(objFOS);
objO.writeObject(p);
objO.flush();
objO.close();
}catch(Exception e)
{
System.out.println("Exception Caught");
}
}
public static void getProducts(String CId) throws Exception{
Product objProduct1 = new Product("","","");
File objFile1 = new File(CId);
FileInputStream objFIS = new FileInputStream(objFile1);
ObjectInputStream objI = new ObjectInputStream(objFIS);
Object obj = null;
try{
while((obj=objI.readObject()) != null){
if (obj instanceof Product) {
System.out.println(((Product)obj).toString());
}
}
}catch (EOFException ex) { //This exception will be caught when EOF is reached
System.out.println("End of file reached.");
}finally {
//Close the ObjectInputStream
try{
if (objI != null)
objI.close();
}catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
</pre>
You can't 'handle' it. You have to prevent it. It results from a design error such as using two ObjectOutputStreams on a stream that is read by a single ObjectInputStream, as you are doing here by appending to the file, or writing data other than objects and not reading it symmetrically.

Load/Store Objects in file in Java

I want to store an object from my class in file, and after that to be able to load the object from this file. But somewhere I am making a mistake(s) and cannot figure out where. May I receive some help?
public class GameManagerSystem implements GameManager, Serializable {
private static final long serialVersionUID = -5966618586666474164L;
HashMap<Game, GameStatus> games;
HashMap<Ticket, ArrayList<Object>> baggage;
HashSet<Ticket> bookedTickets;
Place place;
public GameManagerSystem(Place place) {
super();
this.games = new HashMap<Game, GameStatus>();
this.baggage = new HashMap<Ticket, ArrayList<Object>>();
this.bookedTickets = new HashSet<Ticket>();
this.place = place;
}
public static GameManager createManagerSystem(Game at) {
return new GameManagerSystem(at);
}
public boolean store(File f) {
try {
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(games);
oos.writeObject(bookedTickets);
oos.writeObject(baggage);
oos.close();
fos.close();
} catch (IOException ex) {
return false;
}
return true;
}
public boolean load(File f) {
try {
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
this.games = (HashMap<Game,GameStatus>)ois.readObject();
this.bookedTickets = (HashSet<Ticket>)ois.readObject();
this.baggage = (HashMap<Ticket,ArrayList<Object>>)ois.readObject();
ois.close();
fis.close();
} catch (IOException e) {
return false;
} catch (ClassNotFoundException e) {
return false;
}
return true;
}
.
.
.
}
public class JUnitDemo {
GameManager manager;
#Before
public void setUp() {
manager = GameManagerSystem.createManagerSystem(Place.ENG);
}
#Test
public void testStore() {
Game g = new Game(new Date(), Teams.LIONS, Teams.SHARKS);
manager.registerGame(g);
File file = new File("file.ser");
assertTrue(airport.store(file));
}
}
The solution of this problem is that when you are using other objects, let say class A, into a collection like HashMap and want to serialize the HashMap object, then implement the interface Serializable for class A like this:
class A implements Serializable {
}
...
HashMap<Integer,A> hmap;
...
Otherwise that object will not be serializable.
I hope it will solve this problem now.
Try oos.flush() before you close it.
Please remenber that the whole object graph is persisted during serialize. If you have some references to GUI classes for example, you either have to make them serializable, too, or tag them as "transient", so Java won't serialize them.

Categories

Resources