7144861: speed up RMI activation tests
Reviewed-by: alanb, smarks, dholmes, dmocek
diff --git a/test/java/rmi/testlibrary/JavaVM.java b/test/java/rmi/testlibrary/JavaVM.java
index 4356f34..62be87d 100644
--- a/test/java/rmi/testlibrary/JavaVM.java
+++ b/test/java/rmi/testlibrary/JavaVM.java
@@ -36,7 +36,6 @@
  */
 public class JavaVM {
 
-    // need to
     protected Process vm = null;
 
     private String classname = "";
@@ -46,6 +45,10 @@
     private OutputStream errorStream = System.err;
     private String policyFileName = null;
 
+    // This is used to shorten waiting time at startup.
+    private volatile boolean started = false;
+    private boolean forcesOutput = true; // default behavior
+
     private static void mesg(Object mesg) {
         System.err.println("JAVAVM: " + mesg.toString());
     }
@@ -79,6 +82,25 @@
         this.errorStream = err;
     }
 
+    /* This constructor will instantiate a JavaVM object for which caller
+     * can ask for forcing initial version output on child vm process
+     * (if forcesVersionOutput is true), or letting the started vm behave freely
+     * (when forcesVersionOutput is false).
+     */
+    public JavaVM(String classname,
+                  String options, String args,
+                  OutputStream out, OutputStream err,
+                  boolean forcesVersionOutput) {
+        this(classname, options, args, out, err);
+        this.forcesOutput = forcesVersionOutput;
+    }
+
+
+    public void setStarted() {
+        started = true;
+    }
+
+    // Prepends passed opts array to current options
     public void addOptions(String[] opts) {
         String newOpts = "";
         for (int i = 0 ; i < opts.length ; i ++) {
@@ -87,6 +109,8 @@
         newOpts += " ";
         options = newOpts + options;
     }
+
+    // Prepends passed arguments array to current args
     public void addArguments(String[] arguments) {
         String newArgs = "";
         for (int i = 0 ; i < arguments.length ; i ++) {
@@ -127,6 +151,18 @@
 
         addOptions(new String[] { getCodeCoverageOptions() });
 
+        /*
+         * If forcesOutput is true :
+         *  We force the new starting vm to output something so that we can know
+         *  when it is effectively started by redirecting standard output through
+         *  the next StreamPipe call (the vm is considered started when a first
+         *  output has been streamed out).
+         *  We do this by prepnding a "-showversion" option in the command line.
+         */
+        if (forcesOutput) {
+            addOptions(new String[] {"-showversion"});
+        }
+
         StringTokenizer optionsTokenizer = new StringTokenizer(options);
         StringTokenizer argsTokenizer = new StringTokenizer(args);
         int optionsCount = optionsTokenizer.countTokens();
@@ -150,15 +186,43 @@
         vm = Runtime.getRuntime().exec(javaCommand);
 
         /* output from the execed process may optionally be captured. */
-        StreamPipe.plugTogether(vm.getInputStream(), this.outputStream);
-        StreamPipe.plugTogether(vm.getErrorStream(), this.errorStream);
+        StreamPipe.plugTogether(this, vm.getInputStream(), this.outputStream);
+        StreamPipe.plugTogether(this, vm.getErrorStream(), this.errorStream);
 
         try {
-            Thread.sleep(2000);
-        } catch (Exception ignore) {
-        }
+            if (forcesOutput) {
+                // Wait distant vm to start, by using waiting time slices of 100 ms.
+                // Wait at most for 2secs, after it considers the vm to be started.
+                final long vmStartSleepTime = 100;
+                final int maxTrials = 20;
+                int numTrials = 0;
+                while (!started && numTrials < maxTrials) {
+                    numTrials++;
+                    Thread.sleep(vmStartSleepTime);
+                }
 
-        mesg("finished starting vm.");
+                // Outputs running status of distant vm
+                String message =
+                    "after " + (numTrials * vmStartSleepTime) + " milliseconds";
+                if (started) {
+                    mesg("distant vm process running, " + message);
+                }
+                else {
+                    mesg("unknown running status of distant vm process, " + message);
+                }
+            }
+            else {
+                // Since we have no way to know if the distant vm is started,
+                // we just consider the vm to be started after a 2secs waiting time.
+                Thread.sleep(2000);
+                mesg("distant vm considered to be started after a waiting time of 2 secs");
+            }
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            mesg("Thread interrupted while checking if distant vm is started. Giving up check.");
+            mesg("Distant vm state unknown");
+            return;
+        }
     }
 
     public void destroy() {