8039083: REGRESSION: closed/java/awt/dnd/DragSourceListenerSerializationTest/DragSourceListenerSerializationTest.html fails with NPE since 8u20 b07 on Linux
authorpchelko
Wed, 09 Apr 2014 15:20:09 +0400
changeset 24170 8db250c6c7e8
parent 24169 4efa892f600b
child 24171 9a263c3c482b
8039083: REGRESSION: closed/java/awt/dnd/DragSourceListenerSerializationTest/DragSourceListenerSerializationTest.html fails with NPE since 8u20 b07 on Linux Reviewed-by: serb, azvegint
jdk/src/share/classes/java/awt/dnd/DragSourceContext.java
jdk/test/java/awt/dnd/DragSourceListenerSerializationTest/DragSourceListenerSerializationTest.java
--- a/jdk/src/share/classes/java/awt/dnd/DragSourceContext.java	Wed Apr 09 14:38:27 2014 +0400
+++ b/jdk/src/share/classes/java/awt/dnd/DragSourceContext.java	Wed Apr 09 15:20:09 2014 +0400
@@ -576,9 +576,9 @@
             throw new InvalidObjectException("Null trigger component");
         }
 
-        int DGRActions = newTrigger.getSourceAsDragGestureRecognizer().getSourceActions()
+        int newSourceActions = f.get("sourceActions", 0)
                 & (DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK);
-        if (DGRActions == DnDConstants.ACTION_NONE) {
+        if (newSourceActions == DnDConstants.ACTION_NONE) {
             throw new InvalidObjectException("Invalid source actions");
         }
         int triggerActions = newTrigger.getDragAction();
@@ -591,8 +591,7 @@
 
         cursor = (Cursor)f.get("cursor", null);
         useCustomCursor = f.get("useCustomCursor", false);
-        sourceActions = f.get("sourceActions", 0)
-                & (DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK);
+        sourceActions = newSourceActions;
 
         transferable = (Transferable)s.readObject();
         listener = (DragSourceListener)s.readObject();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/dnd/DragSourceListenerSerializationTest/DragSourceListenerSerializationTest.java	Wed Apr 09 15:20:09 2014 +0400
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+  @test
+  @bug 4422345 8039083
+  @summary tests serialization of DragSourceListeners
+  @author das@sparc.spb.su area=dnd
+  @library ../../../../lib/testlibrary
+  @build jdk.testlibrary.Asserts
+  @run main/othervm DragSourceListenerSerializationTest
+*/
+
+import java.awt.Button;
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.Point;
+import java.awt.Toolkit;
+import java.awt.datatransfer.StringSelection;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DragGestureEvent;
+import java.awt.dnd.DragGestureRecognizer;
+import java.awt.dnd.DragSource;
+import java.awt.dnd.DragSourceAdapter;
+import java.awt.dnd.DragSourceContext;
+import java.awt.dnd.DragSourceListener;
+import java.awt.dnd.DragSourceMotionListener;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseEvent;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.TooManyListenersException;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static jdk.testlibrary.Asserts.assertEquals;
+
+public class DragSourceListenerSerializationTest {
+    public static void main(String[] args) throws Exception {
+        DragSource ds = new DragSource();
+        TestDragSourceAdapter dsa1 = new TestDragSourceAdapter(1);
+        TestDragSourceAdapter dsa2 = new TestDragSourceAdapter(2);
+        Component c = new Button();
+        DragGestureRecognizer dgr = ds.createDefaultDragGestureRecognizer(c,
+                DnDConstants.ACTION_COPY,
+                e -> e.startDrag(null, null));
+        MouseEvent me = new MouseEvent(c, MouseEvent.MOUSE_PRESSED, 0,
+                InputEvent.CTRL_MASK, 100, 100, 0, false);
+        DragGestureEvent dge = new DragGestureEvent(dgr, DnDConstants.ACTION_COPY,
+                new Point(100, 100),
+                Arrays.asList(me));
+        DragSourceContext dsc = new DragSourceContext(
+                Toolkit.getDefaultToolkit().createDragSourceContextPeer(dge),
+                dge,
+                new Cursor(Cursor.HAND_CURSOR),
+                null, null, new StringSelection("TEXT"), null);
+
+        ds.addDragSourceListener(dsa1);
+        ds.addDragSourceListener(dsa2);
+        ds.addDragSourceListener(dsa2);
+        ds.addDragSourceMotionListener(dsa1);
+        ds.addDragSourceMotionListener(dsa1);
+        ds.addDragSourceMotionListener(dsa2);
+        dsc.addDragSourceListener(dsa2);
+
+        byte[] serialized;
+        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
+             ObjectOutputStream oos = new ObjectOutputStream(bos)) {
+            oos.writeObject(dsc);
+            serialized = bos.toByteArray();
+        }
+
+        DragSourceContext dsc_copy;
+        try (ByteArrayInputStream bis = new ByteArrayInputStream(serialized);
+             ObjectInputStream ois = new ObjectInputStream(bis)) {
+            dsc_copy = (DragSourceContext) ois.readObject();
+        }
+
+        try {
+            dsc_copy.addDragSourceListener(dsa1);
+            throw new RuntimeException("Test failed. Listener addition succeeded");
+        } catch (TooManyListenersException ignored) {
+        }
+
+        try {
+            dsc_copy.addDragSourceListener(dsa2);
+            throw new RuntimeException("Test failed. Listener addition succeeded");
+        } catch (TooManyListenersException ignored) {
+        }
+
+        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
+             ObjectOutputStream oos = new ObjectOutputStream(bos)) {
+            oos.writeObject(ds);
+            serialized = bos.toByteArray();
+        }
+
+        DragSource ds_copy;
+        try (ByteArrayInputStream bis = new ByteArrayInputStream(serialized);
+             ObjectInputStream ois = new ObjectInputStream(bis)) {
+             ds_copy = (DragSource) ois.readObject();
+        }
+
+        DragSourceListener[] dsls = ds_copy.getDragSourceListeners();
+        assertEquals(3, dsls.length, "DragSourceListeners number");
+        assertEquals(1, Stream.of(dsls).filter(dsa1::equals).collect(Collectors.counting()).intValue());
+        assertEquals(2, Stream.of(dsls).filter(dsa2::equals).collect(Collectors.counting()).intValue());
+
+        DragSourceMotionListener[] dsmls = ds_copy.getDragSourceMotionListeners();
+        assertEquals(3, dsmls.length, "DragSourceMotionListeners number");
+        assertEquals(2, Stream.of(dsmls).filter(dsa1::equals).collect(Collectors.counting()).intValue());
+        assertEquals(1, Stream.of(dsmls).filter(dsa2::equals).collect(Collectors.counting()).intValue());
+    }
+}
+
+class TestDragSourceAdapter extends DragSourceAdapter implements Serializable {
+    final int id;
+
+    TestDragSourceAdapter(int id) {
+        this.id = id;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public boolean equals(Object obj) {
+        if (obj instanceof TestDragSourceAdapter) {
+            TestDragSourceAdapter tdsa = (TestDragSourceAdapter) obj;
+            return tdsa.getId() == getId();
+        }
+        return false;
+    }
+}