1

I have a serialization problem and am unable to find the cause. It's an Android app in Eclipse that's giving me a very unhelpful stack trace like this:

09-01 00:06:24.414: W/System.err(9961): java.io.NotSerializableException: com.myprogram.main.Entity$1
09-01 00:06:24.414: W/System.err(9961):     at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1344)
09-01 00:06:24.414: W/System.err(9961):     at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651)
09-01 00:06:24.414: W/System.err(9961):     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)
09-01 00:06:24.414: W/System.err(9961):     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)
09-01 00:06:24.415: W/System.err(9961):     at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:959)
09-01 00:06:24.415: W/System.err(9961):     at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:360)
09-01 00:06:24.415: W/System.err(9961):     at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1054)
09-01 00:06:24.415: W/System.err(9961):     at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1384)
09-01 00:06:24.415: W/System.err(9961):     at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651)
09-01 00:06:24.415: W/System.err(9961):     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)
09-01 00:06:24.415: W/System.err(9961):     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)

Having found Java flag to enable extended Serialization debugging info I decided to set

-Dsun.io.serialization.extendedDebugInfo=true

Following How can I specify the default JVM arguments for programs I run from eclipse? I plugged the flag into the VM argument for my JRE, but the stack trace did not change. Rebooting Eclipse did not help. So following Editing the vm args of eclipse I added the flag to my eclipse.ini, but still the stack trace is unchanged. I'm expecting an output that looks something like java.io.NotSerializableException – but where is the field?.

I get it that com.myprogram.main.Entity$1 is not serializable. That's easy. The question is why? Any suggestions as to how I might figure out this java.io.NotSerializableException?

Community
  • 1
  • 1
Mark Cramer
  • 2,614
  • 5
  • 33
  • 57
  • 4
    It's pretty simple: you have an anonymous class `com.myprogram.main.Entity$1` that isn't `Serializable.` You don't need extended debugging for that. – user207421 Sep 01 '15 at 08:07
  • Thank you, but I don't understand. I have `public abstract class Entity implements Serializable {...}`. `java.io.ObjectOutputStream.writeObject(Object object)` used to work, but since then I've made a lot of changes and now I get the error. I believe that something I've changed has made my class "not serializeable" so I'm trying to debug to track that down. – Mark Cramer Sep 01 '15 at 15:08
  • Additionally, I read that the `$1` generally refers to a problem with an inner class. I don't have any inner classes! Another reason I'm trying to turn on extended debugging. – Mark Cramer Sep 01 '15 at 16:18
  • Fixed. I didn't realize a `Runnable()` was an inner class. Your title is completely unhelpful to anyone researching this problem in the future. I will fix again. – Mark Cramer Sep 03 '15 at 16:30
  • 1
    A `Runnable` *isn't* an inner class. An anonymous inner class that *implements* `Runnable` is an anonymous inner class. Same if it implements any other interface, or extends any other class, or even if it doesn't. Nothing to do with `Runnable` *per se* whatsoever. Delighted you found an even better title, after a battle. – user207421 Sep 05 '15 at 10:10
  • Ah, I got it now. It's generally `new Object() {};`. – Mark Cramer Sep 05 '15 at 19:50

2 Answers2

5

You have an anonymous inner class com.myprogram.main.Entity$1 that isn't Serializable. This is clearly stated in the exception. The $ indicates that it's an inner or static nested class that produced the exception. The digit after the $ indicates that the class is anonymous, otherwise the name of the inner class would be present here. The 1 further indicates that this is the first anonymous inner class within com.myprogram.main.Entity.

See How can I identify an anonymous inner class in a NotSerializableException for more.

Community
  • 1
  • 1
user207421
  • 305,947
  • 44
  • 307
  • 483
  • This answer cannot be accepted because the exception does **not** clearly state that the problem is an anonymous inner class. In fact, nowhere in the exception can one find any of the words "anonymous", "inner" or "class". If the exception clearly stated that the problem was an anonymous inner class then it might have been "pretty simple" and I probably would not have needed to post this question. An acceptable answer to this question must indicate how one would know that the problem is an anonymous inner class from an exception that does **not** state that clearly at all. – Mark Cramer Sep 05 '15 at 19:46
-1

To work around java.io.NotSerializableException with a non-serializable anonymous inner class you can remove the anonymity and instantiate an object when necessary, which removes the need to serialize the class.

Rather than this:

class Entity implements Serializable {
  public static void main(String[] args) {
    new Object() { }; // Entity$1 <- anonymous inner class
  }
}

Do this:

class Entity implements Serializable {
  public static void main(String[] args) {
    private class MyClass { } // Entity$MyClass <- inner class
  }
}

If you need to serialize the MyClass objects then you still have a problem (you can make them transient to solve this), but if you don't need to (e.g. they're Runnables) then just instantiate when required like this:

class Entity implements Serializable {
  public static void main(String[] args) {
    ...
    myHandler = new Handler();
    myHandler.postDelayed(new MyRunnable(), 1000);
    ...
    private class MyRunnable implements java.lang.Runnable {
      // runnable code
    }
  }
}
Mark Cramer
  • 2,614
  • 5
  • 33
  • 57