test/java/rmi/activation/Activatable/checkAnnotations/CheckAnnotations.java

Print this page

        

@@ -32,37 +32,64 @@
  * @run main/othervm/policy=security.policy/timeout=480 CheckAnnotations
  */
 
 import java.io.*;
 import java.rmi.*;
-import java.rmi.server.*;
 import java.rmi.activation.*;
-import java.security.CodeSource;
 import java.util.Properties;
 import java.util.StringTokenizer;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 
 
 public class CheckAnnotations
     extends Activatable implements MyRMI, Runnable
 {
-
-    private static Object dummy = new Object();
     private static MyRMI myRMI = null;
+    static class NotifyOutputStream extends ByteArrayOutputStream {
+        final Lock lock;
+        final Condition signal;
+        
+        NotifyOutputStream(Lock lock, Condition signal) {
+            this.lock = lock;
+            this.signal = signal;
+        }
+
+        @Override
+        public synchronized void write(int b) {
+            lock.lock();
+            try{
+                super.write(b);
+                signal.signal();
+            } finally {
+                lock.unlock();
+            }
+        }
+        
+        @Override
+        public synchronized void write(byte b[], int off, int len) {
+            lock.lock();
+            try{
+                super.write(b, off, len);
+                if (len != 0)
+                    signal.signal();
+            } finally {
+                lock.unlock();
+            }
+        }
+    }
 
     // buffers to store rmid output.
-    private static ByteArrayOutputStream rmidOut = new ByteArrayOutputStream();
-    private static ByteArrayOutputStream rmidErr = new ByteArrayOutputStream();
+    private static final Lock lock = new ReentrantLock();
+    private static final Condition writeOutSig = lock.newCondition();
+    private static final Condition writeErrSig = lock.newCondition();
+    private static final NotifyOutputStream rmidOut = new NotifyOutputStream(lock, writeOutSig);
+    private static final NotifyOutputStream rmidErr = new NotifyOutputStream(lock, writeErrSig);
 
     public static void main(String args[]) {
-        /*
-         * The following line is required with the JDK 1.2 VM so that the
-         * VM can exit gracefully when this test completes.  Otherwise, the
-         * conservative garbage collector will find a handle to the server
-         * object on the native stack and not clear the weak reference to
-         * it in the RMI runtime's object table.
-         */
-        Object dummy1 = new Object();
         RMID rmid = null;
 
         System.err.println("\nRegression test for bug/rfe 4109103\n");
 
         try {

@@ -96,22 +123,20 @@
             ActivationGroup.createGroup(groupID, groupDesc, 0);
 
             ActivationDesc desc = new ActivationDesc
                 ("CheckAnnotations", null, null);
             myRMI = (MyRMI) Activatable.register(desc);
-
             /* The test-
              * Loop a bunch of times to force activator to
              * spawn VMs (groups)
              */
             for (int i = 0; i < 3; i++) {
 
                 // object activated in annotation check via method call
                 if(!checkAnnotations(i-1)) {
                     TestLibrary.bomb("Test failed: output improperly annotated.");
                 }
-
                 /*
                  * Clean up object too.
                  */
                 System.err.println
                     ("Deactivate object via method call");

@@ -123,32 +148,34 @@
         } catch (Exception e) {
             TestLibrary.bomb("\nfailure: unexpected exception ", e);
         } finally {
             try {
                 Thread.sleep(4000);
-            } catch (InterruptedException e) {
+            } catch (InterruptedException ignore) {
             }
-
             myRMI = null;
             System.err.println("rmid shut down");
             ActivationLibrary.rmidCleanup(rmid);
         }
     }
 
     /**
      * check to make sure that the output from a spawned vm is
      * formatted/annotated properly.
+     * @param iteration
+     * @return 
+     * @throws java.io.IOException 
+     * @throws java.lang.InterruptedException 
      */
     public static boolean checkAnnotations(int iteration)
-        throws IOException
+        throws IOException, InterruptedException
     {
         try {
-            Thread.sleep(5000);
-        } catch(Exception e) {
+            Thread.sleep(1000);
+        } catch(InterruptedException e) {
             System.err.println(e.getMessage());
         }
-
         /**
          * cause the spawned vm to generate output that will
          * be checked for proper annotation.  printOut is
          * actually being called on an activated implementation.
          */

@@ -160,36 +187,63 @@
         /* we have to wait for output to filter down
          * from children so we can read it before we
          * kill rmid.
          */
 
-        String outString = null;
-        String errString = null;
+        String outString, errString;
 
-        for (int i = 0 ; i < 5 ; i ++ ) {
-            // have to give output from rmid time to trickle down to
-            // this process
+        class WaitThread extends Thread{
+            final Lock lock;
+            final Condition signal;
+            final long timeout;
+            WaitThread(Lock lock, Condition signal, long timeout) {
+                this.lock = lock;
+                this.signal = signal;
+                this.timeout = timeout;
+            }
+
+            @Override
+            public void run(){
+                long goTime = timeout;
+                lock.lock();
+                try{
+                    while(goTime > 0L) {
+                        long start = System.currentTimeMillis();
             try {
-                Thread.sleep(4000);
-            } catch(InterruptedException e) {
+                            if(signal.await(goTime, TimeUnit.MILLISECONDS)) {
+                                break;
+                            }
+                        } catch (InterruptedException e) {
+                            throw new RuntimeException("Signal interrupt unexpected:" + e);
+                        }
+                        goTime =  timeout - System.currentTimeMillis() + start;
+                    }
+                } finally {
+                    lock.unlock();
+                }
+            }
             }
-
             outString = rmidOut.toString();
             errString = rmidErr.toString();
-
-            if ((!outString.equals("")) &&
-                (!errString.equals("")))
-            {
+        if ((!"".equals(outString)) && (!"".equals(errString))) {
+            System.err.println("obtained annotations");
+        } else { 
+            WaitThread waitOutT = new WaitThread(lock, writeOutSig, 10000);
+            WaitThread waitErrT = new WaitThread(lock, writeErrSig, 10000);
+            waitOutT.start();
+            waitErrT.start();
+            waitOutT.join();
+            waitErrT.join();
+            outString = rmidOut.toString();
+            errString = rmidErr.toString();
+            if ((!"".equals(outString)) && (!"".equals(errString))) {
                 System.err.println("obtained annotations");
-                break;
             }
-            System.err.println("rmid output not yet received, retrying...");
         }
 
         rmidOut.reset();
         rmidErr.reset();
-
         // only test when we are annotating..., first run does not annotate
         if (iteration >= 0) {
             System.err.println("Checking annotations...");
             System.err.println(outString);
             System.err.println(errString);

@@ -221,11 +275,10 @@
             }
             if ((execOut == null)||(outTmp == null)||
                 (destOut == null)) {
                 return false;
             }
-
             // just make sure that last two strings are what we expect.
             if (execOut.equals("ExecGroup-" + iteration)
                 && (new String(destOut.substring(0,4)).equals("out" +
                                                               iteration))
                 && (execErr.equals("ExecGroup-"+iteration))

@@ -246,30 +299,35 @@
 
         // register/export anonymously
         super(id,0);
     }
 
+    @Override
     public void printOut(String toPrint) {
         System.out.println(toPrint);
     }
 
+    @Override
     public void printErr(String toPrint) {
         System.err.println(toPrint);
     }
 
     /**
      * Spawns a thread to deactivate the object.
+     * @throws java.lang.Exception
      */
+    @Override
     public void shutdown() throws Exception {
         (new Thread(this,"CheckAnnotations")).start();
     }
 
     /**
      * Thread to deactivate object. First attempts to make object
      * inactive (via the inactive method).  If that fails (the
      * object may still have pending/executing calls), then
      * unexport the object forcibly.
      */
+    @Override
     public void run() {
         ActivationLibrary.deactivate(this, getID());
     }
 }