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());
}
}