Path: blob/master/test/jdk/java/lang/ProcessBuilder/SiblingIOEHandle.java
41149 views
/*1* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/**24* @test25* @bug 692188526* @run main/othervm SiblingIOEHandle27* @summary inherit IOE handles and MS CreateProcess limitations (kb315939)28*/2930import java.io.BufferedReader;31import java.io.File;32import java.io.IOException;33import java.io.InputStreamReader;34import java.util.concurrent.BrokenBarrierException;35import java.util.concurrent.CyclicBarrier;3637public class SiblingIOEHandle {38private static enum APP {39A, B, C;40}4142private static File stopC = new File(".\\StopCs.txt");43private static String SIGNAL = "B child reported.";44private static String JAVA_EXE = System.getProperty("java.home")45+ File.separator + "bin"46+ File.separator + "java";4748private static String[] getCommandArray(String processName) {49String[] cmdArray = {50JAVA_EXE,51"-cp",52System.getProperty("java.class.path"),53SiblingIOEHandle.class.getName(),54processName55};56return cmdArray;57}5859public static void main(String[] args) {60if (!System.getProperty("os.name").startsWith("Windows")) {61return;62}6364APP app = (args.length > 0) ? APP.valueOf(args[0]) : APP.A;65switch (app) {66case A:67performA(true);68performA(false);69break;70case B:71performB();72break;73case C:74performC();75break;76}77}7879static boolean procClaunched = false;8081private static void waitAbit() {82try {83Thread.sleep(0);84} catch (InterruptedException ex) {85// that was long enough86}87}8889private static boolean waitBarrier(CyclicBarrier barrier) {90while (true) try {91barrier.await();92return true;93} catch (InterruptedException ex) {94continue;95} catch (BrokenBarrierException ex) {96ex.printStackTrace();97return false;98}99}100101private static class ProcessC implements Runnable {102private CyclicBarrier barrier;103private Process processC;104105public ProcessC(CyclicBarrier barrier) {106this.barrier = barrier;107}108109@Override110public void run() {111try {112if (waitBarrier(barrier)) {113waitAbit();114// Run process C next to B ASAP to make an attempt115// to capture the B-process IOE handles in C process.116ProcessBuilder builderC = new ProcessBuilder(117getCommandArray(APP.C.name()));118processC = builderC.start();119procClaunched = true;120}121} catch (IOException ex) {122ex.printStackTrace();123}124}125126public void waitFor() throws InterruptedException {127processC.waitFor();128}129}130131private static void performA(boolean fileOut) {132try {133stopC.delete();134ProcessBuilder builderB = new ProcessBuilder(135getCommandArray(APP.B.name()));136137File outB = null;138if (fileOut) {139outB = new File("outB.txt");140builderB.redirectOutput(outB);141}142builderB.redirectErrorStream(true);143144final CyclicBarrier barrier = new CyclicBarrier(2);145//Create process C in a new thread146ProcessC processC = new ProcessC(barrier);147Thread procCRunner = new Thread(processC);148procCRunner.start();149150if (!waitBarrier(barrier)) {151throw new RuntimeException("Catastrophe in process A! Synchronization failed.");152}153// Run process B first.154Process processB = builderB.start();155156while (true) try {157procCRunner.join();158break;159} catch (InterruptedException ex) {160continue;161}162163if (!procClaunched) {164throw new RuntimeException("Catastrophe in process A! C was not launched.");165}166167processB.getOutputStream().close();168processB.getErrorStream().close();169170if (fileOut) {171try {172processB.waitFor();173} catch (InterruptedException ex) {174throw new RuntimeException("Catastrophe in process B! B hung up.");175}176System.err.println("Trying to delete [outB.txt].");177if (!outB.delete()) {178throw new RuntimeException("Greedy brother C deadlock! File share.");179}180System.err.println("Succeeded in delete [outB.txt].");181} else {182System.err.println("Read stream start.");183boolean isSignalReceived = false;184try (BufferedReader in = new BufferedReader(new InputStreamReader(185processB.getInputStream(), "utf-8"))) {186String result;187while ((result = in.readLine()) != null) {188if (SIGNAL.equals(result)) {189isSignalReceived = true;190} else {191throw new RuntimeException("Catastrophe in process B! Bad output.");192}193}194}195if (!isSignalReceived) {196throw new RuntimeException("Signal from B was not received");197}198System.err.println("Read stream finished.");199}200// If JDK-6921885 is not fixed that point is unreachable.201// Test timeout exception.202203// write signal file to stop C process.204stopC.createNewFile();205processC.waitFor();206} catch (IOException ex) {207throw new RuntimeException("Catastrophe in process A!", ex);208} catch (InterruptedException ex) {209throw new RuntimeException("Process A was interrupted while waiting for C", ex);210}211}212213private static void performB() {214System.out.println(SIGNAL);215}216217private static void performC() {218// If JDK-7147084 is not fixed the loop is 5min long.219for (int i = 0; i < 5 * 60; ++i) {220try {221Thread.sleep(1000);222// check for sucess223if (stopC.exists())224break;225} catch (InterruptedException ex) {226// that is ok. Longer sleep - better effect.227}228}229}230}231232233