RFR: 4938801: The popup does not go when the component is removed [v6]
Prasanta Sadhukhan
psadhukhan at openjdk.org
Wed Jul 30 05:14:58 UTC 2025
On Wed, 30 Jul 2025 04:41:41 GMT, Jeremy Wood <duke at 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
More information about the client-libs-dev
mailing list