I get a java.io.NotSerializableException when I try to de-serialize a PullSheet object (classes below). Where am I going wrong?
EDIT: After adding an empty constructor to the problem class I am now getting an "incompatible" exception.
StackTrace:
java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:606)
java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1623)
java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1772)
java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
com.campusden.learning.movingdata.ScannerActivity.loadSheet(ScannerActivity.java:271)
com.campusden.learning.movingdata.ScannerActivity.onCreate(ScannerActivity.java:79)
android.app.Activity.performCreate(Activity.java:6679)
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
android.app.ActivityThread.-wrap12(ActivityThread.java)
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
android.os.Handler.dispatchMessage(Handler.java:102)
android.os.Looper.loop(Looper.java:154)
android.app.ActivityThread.main(ActivityThread.java:6119)
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
I am trying to serialize a PullSheet object so that a simple backup of data is stored and as a functional requirement for users. I am able to serialize the object without exception, but when I try to deserialize I get a java.io.NotSerializableException on the PullItem class.
PullSheet.java
import ...
public class PullSheet implements Serializable{
protected String pullerName;
protected String role;
protected String store;
protected String sheetId;
protected String runItId;
protected String date;
protected UUID uuid;
protected String serialName;
protected Long startTime = System.currentTimeMillis();
protected ArrayList<PullItem> SheetItems = new ArrayList<PullItem>();
public void createSheet(String _pullerName, String _role, String _store, String _runItId){
setPullerName(_pullerName);
setRole(_role);
setStore(_store);
setRunItId(_runItId);
setSerialName();
setDate();
setUuid();
setSheetId();
}
protected void addItem(String sku, Integer qty){
SheetItems.add(new PullItem(sku, qty));
}
protected void removeItem(PullItem item){
this.SheetItems.remove(item);
}
//Getters and setters
public String getPullerName(){ return pullerName; }
public String getRole(){ return role; }
public String getStore(){ return store; }
public String getRunItId(){ return runItId; }
public String getSheetId(){ return sheetId; }
public Long getStartTime(){ return startTime; }
public UUID getUuid() { return uuid; }
private void setPullerName(String _pullerName){ pullerName = _pullerName; }
private void setRole(String _role){ pullerName = _role; }
private void setStore(String _store){ store = _store; }
private void setRunItId(String _runItId){ runItId = _runItId; }
private void setSerialName(){ serialName = this.store + "-" + this.date + "_" + this.uuid; }
private void setUuid(){ uuid = UUID.randomUUID(); }
private void setDate() {
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
this.date = formatter.format(new Date(this.startTime));
}
private void setSheetId(){
String randUUID = uuid.toString();
sheetId = this.date + "-" + this.store + "-" + this.pullerName + "-" + randUUID + "-" + this.runItId;
}
}
PullItem.java
import ...
public class PullItem implements Serializable {
protected String sku;
protected Integer qty;
public PullItem(String sku, Integer qty) {
setSku(sku);
setQty(qty);
}
public PullItem(String sku) {
setSku(sku);
this.qty = 1;
}
String getSku(){
return sku;
}
Integer getQty(){
return qty;
}
void setSku(String _sku){
sku = _sku;
}
void setQty(Integer _qty){
qty = _qty;
}
void incrementQty(){
qty += 1;
}
}
The functions that serialize and deserialize the PullSheet object:
public static boolean saveSheet(Context context, PullSheet sheet){
String fileName = "saved.szs";
try {
FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
Log.d("rep", fileName);
oos.writeObject(sheet);
oos.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
public static PullSheet loadSheet(Context context, String fileName) {
try {
FileInputStream fis = context.openFileInput(fileName);
ObjectInputStream is = new ObjectInputStream(fis);
Object readObject = is.readObject();
is.close();
if(readObject != null && readObject instanceof PullSheet) {
return (PullSheet) readObject;
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
Please let me know where I'm going wrong. I assume it's not the types that are causing the exception because all the classes implement Serializable, but I could be off. Thanks in advance for any help
While the class may implement Serializable, that means every field[1] inside it has to be either:
Meaning for an instance UUID (a field in your class). Is that serializable? Every field you have in your class has to implement Serializable as well. If they don't implement serializable, they have to be transient
. If it is a static or final field, it doesn't have to be. Static and final fields aren't serialized anyways.
[1] : Every field means every field that is serializable. This excludes final and static fields, or fields that are marked transient
Working example:
(All fields mentioned are of importance, and are not static, final or transient for the purpose of this example)
Serializing Class1 would lead to an exception. Let us break this down quickly:
Because Class2 has a Context field (not serializable) and is serialized along with Class1 (because Class1 has a field of type Class2) you end up with an exception
It didn't implement Serializable
when you serialized it. You got an exception at that time. You fixed it to implement Serializable
. Then you tried to deserialize the old stream. It doesn't work.
EDIT
After adding an empty constructor to the problem class I am now getting an "incompatible" exception.
Because you changed the implicit serialVersionUID
. You don't need an empty constructor in a Serializable
class.
EDIT 2
Some folk here appear to be unaware that when you attempt to serialize a non-serializable object, a NotSerializableException
is (1) thrown and (2) written into the data stream in such a way that when you reach it when reading with readObject()
, it is thrown again, exactly as shown in the OP's stack trace.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.