Merge branch 'nr.dev' into 'ibm-trunk' Nr.dev Further fixes for customer-reported problems See merge request !68
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OCI/IIOP/Connector_impl.java b/yoko-core/src/main/java/org/apache/yoko/orb/OCI/IIOP/Connector_impl.java index e2a737e..b257a22 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OCI/IIOP/Connector_impl.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OCI/IIOP/Connector_impl.java
@@ -459,6 +459,7 @@ // ------------------------------------------------------------------ private Connector_impl(IOR ior, Policy[] policies, String host, int port, boolean keepAlive, ConnectCB[] cb, ListenerMap lm, ConnectionHelper helper, ExtendedConnectionHelper xhelper, Codec codec) { + if ((null == helper) && (null == xhelper)) throw new IllegalArgumentException("Both connection helpers must not be null"); ior_ = ior; policies_ = policies; keepAlive_ = keepAlive; @@ -474,8 +475,8 @@ this(ior, policies, host, port, keepAlive, cb, lm, helper, null, codec); } - public Connector_impl(IOR ior, Policy[] policies, String host, int port, boolean keepAlive, ConnectCB[] cb, ListenerMap lm, ExtendedConnectionHelper helper, Codec codec) { - this(ior, policies, host, port, keepAlive, cb, lm, null, helper, codec); + public Connector_impl(IOR ior, Policy[] policies, String host, int port, boolean keepAlive, ConnectCB[] cb, ListenerMap lm, ExtendedConnectionHelper xhelper, Codec codec) { + this(ior, policies, host, port, keepAlive, cb, lm, null, xhelper, codec); } public void finalize() throws Throwable {
diff --git a/yoko-core/src/test/java/org/apache/yoko/AbstractOrbTestBase.java b/yoko-core/src/test/java/org/apache/yoko/AbstractOrbTestBase.java index 2f702b4..ee97b45 100644 --- a/yoko-core/src/test/java/org/apache/yoko/AbstractOrbTestBase.java +++ b/yoko-core/src/test/java/org/apache/yoko/AbstractOrbTestBase.java
@@ -97,9 +97,6 @@ server.launch(); Future<Void> serverFuture = server.invokeMainAsync(serverClass, serverArgs); waitForFile(); - // TODO: Need to find a better way, this slows down testing unneccesarily, - // and is somewhat non-robust. - Thread.sleep(1000); client.invokeMain(clientClass, clientArgs); try { serverFuture.get(2, SECONDS);
diff --git a/yoko-core/src/test/java/test/poa/PMSTestThread.java b/yoko-core/src/test/java/test/poa/PMSTestThread.java index 1002cf6..a882e7e 100644 --- a/yoko-core/src/test/java/test/poa/PMSTestThread.java +++ b/yoko-core/src/test/java/test/poa/PMSTestThread.java
@@ -17,47 +17,48 @@ package test.poa; -import org.omg.CORBA.*; -import org.omg.PortableServer.*; -import org.omg.PortableServer.POAPackage.*; -import java.io.*; +import java.util.concurrent.CountDownLatch; final class PMSTestThread extends Thread { - private Test test_; + private final Test test_; - private int state_; + private final CountDownLatch startLatch = new CountDownLatch(1); + public volatile Result result = null; - final static int NONE = 0; - - final static int CALL_STARTED = 1; - - final static int CALL_FAILURE = 2; - - final static int CALL_SUCCESS = 3; - - private synchronized void setState(int val) { - state_ = val; - } + public enum Result { SUCCESS, FAILURE, ERROR }; public void run() { - setState(CALL_STARTED); + startLatch.countDown(); try { test_.aMethod(); + result = Result.SUCCESS; } catch (org.omg.CORBA.TRANSIENT ex) { - setState(CALL_FAILURE); + result = Result.FAILURE; return; } catch (org.omg.CORBA.SystemException ex) { + result = Result.ERROR; System.err.println("Unexpected: " + ex); } - setState(CALL_SUCCESS); } - synchronized int callState() { - return state_; + public void waitForStart() { + do { + try { + startLatch.await(); + return; + } catch (InterruptedException ie) {} + } while (true); + } + + public void waitForEnd() { + while (isAlive()) { + try { + join(); + } catch (InterruptedException ie) {} + } } PMSTestThread(Test test) { test_ = test; - state_ = NONE; } }
diff --git a/yoko-core/src/test/java/test/poa/TestDispatchStrategyServer.java b/yoko-core/src/test/java/test/poa/TestDispatchStrategyServer.java index 258e9e3..ea03185 100644 --- a/yoko-core/src/test/java/test/poa/TestDispatchStrategyServer.java +++ b/yoko-core/src/test/java/test/poa/TestDispatchStrategyServer.java
@@ -17,135 +17,78 @@ package test.poa; -import java.io.*; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.HashSet; import java.util.Properties; +import java.util.Set; public final class TestDispatchStrategyServer extends test.common.TestBase { // // Implementation to test same thread dispatch strategy // - final static class TestSameThread_impl extends TestPOA { - private Thread thread_; + abstract static class AbstractTest extends TestPOA { + private volatile boolean failed = false; - private boolean failed_; - - private boolean first_; - - TestSameThread_impl() { - failed_ = false; - first_ = true; + public final boolean failed() { + return failed; } - public void aMethod() { - // - // Test to ensure that all requests handled by the same thread - // - if (first_) { - thread_ = Thread.currentThread(); - first_ = false; - } else if (!Thread.currentThread().equals(thread_)) { - failed_ = true; + protected void fail() { + failed = true; + } + } + + abstract static class AbstractTestPool extends AbstractTest { + private final Set<Thread> threadSet = new HashSet<>(); + private final int maxSize; + + AbstractTestPool(int maxSize) { + this.maxSize = maxSize; + } + + public final synchronized void aMethod() { + final Thread thisThread = Thread.currentThread(); + if (threadSet.contains(thisThread)) return; + if (threadSet.size() < maxSize) { + threadSet.add(thisThread); + return; } - - try { - Thread.sleep(100); - } catch (InterruptedException ex) { - } + fail(); } + } - public boolean failed() { - return failed_; - } + final static class TestSameThread_impl extends AbstractTestPool { + TestSameThread_impl() { super(1); } } // // Implementation to test thread per request dispatch strategy // - final static class TestThreadPerReq_impl extends TestPOA { - private Thread threads_[]; + final static class TestThreadPerReq_impl extends AbstractTest { + private final Set<Thread> threadSet = new HashSet<>(); - private int thread_count_; - - private boolean failed_; - - TestThreadPerReq_impl() { - failed_ = false; - thread_count_ = 0; - threads_ = new Thread[5]; - } - - public void aMethod() { - int idx; - synchronized (this) { - // - // Test to ensure that each request is being handled - // by a different thread. - // - for (idx = 0; idx < thread_count_; idx++) { - if (Thread.currentThread().equals(threads_[idx])) - failed_ = true; - } - - if (idx == thread_count_) { - threads_[thread_count_++] = Thread.currentThread(); - } + public synchronized void aMethod() { + final Thread thisThread = Thread.currentThread(); + // + // Test to ensure that each request is being handled + // by a different thread. + // + if (threadSet.contains(thisThread)) { + fail(); + return; } - - try { - Thread.sleep(100); - } catch (InterruptedException ex) { - } - } - - public boolean failed() { - return failed_; + threadSet.add(thisThread); } } // // Implementation to test thread pool dispatch strategy // - final static class TestThreadPool_impl extends TestPOA { - private Thread threads_[]; - - private int thread_count_; - - private boolean failed_; - - TestThreadPool_impl() { - failed_ = false; - thread_count_ = 0; - threads_ = new Thread[2]; - } - - public void aMethod() { - synchronized (this) { - // - // Test to ensure that all requests are handled only by - // the two threads in the thread pool. - // - if (thread_count_ == 0) { - threads_[0] = Thread.currentThread(); - ++thread_count_; - } else if (!Thread.currentThread().equals(threads_[0])) { - if (thread_count_ == 1) { - threads_[1] = Thread.currentThread(); - ++thread_count_; - } else if (!Thread.currentThread().equals(threads_[1])) { - failed_ = true; - } - } - } - - try { - Thread.sleep(100); - } catch (InterruptedException ex) { - } - } - - public boolean failed() { - return failed_; - } + final static class TestThreadPool_impl extends AbstractTestPool { + TestThreadPool_impl() { super(2); } } //
diff --git a/yoko-core/src/test/java/test/poa/TestPOAManagerCommon.java b/yoko-core/src/test/java/test/poa/TestPOAManagerCommon.java index 4241b27..9a5895a 100644 --- a/yoko-core/src/test/java/test/poa/TestPOAManagerCommon.java +++ b/yoko-core/src/test/java/test/poa/TestPOAManagerCommon.java
@@ -23,45 +23,55 @@ import org.omg.PortableServer.*; import org.omg.PortableServer.POAPackage.*; +import java.util.concurrent.CountDownLatch; + final class TestPOAManagerCommon extends test.common.TestBase { final static class TestHoldingState extends Thread { private Test test_; - private int state_; + private final CountDownLatch startLatch = new CountDownLatch(1); + public volatile Result result = null; - final static int NONE = 0; - - final static int CALL_STARTED = 1; - - final static int CALL_FAILURE = 2; - - final static int CALL_SUCCESS = 3; - - private synchronized void setState(int val) { - state_ = val; - } + public enum Result { SUCCESS, FAILURE, ERROR }; TestHoldingState(Test test) { test_ = test; - state_ = NONE; } public void run() { - setState(CALL_STARTED); + startLatch.countDown(); try { test_.aMethod(); + result = Result.SUCCESS; } catch (TRANSIENT ex) { - setState(CALL_FAILURE); + result = Result.FAILURE; return; } catch (SystemException ex) { + result = Result.ERROR; System.err.println("Unexpected: " + ex); ex.printStackTrace(); } - setState(CALL_SUCCESS); } - synchronized int callState() { - return state_; + public void waitForStart() { + do { + try { + startLatch.await(); + return; + } catch (InterruptedException e) { + } + } while (true); + } + + + + public void waitForEnd() { + while (isAlive()) { + try { + join(); + } catch (java.lang.InterruptedException e) { + } + } } } @@ -142,33 +152,16 @@ TestHoldingState t = new TestHoldingState(info[i].obj); t.start(); - - // - // Wait for the call to start - // - try { - Thread.sleep(500); - } catch (InterruptedException ex) { - // Ignore - } - - assertTrue(t.callState() == TestHoldingState.CALL_STARTED); + t.waitForStart(); try { manager.activate(); } catch (test.poa.POAManagerProxyPackage.AdapterInactive ex) { assertTrue(false); } + t.waitForEnd(); + assertTrue(t.result == TestHoldingState.Result.SUCCESS); - // - // Wait for the call to complete - // - try { - Thread.sleep(500); - } catch (InterruptedException ex) { - } - - assertTrue(t.callState() == TestHoldingState.CALL_SUCCESS); // // Test discard_requests when holding. @@ -182,18 +175,7 @@ t = new TestHoldingState(info[i].obj); t.start(); - - // - // Wait for the call to start - // - try { - Thread.sleep(500); - } catch (InterruptedException ex) { - // Ignore - } - - assertTrue(t.callState() == TestHoldingState.CALL_STARTED); - + t.waitForStart(); try { manager.discard_requests(false); assertTrue(manager.get_state() == test.poa.POAManagerProxyPackage.State.DISCARDING); @@ -208,16 +190,11 @@ // Expected } - while (t.isAlive()) { - try { - t.join(); - } catch (java.lang.InterruptedException e) { - } - } + t.waitForEnd(); // // Queued call should have been discarded. // - assertTrue(t.callState() == TestHoldingState.CALL_FAILURE); + assertTrue(t.result == TestHoldingState.Result.FAILURE); // // Test hold_requests when discarding. @@ -231,17 +208,7 @@ t = new TestHoldingState(info[i].obj); t.start(); - - // - // Wait for the call to start - // - try { - Thread.sleep(500); - } catch (InterruptedException ex) { - // Ignore - } - - assertTrue(t.callState() == TestHoldingState.CALL_STARTED); + t.waitForStart(); try { manager.activate(); @@ -249,15 +216,8 @@ assertTrue(false); } - // - // Wait for the call to complete - // - try { - Thread.sleep(500); - } catch (InterruptedException ex) { - } - - assertTrue(t.callState() == TestHoldingState.CALL_SUCCESS); + t.waitForEnd(); + assertTrue(t.result == TestHoldingState.Result.SUCCESS); // // Try deactivate with wait completion == true,
diff --git a/yoko-core/src/test/java/test/poa/TestPOAManagerServer.java b/yoko-core/src/test/java/test/poa/TestPOAManagerServer.java index 73027d7..b609416 100644 --- a/yoko-core/src/test/java/test/poa/TestPOAManagerServer.java +++ b/yoko-core/src/test/java/test/poa/TestPOAManagerServer.java
@@ -117,10 +117,8 @@ POA retain = null; try { retain = root.create_POA("retain", null, policies); - } catch (AdapterAlreadyExists ex) { - throw new RuntimeException(); - } catch (InvalidPolicy ex) { - throw new RuntimeException(); + } catch (AdapterAlreadyExists | InvalidPolicy ex) { + throw new RuntimeException(ex); } POAManager retainManager = retain.the_POAManager(); @@ -133,12 +131,8 @@ byte[] oid = ("test").getBytes(); try { retain.activate_object_with_id(oid, testImpl); - } catch (ObjectAlreadyActive ex) { - assertTrue(false); - } catch (ServantAlreadyActive ex) { - assertTrue(false); - } catch (WrongPolicy ex) { - assertTrue(false); + } catch (ObjectAlreadyActive | ServantAlreadyActive | WrongPolicy ex) { + throw new RuntimeException(ex); } Test test = testImpl._this(); @@ -147,12 +141,8 @@ byte[] oidDSI = ("testDSI").getBytes(); try { retain.activate_object_with_id(oidDSI, testDSIImpl); - } catch (ObjectAlreadyActive ex) { - assertTrue(false); - } catch (ServantAlreadyActive ex) { - assertTrue(false); - } catch (WrongPolicy ex) { - assertTrue(false); + } catch (ObjectAlreadyActive | ServantAlreadyActive | WrongPolicy ex) { + throw new RuntimeException(ex); } org.omg.CORBA.Object objDSI = retain.create_reference_with_id( @@ -179,13 +169,7 @@ // PMSTestThread t = new PMSTestThread(test); t.start(); - - try { - Thread.sleep(500); - } catch (InterruptedException ex) { - } - - assertTrue(t.callState() == PMSTestThread.CALL_STARTED); + t.waitForStart(); // // Run implementation. This should cause the blocked call in @@ -195,19 +179,11 @@ manager.activate(); retainManager.activate(); } catch (org.omg.PortableServer.POAManagerPackage.AdapterInactive ex) { - throw new RuntimeException(); + throw new RuntimeException(ex); } + t.waitForEnd(); - // - // Wait for the call to complete - // - try { - Thread.sleep(500); - } catch (InterruptedException ex) { - // Ignore - } - - assertTrue(t.callState() == PMSTestThread.CALL_SUCCESS); + assertTrue(t.result == PMSTestThread.Result.SUCCESS); new TestPOAManagerCommon(proxy, info);
diff --git a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ArrayDescriptor.java b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ArrayDescriptor.java index 2cedbfa..ca4e0b1 100755 --- a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ArrayDescriptor.java +++ b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ArrayDescriptor.java
@@ -185,27 +185,20 @@ _out.write_value((Serializable)value, getRepositoryID()); } - ValueMember[] getValueMembers() { + @Override + protected final ValueMember[] genValueMembers() { + final ValueMember[] members = new ValueMember[1]; + final TypeDescriptor elemDesc = repo.getDescriptor(elementType); + final String elemRepID = elemDesc.getRepositoryID(); - if (_value_members == null) { + final ORB orb = ORB.init(); + TypeCode memberTC = orb.create_sequence_tc(0, elemDesc.getTypeCode()); - _value_members = new ValueMember[1]; - - TypeDescriptor elemDesc = repo.getDescriptor(elementType); - - String elemRepID = elemDesc.getRepositoryID(); - - ORB orb = ORB.init(); - TypeCode memberTC = orb.create_sequence_tc(0, elemDesc - .getTypeCode()); - - _value_members[0] = new ValueMember("", // member has no name! + members[0] = new ValueMember("", // member has no name! elemRepID, this.getRepositoryID(), "1.0", memberTC, null, (short) 1); - // public - } - return _value_members; + return members; } @Override
diff --git a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/TypeDescriptor.java b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/TypeDescriptor.java index ed66893..aea1298 100755 --- a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/TypeDescriptor.java +++ b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/TypeDescriptor.java
@@ -208,14 +208,17 @@ @Override protected void init() { - typeCode = genTypeCode(); + getTypeCode(); } private volatile TypeCode typeCode = null; protected abstract TypeCode genTypeCode(); final TypeCode getTypeCode() { - // typeCode should have already been set from within init(), so this is just defensive - if (null == typeCode) typeCode = genTypeCode(); + if (null == typeCode) { + synchronized (repo) { + if (null == typeCode) typeCode = genTypeCode(); + } + } return typeCode; } protected final void setTypeCode(TypeCode tc) {
diff --git a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ValueDescriptor.java b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ValueDescriptor.java index e6b1849..6e66d1c 100755 --- a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ValueDescriptor.java +++ b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ValueDescriptor.java
@@ -821,19 +821,23 @@ return _hash_code; } - protected ValueMember[] _value_members = null; - - private ValueMember[] getValueMembers() { - getTypeCode(); // ensure recursion through typecode for non-array types - - if (_value_members == null) { - _value_members = new ValueMember[_fields.length]; - for (int i = 0; i < _fields.length; i++) { - _value_members[i] = _fields[i].getValueMember(repo); - } + private volatile ValueMember[] valueMembers = null; + protected ValueMember[] genValueMembers() { + final ValueMember[] members = new ValueMember[_fields.length]; + for (int i = 0; i < _fields.length; i++) { + members[i] = _fields[i].getValueMember(repo); } - return _value_members; + return members; + } + final ValueMember[] getValueMembers() { + getTypeCode(); // ensure recursion through typecode + if (null == valueMembers) { + synchronized (repo) { + if (null == valueMembers) valueMembers = genValueMembers(); + } + } + return valueMembers; } @Override