1 /* 2 * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 import java.awt.*; 27 import java.awt.datatransfer.Clipboard; 28 import java.awt.datatransfer.ClipboardOwner; 29 import java.awt.datatransfer.StringSelection; 30 import java.awt.datatransfer.Transferable; 31 import java.io.File; 32 import java.io.IOException; 33 import java.io.InputStream; 34 35 /* 36 * @test 37 * @bug 4532299 4648733 38 * @summary Tests that getting clipboard contents on the interrupted thread will 39 * not cause deadlock.Also check that lostOwnership event occurs while 40 * cross-JVM interaction 41 * @author Kanishk Jethi 42 * @run main GetContentsInterruptedTest 43 */ 44 45 public class GetContentsInterruptedTest implements ClipboardOwner { 46 47 final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 48 final Transferable transferable = new StringSelection("TEXT"); 49 private final Object o = new Object(); 50 51 public static void main(String args[]) throws Exception { 52 if (System.getProperty("os.name").startsWith("Mac")) { 53 System.out.println("This tests should not be run on OS X. " + 54 "See CR 7124344 for more info"); 55 } else { 56 boolean subTestFlag = false; 57 for (String arg : args) { 58 if (arg.indexOf("SubTest") != -1) 59 subTestFlag = true; 60 } 61 62 if (!subTestFlag) { 63 new GetContentsInterruptedTest().performTest(); 64 } else { 65 new GetContentsInterruptedTest().execute(); 66 } 67 } 68 } 69 70 private void performTest() throws Exception { 71 int retCode; 72 String javaPath = System.getProperty("java.home", ""); 73 String javaClasspath = System.getProperty("java.class.path", "."); 74 String command = javaPath + File.separator + "bin" + 75 File.separator + "java -classpath " + javaClasspath + 76 " GetContentsInterruptedTest SubTest"; 77 System.out.println(command); 78 boolean processExit = false; 79 80 clipboard.setContents(transferable, this); 81 Process process = Runtime.getRuntime().exec(command); 82 synchronized (o) { 83 o.wait(10000); 84 } 85 86 try { 87 retCode = process.exitValue(); 88 processExit = true; 89 }catch (IllegalThreadStateException e){ 90 throw new RuntimeException(e); 91 } 92 System.out.println("[RESULT] : " + 93 "The sub process has cleanly exited : PASS"); 94 95 System.out.println("[RESULT] : Child returned: " + retCode ); 96 97 InputStream errorStream = process.getErrorStream(); 98 System.out.println("========= Child process stderr ========"); 99 dumpStream(errorStream); 100 System.out.println("======================================="); 101 102 InputStream processInputStream = process.getInputStream(); 103 System.out.println("========= Child process output ========"); 104 dumpStream(processInputStream); 105 System.out.println("======================================="); 106 107 if (!processExit) { 108 process.destroy(); 109 throw new RuntimeException("[RESULT] : " + 110 "The sub process has not exited : FAIL"); 111 } 112 } 113 114 /* 115 * execute is run through another instance of this class. 116 * it acquires the systemClipboard through another JVM. 117 */ 118 public void execute() { 119 System.out.println("Hello world"); 120 final ClipboardOwner clipboardOwner = new ClipboardOwner() { 121 public void lostOwnership(Clipboard clipboard, Transferable contents) { 122 System.exit(0); 123 } 124 }; 125 clipboard.setContents(transferable, clipboardOwner); 126 synchronized (o) { 127 try { 128 o.wait(); 129 } catch (InterruptedException ie) { 130 ie.printStackTrace(); 131 } 132 } 133 } 134 135 public void dumpStream(InputStream in) throws IOException { 136 String tempString; 137 int count = in.available(); 138 while (count > 0) { 139 byte[] b = new byte[count]; 140 in.read(b); 141 tempString = new String(b); 142 if (tempString.indexOf("Exception") != -1 ) 143 throw new RuntimeException("[RESULT] :" + 144 " Exception in child process : FAIL"); 145 System.out.println(tempString); 146 count = in.available(); 147 } 148 } 149 150 public void lostOwnership(Clipboard clip, Transferable contents) { 151 new Thread(() -> { 152 try { 153 Thread.sleep(3000); 154 } catch (InterruptedException e) { 155 throw new RuntimeException(e); 156 } 157 clipboard.getContents(null); 158 Thread.currentThread().interrupt(); 159 clipboard.getContents(null); 160 clipboard.setContents(transferable, null); 161 }).start(); 162 } 163 } 164