RFR: 6441373: Editing JTable is not Serializable

Prasanta Sadhukhan psadhukhan at openjdk.org
Wed Dec 10 14:22:23 UTC 2025


On Wed, 10 Dec 2025 03:38:25 GMT, Prasanta Sadhukhan <psadhukhan at openjdk.org> wrote:

> > > I dont understand what you are trying to say. WHen JTable is serialized, writeObject also tries to serialize inner GenericEditor class (which is by default Serializable) which it fails to do..I dont see any other way of it being serialized..
> > 
> > 
> > writeObject only cares about the objects we pass to it, not the static inner classes. The fact that changing the constructor field helps indicates that an instance of the GenericEditor class still exists and is being referenced somewhere.
> > What is the full stack trace of the exception?
> 
> ```
> Caused by: java.io.NotSerializableException: java.lang.reflect.Constructor
>         at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1087)
>         at java.base/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1453)
>         at java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1410)
>         at java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1319)
>         at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1081)
>         at java.base/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1453)
>         at java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1410)
>         at java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1319)
>         at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1081)
>         at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:327)
>         at java.desktop/javax.swing.event.EventListenerList.writeObject(EventListenerList.java:286)
>         at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
>         at java.base/java.lang.reflect.Method.invoke(Method.java:565)
>         at java.base/java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:946)
>         at java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1397)
>         at java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1319)
>         at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1081)
>         at java.base/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1453)
>         at java.base/java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:414)
>         at java.desktop/javax.swing.JComponent.writeObject(JComponent.java:5632)
>         at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
>         at java.base/java.lang.reflect.Method.invoke(Method.java:565)
>         at java.base/java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:946)
>         at java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1397)
>         at java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1319)
>         at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1081)
>         at java.base/java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1262)
>         at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1077)
>         at java.base/java.io.ObjectOutputStream$PutFieldImpl.writeFields(ObjectOutputStream.java:1597)
>         at java.base/java.io.ObjectOutputStream.writeFields(ObjectOutputStream.java:455)
>         at java.desktop/java.awt.Container.writeObject(Container.java:3686)
>         at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
>         at java.base/java.lang.reflect.Method.invoke(Method.java:565)
>         at java.base/java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:946)
>         at java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1397)
>         at java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1319)
>         at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1081)
>         at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:327)
>         at EditingJTableNotSerializable.serialize(EditingJTableNotSerializable.java:45)
>         at EditingJTableNotSerializable.lambda$main$0(EditingJTableNotSerializable.java:60)
>         ... 9 more
> ```
> 
> It seems `JTable.editCellAt()` calls `getCellEditor()` which calls `getDefaultEditor()` which returns` javax.swing.JTable$GenericEditor` object which is then used to add a `cellEditorListener ` creating a JTable reference for the listener by calling ` editor.addCellEditorListener(this);`
> 
> and it is not removed unless `removeEditor()` is called which is not in this case.. Not sure if this is what holding the reference and causing GenericEditor to get serialized?
> 
> SInce `readObject()` again creates a GenericEditor via `createDefaultEditors()` the same editor and therefore this listener will not be used after serialization.. Probably we should remove this listener when we enter serialization for editing JTable but it seems it throws exception before calling `JTable.writeObject` so we cannot remove the listener there..so I think present fix is good enough to make it not serialized..

Fixed GenericEditor serialization

-------------

PR Comment: https://git.openjdk.org/jdk/pull/28627#issuecomment-3637309995


More information about the client-libs-dev mailing list