RFR: 6441373: Editing JTable is not Serializable
Prasanta Sadhukhan
psadhukhan at openjdk.org
Wed Dec 10 03:41:24 UTC 2025
On Wed, 10 Dec 2025 02:36:47 GMT, Sergey Bylokhov <serb 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..
-------------
PR Comment: https://git.openjdk.org/jdk/pull/28627#issuecomment-3635217678
More information about the client-libs-dev
mailing list