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