1 /*
   2  * Copyright (c) 2001, 2016, 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  * @key headful
  38  * @bug 4532299 4648733
  39  * @summary Tests that getting clipboard contents on the interrupted thread will
  40  *          not cause deadlock.Also check that lostOwnership event occurs while
  41  *          cross-JVM interaction
  42  * @author Kanishk Jethi
  43  * @run main GetContentsInterruptedTest
  44  */
  45 
  46 public class GetContentsInterruptedTest implements ClipboardOwner {
  47 
  48     final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
  49     final Transferable transferable = new StringSelection("TEXT");
  50     private final Object o = new Object();
  51 
  52     public static void main(String args[]) throws Exception {
  53         if (System.getProperty("os.name").startsWith("Mac")) {
  54             System.out.println("This tests should not be run on OS X. " +
  55                     "See CR 7124344 for more info");
  56         } else {
  57             boolean subTestFlag = false;
  58             for (String arg : args) {
  59                 if (arg.indexOf("SubTest") != -1)
  60                     subTestFlag = true;
  61             }
  62 
  63             if (!subTestFlag) {
  64                 new GetContentsInterruptedTest().performTest();
  65             } else {
  66                 new GetContentsInterruptedTest().execute();
  67             }
  68         }
  69     }
  70 
  71     private void performTest() throws Exception {
  72         int retCode;
  73         String javaPath = System.getProperty("java.home", "");
  74         String javaClasspath = System.getProperty("java.class.path", ".");
  75         String command = javaPath + File.separator + "bin" +
  76             File.separator + "java -classpath " + javaClasspath +
  77             " GetContentsInterruptedTest SubTest";
  78         System.out.println(command);
  79         boolean processExit = false;
  80 
  81         clipboard.setContents(transferable, this);
  82         Process process = Runtime.getRuntime().exec(command);
  83         synchronized (o) {
  84             o.wait(10000);
  85         }
  86 
  87         try {
  88             retCode = process.exitValue();
  89             processExit = true;
  90         }catch (IllegalThreadStateException e){
  91             throw new RuntimeException(e);
  92         }
  93         System.out.println("[RESULT] : " +
  94                 "The sub process has cleanly exited : PASS");
  95 
  96         System.out.println("[RESULT] : Child returned: " + retCode );
  97 
  98         InputStream errorStream = process.getErrorStream();
  99         System.out.println("========= Child process stderr ========");
 100         dumpStream(errorStream);
 101         System.out.println("=======================================");
 102 
 103         InputStream processInputStream = process.getInputStream();
 104         System.out.println("========= Child process output ========");
 105         dumpStream(processInputStream);
 106         System.out.println("=======================================");
 107 
 108         if (!processExit) {
 109             process.destroy();
 110             throw new RuntimeException("[RESULT] : " +
 111                     "The sub process has not exited : FAIL");
 112         }
 113     }
 114 
 115     /*
 116      * execute is run through another instance of this class.
 117      * it acquires the systemClipboard through another JVM.
 118      */
 119     public void execute() {
 120         System.out.println("Hello world");
 121         final ClipboardOwner clipboardOwner = new ClipboardOwner() {
 122             public void lostOwnership(Clipboard clipboard, Transferable contents) {
 123                 System.exit(0);
 124             }
 125         };
 126         clipboard.setContents(transferable, clipboardOwner);
 127         synchronized (o) {
 128             try {
 129                 o.wait();
 130             } catch (InterruptedException ie) {
 131                 ie.printStackTrace();
 132             }
 133         }
 134     }
 135 
 136     public void dumpStream(InputStream in) throws IOException {
 137         String tempString;
 138         int count = in.available();
 139         while (count > 0) {
 140             byte[] b = new byte[count];
 141             in.read(b);
 142             tempString = new String(b);
 143             if (tempString.indexOf("Exception") != -1 )
 144                 throw new RuntimeException("[RESULT] :" +
 145                         " Exception in child process : FAIL");
 146             System.out.println(tempString);
 147             count = in.available();
 148         }
 149     }
 150 
 151     public void lostOwnership(Clipboard clip, Transferable contents) {
 152         new Thread(() -> {
 153             try {
 154                 Thread.sleep(3000);
 155             } catch (InterruptedException e) {
 156                 throw new RuntimeException(e);
 157             }
 158             clipboard.getContents(null);
 159             Thread.currentThread().interrupt();
 160             clipboard.getContents(null);
 161             clipboard.setContents(transferable, null);
 162         }).start();
 163     }
 164 }
 165