On Wed, 30 Jul 2025 04:41:41 GMT, Jeremy Wood <d...@openjdk.org> 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