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