On Wed, 30 Jul 2025 04:41:41 GMT, Jeremy Wood <[email protected]> wrote:
>> It is transient so its value should not be included in the default
>> serialization process in my opinion
>
> I'm fine with `propListener` being transient ... as long as when we call
> readObject() we still initialize `propListener`.
>
> Here's a unit test that demonstrates what I'm worried about:
>
> import javax.swing.*;
> import java.beans.PropertyChangeListener;
> import java.io.*;
>
> public class JPopupMenuSerializationTest {
> static class JPopupMenuSubclass extends JPopupMenu implements
> Serializable {
> private transient PropertyChangeListener propListener =
> (e) -> {
> if (e.getOldValue() != null
> && e.getNewValue() == null
> && isVisible()) {
> setVisible(false);
> }
> };
>
> @Serial
> private void writeObject(ObjectOutputStream s) throws IOException {
> Object serializable = propListener instanceof Serializable ?
> (Serializable) propListener : null;
> System.out.println("Serialized: " + serializable);
> s.writeObject(serializable);
> }
>
> @Serial
> private void readObject(ObjectInputStream s)
> throws IOException, ClassNotFoundException {
> PropertyChangeListener l = (PropertyChangeListener)
> s.readObject();
> System.out.println("Deserialized: " + l);
> if (l != null) {
> propListener = l;
> }
> System.out.println("propListener: " + propListener);
> }
> }
>
> public static void main(String[] args) throws Exception {
> JPopupMenuSerializationTest test = new JPopupMenuSerializationTest();
> test.testSerialization();
> }
>
> public void testSerialization() throws Exception {
> JPopupMenuSubclass popupMenu = new JPopupMenuSubclass();
> byte[] data = serialize(popupMenu);
> JPopupMenuSubclass copy = deserialize(data);
>
> assertTrue("original.propListener should exist",
> popupMenu.propListener != null);
>
> // currently this fails, and IMO it should pass:
> assertTrue("copy.propListener should exist", copy.propListener !=
> null);
> }
>
> private static void assertTrue(String errorMsg, boolean b) {
> if (!b)
> throw new Error(errorMsg);
> }
>
> private static byte[] serialize(JPopupMenuSubclass popupMenu) throws
> IOException {
> try (ByteArrayOutputStream byteOut = new ByteArrayOutputStream()) {
> try (ObjectOutputStream objOut = new ObjectOutputStream(byteOut))
> {
> objO...
Hmm..We need to take a look at how to handle serialization aspect of
propListener
but as per
https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html#serialization
> You can serialize a lambda expression if its target type and its captured
> arguments are serializable. However, like inner classes, the serialization of
> lambda expressions is strongly discouraged.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/26407#discussion_r2241547175