--- old/test/java/rmi/activation/Activatable/checkAnnotations/CheckAnnotations.java 2013-12-18 17:39:43.604304578 +0800 +++ new/test/java/rmi/activation/Activatable/checkAnnotations/CheckAnnotations.java 2013-12-18 17:39:43.436388572 +0800 @@ -34,33 +34,60 @@ 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"); @@ -98,7 +125,6 @@ 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) @@ -109,7 +135,6 @@ if(!checkAnnotations(i-1)) { TestLibrary.bomb("Test failed: output improperly annotated."); } - /* * Clean up object too. */ @@ -125,9 +150,8 @@ } finally { try { Thread.sleep(4000); - } catch (InterruptedException e) { + } catch (InterruptedException ignore) { } - myRMI = null; System.err.println("rmid shut down"); ActivationLibrary.rmidCleanup(rmid); @@ -137,16 +161,19 @@ /** * 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 @@ -162,32 +189,59 @@ * kill rmid. */ - String outString = null; - String errString = null; - - for (int i = 0 ; i < 5 ; i ++ ) { - // have to give output from rmid time to trickle down to - // this process - try { - Thread.sleep(4000); - } catch(InterruptedException e) { + String outString, errString; + + 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 { + 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 ((!"".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 ((!outString.equals("")) && - (!errString.equals(""))) - { + 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..."); @@ -223,7 +277,6 @@ (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" + @@ -248,17 +301,21 @@ 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(); } @@ -269,6 +326,7 @@ * object may still have pending/executing calls), then * unexport the object forcibly. */ + @Override public void run() { ActivationLibrary.deactivate(this, getID()); } --- old/test/java/rmi/activation/Activatable/forceLogSnapshot/ForceLogSnapshot.java 2013-12-18 17:39:44.044084595 +0800 +++ new/test/java/rmi/activation/Activatable/forceLogSnapshot/ForceLogSnapshot.java 2013-12-18 17:39:43.880166588 +0800 @@ -32,12 +32,13 @@ * @run main/othervm/policy=security.policy/timeout=640 ForceLogSnapshot */ -import java.io.*; +import java.io.IOException; import java.rmi.*; import java.rmi.activation.*; import java.rmi.server.*; -import java.rmi.registry.*; import java.util.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; public class ForceLogSnapshot implements ActivateMe @@ -49,20 +50,17 @@ final public static int SNAPSHOT_INTERVAL = 10; private ActivationID id; - private Vector responders = new Vector(); private static final String RESTARTABLE = "restartable"; private static final String ACTIVATABLE = "activatable"; - private static Object lock = new Object(); - private static boolean[] restartedObjects = new boolean[HOW_MANY]; - private static boolean[] activatedObjects = new boolean[HOW_MANY]; + private static final CountDownLatch restartedLatch = new CountDownLatch(HOW_MANY); + private static final CountDownLatch activatedLatch = new CountDownLatch(HOW_MANY); public ForceLogSnapshot(ActivationID id, MarshalledObject mobj) throws ActivationException, RemoteException { this.id = id; - int intId = 0; Activatable.exportObject(this, id, 0); ActivateMe obj; @@ -70,39 +68,37 @@ try { Object[] stuff = (Object[]) mobj.get(); - intId = ((Integer) stuff[0]).intValue(); + int intId = ((Integer) stuff[0]).intValue(); responder = (String) stuff[1]; obj = (ActivateMe) stuff[2]; System.err.println(responder + " service started"); - } catch (Exception e) { + obj.ping(intId, responder); + } catch (IOException | ClassNotFoundException e) { System.err.println("unable to obtain stub from marshalled object"); System.err.println(e.getMessage()); - e.printStackTrace(); - return; } - - obj.ping(intId, responder); } public ForceLogSnapshot() throws RemoteException { UnicastRemoteObject.exportObject(this, 0); } + @Override public void ping(int intId, String responder) { System.err.println("ForceLogSnapshot: received ping from " + responder); - if (responder.equals(RESTARTABLE)) { - synchronized (lock) { - restartedObjects[intId] = true; - } - } else if (responder.equals(ACTIVATABLE)) { - synchronized (lock) { - activatedObjects[intId] = true; - } + switch (responder) { + case RESTARTABLE: + restartedLatch.countDown(); + break; + case ACTIVATABLE: + activatedLatch.countDown(); + break; } } + @Override public void crash() { System.exit(0); } @@ -141,12 +137,12 @@ TestParams.defaultSecurityManager); Object[][] stuff = new Object[HOW_MANY][]; - MarshalledObject restartMobj = null; - ActivationGroupDesc groupDesc = null; - MarshalledObject activateMobj = null; + MarshalledObject restartMobj; + ActivationGroupDesc groupDesc; + MarshalledObject activateMobj; ActivationGroupID[] groupIDs = new ActivationGroupID[NUM_GROUPS]; - ActivationDesc restartableDesc = null; - ActivationDesc activatableDesc = null; + ActivationDesc restartableDesc; + ActivationDesc activatableDesc; ActivateMe[] restartableObj = new ActivateMe[HOW_MANY]; ActivateMe[] activatableObj = new ActivateMe[HOW_MANY]; @@ -214,7 +210,7 @@ */ rmid.restart(); - if (howManyRestarted(restartedObjects, 10) < HOW_MANY) { + if (waitAllStarted(restartedLatch, 10) != HOW_MANY) { TestLibrary.bomb("Test1 failed: a service would not " + "restart"); } @@ -225,7 +221,7 @@ * Make sure no activatable services were automatically * restarted. */ - if (howManyRestarted(activatedObjects, 2) != 0) { + if (waitAllStarted(activatedLatch, 2) != 0) { TestLibrary.bomb("Test2 failed: activatable service restarted!", null); } @@ -245,7 +241,7 @@ } while (repeatOnce-- > 0); - } catch (Exception e) { + } catch (IOException | ActivationException e) { TestLibrary.bomb("test failed", e); } finally { ActivationLibrary.rmidCleanup(rmid); @@ -256,30 +252,23 @@ } /** - * Check to see how many services have been automatically - * restarted. + * Check to see if all services have been automatically restarted. + * + * @waitObjects a CountDownLatch that used to sync all services. + * @retries retries times + * @return with retry retries times, how many services has been started */ - private static int howManyRestarted(boolean[] startedObjects, int retries) { - int succeeded = 0; - int restarted = 0; + private static int waitAllStarted(CountDownLatch waitObjects, int retries) { int atry = 0; - while ((restarted < HOW_MANY) && (atry < retries)) { - restarted = 0; - for (int j = 0 ; j < HOW_MANY ; j ++ ) { - synchronized(lock) { - if (startedObjects[j]) { - restarted ++; - } - } - } - System.err.println("not all objects restarted, retrying..."); + while (atry++ < retries) { try { - Thread.sleep(10000); - } catch (InterruptedException ie) { + if(waitObjects.await(10, TimeUnit.SECONDS)) + return HOW_MANY; + } catch (InterruptedException ex) { + throw new RuntimeException(ex); } - atry ++; } - return restarted; + return HOW_MANY - (int)waitObjects.getCount(); } }