diff --git a/test/jdk/java/awt/Toolkit/ToolkitListenerTest/ToolkitListenerTest.java b/test/jdk/java/awt/Toolkit/ToolkitListenerTest/ToolkitListenerTest.java
new file mode 100644
index 0000000000000..3d7b6df2cba43
--- /dev/null
+++ b/test/jdk/java/awt/Toolkit/ToolkitListenerTest/ToolkitListenerTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2001, 2023, 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 4460376
+ @summary we should create Component-, Container- and HierarchyEvents if
+ appropriate AWTEventListener added on Toolkit
+ @key headful
+*/
+
+import java.awt.AWTEvent;
+import java.awt.Button;
+import java.awt.EventQueue;
+import java.awt.Frame;
+import java.awt.Toolkit;
+import java.awt.event.AWTEventListener;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ContainerEvent;
+import java.awt.event.HierarchyEvent;
+import java.lang.reflect.InvocationTargetException;
+
+public class ToolkitListenerTest implements AWTEventListener
+{
+ public static Frame frame;
+ static boolean containerEventReceived = false;
+ static boolean componentEventReceived = false;
+ static boolean hierarchyEventReceived = false;
+ static boolean hierarchyBoundsEventReceived = false;
+
+ public static void main(String[] args) throws Exception {
+ ToolkitListenerTest test = new ToolkitListenerTest();
+ test.start();
+ }
+ public void start() throws Exception {
+ Toolkit.getDefaultToolkit().
+ addAWTEventListener(this,
+ AWTEvent.COMPONENT_EVENT_MASK |
+ AWTEvent.CONTAINER_EVENT_MASK |
+ AWTEvent.HIERARCHY_EVENT_MASK |
+ AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
+ EventQueue.invokeAndWait(() -> {
+ frame = new Frame("ToolkitListenerTest");
+ frame.setSize(200, 200);
+ frame.add(new Button());
+ frame.setBounds(100, 100, 100, 100);
+ });
+ try {
+ Toolkit.getDefaultToolkit().getSystemEventQueue().
+ invokeAndWait(new Runnable() {
+ public void run() {}
+ });
+
+ EventQueue.invokeAndWait(() -> {
+ if (!componentEventReceived) {
+ throw new RuntimeException("Test Failed: ComponentEvent " +
+ "was not dispatched");
+ }
+ if (!containerEventReceived) {
+ throw new RuntimeException("Test Failed: ContainerEvent " +
+ "was not dispatched");
+ }
+ if (!hierarchyEventReceived) {
+ throw new RuntimeException("Test Failed: " +
+ "HierarchyEvent(HIERARCHY_CHANGED) was not dispatched");
+ }
+ if (!hierarchyBoundsEventReceived) {
+ throw new RuntimeException("Test Failed: " +
+ "HierarchyEvent(ANCESTOR_MOVED or ANCESTOR_RESIZED) " +
+ "was not dispatched");
+ }
+ });
+ } catch (InterruptedException ie) {
+ throw new RuntimeException("Test Failed: InterruptedException " +
+ "accured.");
+ } catch (InvocationTargetException ite) {
+ throw new RuntimeException("Test Failed: " +
+ "InvocationTargetException accured.");
+ } finally {
+ EventQueue.invokeAndWait(() -> {
+ if (frame != null) {
+ frame.dispose();
+ }
+ });
+ }
+ }
+
+ public void eventDispatched(AWTEvent e) {
+ System.err.println(e);
+ if (e instanceof ContainerEvent) {
+ containerEventReceived = true;
+ } else if (e instanceof ComponentEvent) {
+ componentEventReceived = true;
+ } else if (e instanceof HierarchyEvent) {
+ switch (e.getID()) {
+ case HierarchyEvent.HIERARCHY_CHANGED:
+ hierarchyEventReceived = true;
+ break;
+ case HierarchyEvent.ANCESTOR_MOVED:
+ case HierarchyEvent.ANCESTOR_RESIZED:
+ hierarchyBoundsEventReceived = true;
+ break;
+ }
+ }
+ }
+}
diff --git a/test/jdk/java/awt/datatransfer/CRLFTest/CRLFTest.java b/test/jdk/java/awt/datatransfer/CRLFTest/CRLFTest.java
new file mode 100644
index 0000000000000..c61791d13fa96
--- /dev/null
+++ b/test/jdk/java/awt/datatransfer/CRLFTest/CRLFTest.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2003, 2023, 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 4914613
+ @summary tests that "\r\n" is not converted to "\r\r\n"
+ @key headful
+*/
+
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.ClipboardOwner;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.StringSelection;
+import java.awt.datatransfer.SystemFlavorMap;
+import java.awt.datatransfer.Transferable;
+import java.io.File;
+import java.io.InputStream;
+
+public class CRLFTest {
+ private int returnCode = 0;
+
+ public static void main(String[] args) {
+ CRLFTest parent = new CRLFTest();
+ parent.start();
+ }
+ public void start() {
+
+ try {
+ String javaPath = System.getProperty("java.home", "");
+ String command = javaPath + File.separator + "bin" +
+ File.separator + "java -cp " +
+ System.getProperty("test.classes", ".") +
+ " CRLFTestClipboard";
+
+ Process process = Runtime.getRuntime().exec(command);
+ ProcessResults pres = ProcessResults.doWaitFor(process);
+ returnCode = pres.exitValue;
+
+ if (pres.stderr != null && pres.stderr.length() > 0) {
+ System.err.println("========= Child VM System.err ========");
+ System.err.print(pres.stderr);
+ System.err.println("======================================");
+ }
+
+ if (pres.stdout != null && pres.stdout.length() > 0) {
+ System.err.println("========= Child VM System.out ========");
+ System.err.print(pres.stdout);
+ System.err.println("======================================");
+ }
+
+ System.err.println("Child return code=" + returnCode);
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+}
+
+class CRLFTestClipboard implements ClipboardOwner {
+ private static final Clipboard clipboard =
+ Toolkit.getDefaultToolkit().getSystemClipboard();
+
+ public static void main(String[] args) {
+ CRLFTestClipboard child = new CRLFTestClipboard();
+ child.run();
+ }
+
+ public void run() {
+ ClipboardOwner owner = new ClipboardOwner() {
+ public void lostOwnership(Clipboard clipboard,
+ Transferable contents) {
+ System.exit(0);
+ }
+ };
+ clipboard.setContents(new StringSelection("\r\n"), owner);
+
+ // Wait to let the parent retrieve the contents.
+ try {
+ Thread.sleep(30000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void lostOwnership(Clipboard clip, Transferable contents) {
+ final DataFlavor df =
+ new DataFlavor("text/test-subtype; class=java.io.InputStream",
+ null);
+ SystemFlavorMap sfm =
+ (SystemFlavorMap)SystemFlavorMap.getDefaultFlavorMap();
+ sfm.addUnencodedNativeForFlavor(df, "TEXT");
+ sfm.addFlavorForUnencodedNative("TEXT", df);
+ Runnable r = new Runnable() {
+ public void run() {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ Transferable t = clipboard.getContents(null);
+ boolean passed = true;
+ try {
+ InputStream is =
+ (InputStream)t.getTransferData(df);
+ int prev = 0;
+ int b = 0;
+ System.err.print("Bytes: ");
+ while ((b = is.read()) != -1) {
+ System.err.print(" " + Integer.
+ toHexString((int)b & 0xFF));
+ if (b == 0xD && prev == 0xD) {
+ passed = false;
+ }
+ prev = b;
+ }
+ System.err.println();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ clipboard.setContents(new StringSelection(""), null);
+
+ if (!passed) {
+ throw new RuntimeException("Test failed");
+ }
+ }
+ };
+ new Thread(r).start();
+ }
+}
+
+class ProcessResults {
+ public int exitValue;
+ public String stdout;
+ public String stderr;
+
+ public ProcessResults() {
+ exitValue = -1;
+ stdout = "";
+ stderr = "";
+ }
+
+ /**
+ * Method to perform a "wait" for a process and return its exit value.
+ * This is a workaround for Process.waitFor()
never returning.
+ */
+ public static ProcessResults doWaitFor(Process p) {
+ ProcessResults pres = new ProcessResults();
+
+ InputStream in = null;
+ InputStream err = null;
+
+ try {
+ in = p.getInputStream();
+ err = p.getErrorStream();
+
+ boolean finished = false;
+
+ while (!finished) {
+ try {
+ while (in.available() > 0) {
+ pres.stdout += (char)in.read();
+ }
+ while (err.available() > 0) {
+ pres.stderr += (char)err.read();
+ }
+ // Ask the process for its exitValue. If the process
+ // is not finished, an IllegalThreadStateException
+ // is thrown. If it is finished, we fall through and
+ // the variable finished is set to true.
+ pres.exitValue = p.exitValue();
+ finished = true;
+ }
+ catch (IllegalThreadStateException e) {
+ // Process is not finished yet;
+ // Sleep a little to save on CPU cycles
+ Thread.currentThread().sleep(500);
+ }
+ }
+ if (in != null) in.close();
+ if (err != null) err.close();
+ }
+ catch (Throwable e) {
+ System.err.println("doWaitFor(): unexpected exception");
+ e.printStackTrace();
+ }
+ return pres;
+ }
+}
diff --git a/test/jdk/java/awt/datatransfer/DataConversionDeadlockTest/DataConversionDeadlockTest.java b/test/jdk/java/awt/datatransfer/DataConversionDeadlockTest/DataConversionDeadlockTest.java
new file mode 100644
index 0000000000000..e1257a4e99ff8
--- /dev/null
+++ b/test/jdk/java/awt/datatransfer/DataConversionDeadlockTest/DataConversionDeadlockTest.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2002, 2023, 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 4760364
+ @summary Tests that the deadlock doesn't happen when two apps request
+ selection data from each other.
+ @key headful
+*/
+
+import java.awt.EventQueue;
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.ClipboardOwner;
+import java.awt.datatransfer.StringSelection;
+import java.awt.datatransfer.Transferable;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class DataConversionDeadlockTest {
+
+ public static void main(String[] args) {
+ DataConversionDeadlockTest parent = new DataConversionDeadlockTest();
+ parent.start();
+ }
+
+ public void start() {
+ try {
+ String javaPath = System.getProperty("java.home", "");
+ String cmd = javaPath + File.separator + "bin" +
+ File.separator + "java -cp " +
+ System.getProperty("test.classes", ".") +
+ " DataConversionDeadlockTestChild";
+
+ Process process = Runtime.getRuntime().exec(cmd);
+ ProcessResults pres = ProcessResults.doWaitFor(process);
+
+ if (pres.stderr != null && pres.stderr.length() > 0) {
+ System.err.println("========= Child VM System.err ========");
+ System.err.print(pres.stderr);
+ System.err.println("======================================");
+ }
+
+ if (pres.stdout != null && pres.stdout.length() > 0) {
+ System.err.println("========= Child VM System.out ========");
+ System.err.print(pres.stdout);
+ System.err.println("======================================");
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
+
+class DataConversionDeadlockTestChild implements ClipboardOwner, Runnable {
+ private static final Toolkit toolkit = Toolkit.getDefaultToolkit();
+ private static final Clipboard clipboard = toolkit.getSystemClipboard();
+ private static final Clipboard selection = toolkit.getSystemSelection();
+ private static final Transferable t = new StringSelection("TEXT");
+
+ public void lostOwnership(Clipboard cb, Transferable contents) {
+ ClipboardUtil.setClipboardContents(selection, t, this);
+ new Thread(this).start();
+ }
+
+ public void run() {
+ for (int i = 0; i < 100; i++) {
+ EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ ClipboardUtil.getClipboardContents(clipboard, null);
+ }
+ });
+ }
+ }
+
+ public static void main(String[] args) {
+ if (clipboard == null || selection == null) {
+ return;
+ }
+ ClipboardUtil.setClipboardContents(clipboard, t, null);
+ for (int i = 0; i < 100; i++) {
+ EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ ClipboardUtil.getClipboardContents(selection, null);
+ }
+ });
+ }
+ }
+}
+
+class ClipboardUtil {
+ public static void setClipboardContents(Clipboard cb,
+ Transferable contents,
+ ClipboardOwner owner) {
+ synchronized (cb) {
+ boolean set = false;
+ while (!set) {
+ try {
+ cb.setContents(contents, owner);
+ set = true;
+ } catch (IllegalStateException ise) {
+ try { Thread.sleep(100); }
+ catch (InterruptedException e) { e.printStackTrace(); }
+ }
+ }
+ }
+ }
+
+ public static Transferable getClipboardContents(Clipboard cb,
+ Object requestor) {
+ synchronized (cb) {
+ while (true) {
+ try {
+ Transferable t = cb.getContents(requestor);
+ return t;
+ } catch (IllegalStateException ise) {
+ try { Thread.sleep(100); }
+ catch (InterruptedException e) { e.printStackTrace(); }
+ }
+ }
+ }
+ }
+}
+
+class ProcessResults {
+ public int exitValue;
+ public String stdout;
+ public String stderr;
+
+ public ProcessResults() {
+ exitValue = -1;
+ stdout = "";
+ stderr = "";
+ }
+
+ /**
+ * Method to perform a "wait" for a process and return its exit value.
+ * This is a workaround for Process.waitFor()
never returning.
+ */
+ public static ProcessResults doWaitFor(Process p) {
+ ProcessResults pres = new ProcessResults();
+
+ InputStream in = null;
+ InputStream err = null;
+
+ try {
+ in = p.getInputStream();
+ err = p.getErrorStream();
+
+ boolean finished = false;
+
+ while (!finished) {
+ try {
+ while (in.available() > 0) {
+ pres.stdout += (char)in.read();
+ }
+ while (err.available() > 0) {
+ pres.stderr += (char)err.read();
+ }
+ // Ask the process for its exitValue. If the process
+ // is not finished, an IllegalThreadStateException
+ // is thrown. If it is finished, we fall through and
+ // the variable finished is set to true.
+ pres.exitValue = p.exitValue();
+ finished = true;
+ }
+ catch (IllegalThreadStateException e) {
+ // Process is not finished yet;
+ // Sleep a little to save on CPU cycles
+ Thread.currentThread().sleep(500);
+ }
+ }
+ if (in != null) in.close();
+ if (err != null) err.close();
+ }
+ catch (Throwable e) {
+ System.err.println("doWaitFor(): unexpected exception");
+ e.printStackTrace();
+ }
+ return pres;
+ }
+}
diff --git a/test/jdk/java/awt/datatransfer/DataFlavor/BestTextFlavorTest/BestTextFlavorTest.java b/test/jdk/java/awt/datatransfer/DataFlavor/BestTextFlavorTest/BestTextFlavorTest.java
new file mode 100644
index 0000000000000..81558d23ad820
--- /dev/null
+++ b/test/jdk/java/awt/datatransfer/DataFlavor/BestTextFlavorTest/BestTextFlavorTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2008, 2023, 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
+ @summary To test if the DataFlavor.selectBestTextFlavor() method
+ is selecting the correct best flavor from an array of flavors.
+*/
+
+
+import java.awt.datatransfer.DataFlavor;
+import java.util.Vector;
+
+public class BestTextFlavorTest {
+ public static DataFlavor plainISOFlavor,
+ plainAsciiFlavor,
+ plainTextFlavor,
+ enrichFlavor;
+ public static DataFlavor[] bestFlavorArray1;
+ public static DataFlavor[] bestFlavorArray2;
+ public static DataFlavor bestFlavor1,bestFlavor2;
+ private static Vector tmpFlavors;
+
+ //Creating new flavors
+ static {
+
+ tmpFlavors = new Vector();
+ try {
+ tmpFlavors.addElement(DataFlavor.stringFlavor);
+ tmpFlavors.addElement(new DataFlavor
+ ("text/plain; charset=unicode"));
+ tmpFlavors.addElement(
+ new DataFlavor("text/plain; charset=us-ascii"));
+ enrichFlavor=new DataFlavor("text/enriched; charset=ascii");
+ tmpFlavors.addElement(enrichFlavor);
+ plainTextFlavor=DataFlavor.getTextPlainUnicodeFlavor();
+ tmpFlavors.addElement(plainTextFlavor);
+ plainAsciiFlavor=new DataFlavor("text/plain; charset=ascii");
+ tmpFlavors.addElement(plainAsciiFlavor);
+ plainISOFlavor=new DataFlavor("text/plain; charset=iso8859-1");
+ tmpFlavors.addElement(plainISOFlavor);
+ }
+ catch (ClassNotFoundException e) {
+ // should never happen...
+ System.out.println("ClassNotFound Exception is thrown when"+
+ "flavors are created");
+ }
+ }
+
+ public static void main(String[] args) {
+ bestFlavorArray1 = new DataFlavor[tmpFlavors.size()];
+ tmpFlavors.copyInto(bestFlavorArray1);
+
+ //Selecting the best text flavor from a set of Data Flavors.
+ bestFlavor1 = DataFlavor.selectBestTextFlavor(bestFlavorArray1);
+ System.out.println("The Best Text Flavor is " + bestFlavor1);
+
+ bestFlavorArray2 = reverseDataFlavor(bestFlavorArray1);
+ bestFlavor2 = DataFlavor.selectBestTextFlavor(bestFlavorArray2);
+ System.out.println("The Best Text Flavor is " + bestFlavor2);
+
+ //Checking whether the selected flavors in both the arrays are same.
+ if (bestFlavor2.match(bestFlavor1)) {
+ System.out.println("The test is Passed");
+ }
+ else {
+ System.out.println("The test is Failed");
+ throw new RuntimeException("SelectBestTextFlavor doesn't return "+
+ "the same best Text flavor from a set of DataFlavors, "+
+ "it always returns the first Text Flavor encountered.");
+ }
+ }
+
+ //Returns the array of DataFlavor passed in reverse order.
+ public static DataFlavor[] reverseDataFlavor(DataFlavor[] dataflavor) {
+
+ DataFlavor[] tempFlavor = new DataFlavor[dataflavor.length];
+ int j = 0;
+ for (int i = dataflavor.length - 1 ; i >= 0; i--) {
+ tempFlavor[j] = dataflavor[i];
+ j++;
+ }
+ return tempFlavor;
+ }
+}
diff --git a/test/jdk/java/awt/datatransfer/FileTransferAWTLockTest/FileTransferAWTLockTest.java b/test/jdk/java/awt/datatransfer/FileTransferAWTLockTest/FileTransferAWTLockTest.java
new file mode 100644
index 0000000000000..ac4ff5c9b11ee
--- /dev/null
+++ b/test/jdk/java/awt/datatransfer/FileTransferAWTLockTest/FileTransferAWTLockTest.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2003, 2023, 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 4916420
+ @requires os.family == "linux"
+ @summary verifies that AWT_LOCK is properly taken during file transfer
+ @key headful
+*/
+
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.ClipboardOwner;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+public class FileTransferAWTLockTest {
+
+ public static void main(String[] args) {
+ if (!(System.getProperty("os.name").startsWith("Linux"))) {
+ return;
+ }
+ FileTransferAWTLockTest parent = new FileTransferAWTLockTest();
+ parent.start();
+ }
+
+ public void start() {
+ String stderr = null;
+ try {
+ String javaPath = System.getProperty("java.home", "");
+ String command = javaPath + File.separator + "bin" +
+ File.separator + "java -cp " +
+ System.getProperty("test.classes", ".") +
+ " -Dawt.toolkit=sun.awt.X11.XToolkit" +
+ " FileTransferAWTLockTestChild";
+
+ Process process = Runtime.getRuntime().exec(command);
+ ProcessResults pres = ProcessResults.doWaitFor(process);
+
+ stderr = pres.stderr;
+
+ if (pres.stderr != null && pres.stderr.length() > 0) {
+ System.err.println("========= Child VM System.err ========");
+ System.err.print(pres.stderr);
+ System.err.println("======================================");
+ }
+
+ if (pres.stdout != null && pres.stdout.length() > 0) {
+ System.err.println("========= Child VM System.out ========");
+ System.err.print(pres.stdout);
+ System.err.println("======================================");
+ }
+
+ System.err.println("Child VM return code: " + pres.exitValue);
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+
+ if (stderr != null && stderr.indexOf("InternalError") >= 0) {
+ throw new RuntimeException("Test failed");
+ }
+ }
+}
+
+class FileTransferAWTLockTestChild {
+ static final Clipboard clipboard =
+ Toolkit.getDefaultToolkit().getSystemClipboard();
+ static final Transferable transferable = new Transferable() {
+ public DataFlavor[] getTransferDataFlavors() {
+ return new DataFlavor[] { DataFlavor.javaFileListFlavor };
+ }
+ public boolean isDataFlavorSupported(DataFlavor df) {
+ return DataFlavor.javaFileListFlavor.equals(df);
+ }
+ public Object getTransferData(DataFlavor df)
+ throws IOException, UnsupportedFlavorException {
+ if (!isDataFlavorSupported(df)) {
+ throw new UnsupportedFlavorException(df);
+ }
+
+ File file = new File("file.txt");
+ ArrayList list = new ArrayList();
+ list.add(file);
+ return list;
+ }
+ };
+
+ public static void main(String[] args) {
+ Util.setClipboardContents(clipboard, transferable, null);
+ FileTransferAWTLockTestChild test = new FileTransferAWTLockTestChild();
+ test.run();
+ }
+
+ public void run() {
+ Transferable t = Util.getClipboardContents(clipboard, null);
+ try {
+ t.getTransferData(DataFlavor.javaFileListFlavor);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
+
+class Util {
+ public static void setClipboardContents(Clipboard cb,
+ Transferable contents,
+ ClipboardOwner owner) {
+ synchronized (cb) {
+ while (true) {
+ try {
+ cb.setContents(contents, owner);
+ return;
+ } catch (IllegalStateException ise) {
+ try { Thread.sleep(100); }
+ catch (InterruptedException e) { e.printStackTrace(); }
+ }
+ }
+ }
+ }
+
+ public static Transferable getClipboardContents(Clipboard cb,
+ Object requestor) {
+ synchronized (cb) {
+ while (true) {
+ try {
+ return cb.getContents(requestor);
+ } catch (IllegalStateException ise) {
+ try { Thread.sleep(100); }
+ catch (InterruptedException e) { e.printStackTrace(); }
+ }
+ }
+ }
+ }
+}
+
+class ProcessResults {
+ public int exitValue;
+ public String stdout;
+ public String stderr;
+
+ public ProcessResults() {
+ exitValue = -1;
+ stdout = "";
+ stderr = "";
+ }
+
+ /**
+ * Method to perform a "wait" for a process and return its exit value.
+ * This is a workaround for Process.waitFor()
never returning.
+ */
+ public static ProcessResults doWaitFor(Process p) {
+ ProcessResults pres = new ProcessResults();
+
+ InputStream in = null;
+ InputStream err = null;
+
+ try {
+ in = p.getInputStream();
+ err = p.getErrorStream();
+
+ boolean finished = false;
+
+ while (!finished) {
+ try {
+ while (in.available() > 0) {
+ pres.stdout += (char)in.read();
+ }
+ while (err.available() > 0) {
+ pres.stderr += (char)err.read();
+ }
+ // Ask the process for its exitValue. If the process
+ // is not finished, an IllegalThreadStateException
+ // is thrown. If it is finished, we fall through and
+ // the variable finished is set to true.
+ pres.exitValue = p.exitValue();
+ finished = true;
+ }
+ catch (IllegalThreadStateException e) {
+ // Process is not finished yet;
+ // Sleep a little to save on CPU cycles
+ Thread.currentThread().sleep(500);
+ }
+ }
+ if (in != null) in.close();
+ if (err != null) err.close();
+ }
+ catch (Throwable e) {
+ System.err.println("doWaitFor(): unexpected exception");
+ e.printStackTrace();
+ }
+ return pres;
+ }
+}