Merge branch 'bidir-deadlock' into 'ibm-trunk'
Bidir deadlock
See merge request !49
diff --git a/yoko-core/src/test/java/test/rmi/ClientMain.java b/yoko-core/src/test/java/test/rmi/ClientMain.java
index 5f25e88..97e1f34 100755
--- a/yoko-core/src/test/java/test/rmi/ClientMain.java
+++ b/yoko-core/src/test/java/test/rmi/ClientMain.java
@@ -348,6 +348,20 @@
assertSame(map2.get(3), map2.get(4));
assertSame(map2.get(0), map2.get(1));
}
+
+ public void testClass() throws RemoteException {
+ final Class<?> type = Object.class;
+ sample.setSerializable(type);
+ Serializable s = sample.getSerializable();
+ assertSame(s, type);
+ }
+
+ public void testClassArray() throws RemoteException {
+ final Class<?>[] types = { Object.class, Map.class, String.class, Map.class };
+ sample.setSerializable(types);
+ Object[] oa = (Object[])sample.getSerializable();
+ assertArrayEquals(types, oa);
+ }
}
public static void main(String[] args) throws Exception {
@@ -392,6 +406,8 @@
test.testTimeUnit();
test.testTimeUnitArray();
test.testCmsfv2Data();
+ test.testClass();
+ test.testClassArray();
//myORB.destroy();
System.out.println("Testing complete");
}
diff --git a/yoko-rmi-impl/pom.xml b/yoko-rmi-impl/pom.xml
index d87bb45..a436390 100755
--- a/yoko-rmi-impl/pom.xml
+++ b/yoko-rmi-impl/pom.xml
@@ -76,7 +76,6 @@
org.apache.yoko.rmi.util,
org.apache.yoko.rmi.util.corba,
org.apache.yoko.rmi.util.stub,
- org.apache.yoko.rmi.cmsf
</Export-Package>
<Import-Package>
!sun.*,
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 6c2bf4c..b3ee101 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
@@ -18,7 +18,9 @@
package org.apache.yoko.rmi.impl;
+import java.io.Serializable;
import java.lang.reflect.Array;
+import java.util.Map;
import java.util.Vector;
import java.util.logging.Logger;
@@ -28,6 +30,7 @@
import org.omg.CORBA.ORB;
import org.omg.CORBA.TypeCode;
import org.omg.CORBA.ValueMember;
+import org.omg.CORBA.portable.InputStream;
public abstract class ArrayDescriptor extends ValueDescriptor {
protected int order;
@@ -49,7 +52,7 @@
} else {
TypeDescriptor desc = getTypeRepository()
.getDescriptor(elementType);
- String elemRep = desc.getRepositoryIDForArray();
+ String elemRep = desc.getRepositoryID();
String hash = elemRep.substring(elemRep.indexOf(':', 4));
_repid = "RMI:" + getJavaClass().getName() + hash;
}
@@ -71,7 +74,7 @@
} else {
TypeDescriptor desc = getTypeRepository()
.getDescriptor(elementType);
- _elementRepid = desc.getRepositoryIDForArray();
+ _elementRepid = desc.getRepositoryID();
}
// System.out.println ("Element REPID "+getJavaClass()+" >> "+_elementRepid);
@@ -424,27 +427,21 @@
}
}
- public java.io.Serializable readValue(
- org.omg.CORBA.portable.InputStream in, java.util.Map offsetMap,
- Integer key) {
- try {
- ObjectReader reader = makeCorbaObjectReader(in, offsetMap, null);
+ public Serializable readValue(InputStream in, Map offsetMap, Integer key) {
+ final int length = in.read_long();
+ Object[] arr = (Object[]) Array.newInstance(elementType, length);
+ offsetMap.put(key, arr);
- int length = reader.readInt();
- Object[] arr = (Object[]) Array.newInstance(elementType, length);
- offsetMap.put(key, arr);
- // System.out.println ("ValueArrayDescriptor::readValue
- // len="+length+"; type="+elementType);
-
- for (int i = 0; i < length; i++) {
- arr[i] = reader.readValueObject(elementType);
+ final org.omg.CORBA_2_3.portable.InputStream _in = (org.omg.CORBA_2_3.portable.InputStream) in;
+ for (int i = 0; i < length; i++) {
+ try {
+ arr[i] = _in.read_value(elementType);
+ } catch (org.omg.CORBA.portable.IndirectionException ex) {
+ arr[i] = offsetMap.get(new Integer(ex.offset));
}
-
- return (java.io.Serializable) arr;
- } catch (java.io.IOException ex) {
- throw (MARSHAL)new MARSHAL(ex.getMessage()).initCause(ex);
}
+ return arr;
}
Object copyObject(Object value, CopyState state) {
diff --git a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ClassBaseDescriptor.java b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ClassBaseDescriptor.java
new file mode 100644
index 0000000..debb1ec
--- /dev/null
+++ b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ClassBaseDescriptor.java
@@ -0,0 +1,41 @@
+package org.apache.yoko.rmi.impl;
+
+import java.lang.reflect.Field;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import javax.rmi.CORBA.ClassDesc;
+
+import org.omg.CORBA.MARSHAL;
+
+abstract class ClassBaseDescriptor extends ValueDescriptor {
+
+ ClassBaseDescriptor(Class type, TypeRepository repository) {
+ super(type, repository);
+ }
+
+ @Override
+ public void init() {
+ super.init();
+
+ final Class<?> clz = ClassDesc.class;
+
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ @Override
+ public Void run() {
+ try {
+ final Field repid_field = clz.getDeclaredField("repid");
+ repid_field.setAccessible(true);
+ final Field codebase_field = clz.getDeclaredField("codebase");
+ codebase_field.setAccessible(true);
+ init(repid_field, codebase_field);
+ } catch (NoSuchFieldException ex) {
+ throw (MARSHAL)new MARSHAL("no such field: " + ex).initCause(ex);
+ }
+ return null;
+ }
+ });
+ }
+
+ abstract void init(Field repid_field, Field codebase_field);
+}
diff --git a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ClassDescDescriptor.java b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ClassDescDescriptor.java
new file mode 100644
index 0000000..c2ff742
--- /dev/null
+++ b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ClassDescDescriptor.java
@@ -0,0 +1,70 @@
+package org.apache.yoko.rmi.impl;
+
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.rmi.CORBA.ClassDesc;
+import javax.rmi.CORBA.Util;
+
+import org.omg.CORBA.MARSHAL;
+
+public class ClassDescDescriptor extends ClassBaseDescriptor {
+ private static final Logger logger = Logger.getLogger(ClassDescDescriptor.class.getName());
+
+ private Field repid_field;
+ private Field codebase_field;
+
+ ClassDescDescriptor(TypeRepository repository) {
+ super(ClassDesc.class, repository);
+ }
+
+ @Override
+ void init(Field repid_field, Field codebase_field) {
+ this.repid_field = repid_field;
+ this.codebase_field = codebase_field;
+ }
+
+ /** Read an instance of this value from a CDR stream */
+ @Override
+ public Serializable readResolve(final Serializable value) {
+ final ClassDesc desc = (ClassDesc) value;
+
+ Class<?> result = AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
+ public Class<?> run() {
+ String className = "<unknown>";
+ try {
+ String repid = (String) repid_field.get(desc);
+ String codebase = (String) codebase_field.get(desc);
+
+ TypeDescriptor typeDesc = repository.getDescriptor(repid);
+ if (null != typeDesc) {
+ Class<?> type = typeDesc.getJavaClass();
+ if (null != type) return type;
+ }
+
+ int beg = repid.indexOf(':');
+ int end = repid.indexOf(':', beg + 1);
+
+ className = repid.substring(beg + 1, end);
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+
+ return Util.loadClass(className, codebase, loader);
+ } catch (ClassNotFoundException ex) {
+ throw (MARSHAL)new MARSHAL("cannot load class " + className).initCause(ex);
+ } catch (IllegalAccessException ex) {
+ throw (MARSHAL)new MARSHAL("no such field: " + ex).initCause(ex);
+ }
+ }
+ });
+
+ if (logger.isLoggable(Level.FINE))
+ logger.fine(String.format("readResolve %s => %s", value, result));
+
+ return result;
+ }
+
+}
diff --git a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ClassDescriptor.java b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ClassDescriptor.java
index 37d2202..fab9919 100755
--- a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ClassDescriptor.java
+++ b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ClassDescriptor.java
@@ -18,115 +18,71 @@
package org.apache.yoko.rmi.impl;
+import java.io.Serializable;
+import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.logging.Level;
import java.util.logging.Logger;
-public class ClassDescriptor extends ValueDescriptor {
- static Logger logger = Logger.getLogger(ClassDescriptor.class.getName());
+import javax.rmi.CORBA.ClassDesc;
+import javax.rmi.CORBA.Util;
+import javax.rmi.CORBA.ValueHandler;
+
+import org.omg.CORBA.MARSHAL;
+
+public class ClassDescriptor extends ClassBaseDescriptor {
+ private static final Logger logger = Logger.getLogger(ClassDescriptor.class.getName());
+
+ private Field repid_field;
+ private Field codebase_field;
ClassDescriptor(TypeRepository repository) {
- super(javax.rmi.CORBA.ClassDesc.class, repository);
+ super(Class.class, repository);
}
- java.lang.reflect.Field repid_field;
-
- java.lang.reflect.Field codebase_field;
-
- String _repid_arr;
-
- public void init() {
- super.init();
-
- Class clz = javax.rmi.CORBA.ClassDesc.class;
- try {
- repid_field = clz.getDeclaredField("repid");
- repid_field.setAccessible(true);
- codebase_field = clz.getDeclaredField("codebase");
- codebase_field.setAccessible(true);
- } catch (java.lang.NoSuchFieldException ex) {
- throw new org.omg.CORBA.MARSHAL("no such field: " + ex);
- }
-
- ValueDescriptor class_desc = new ValueDescriptor(Class.class,
- getTypeRepository());
- class_desc.init();
- _repid_arr = class_desc.getRepositoryID();
+ @Override
+ void init(Field repid_field, Field codebase_field) {
+ this.repid_field = repid_field;
+ this.codebase_field = codebase_field;
}
- public String getRepositoryIDForArray() {
- return _repid_arr;
- }
-
+ @Override
Object copyObject(Object orig, CopyState state) {
state.put(orig, orig);
return orig;
}
- /** Read an instance of this value from a CDR stream */
- public java.io.Serializable readResolve(final java.io.Serializable value) {
- final javax.rmi.CORBA.ClassDesc desc = (javax.rmi.CORBA.ClassDesc) value;
-
- java.io.Serializable result = (java.io.Serializable) AccessController
- .doPrivileged(new PrivilegedAction() {
- public Object run() {
- String className = "<unknown>";
- try {
- String repid = (String) repid_field.get(desc);
- String codebase = (String) codebase_field.get(desc);
-
- int beg = repid.indexOf(':');
- int end = repid.indexOf(':', beg + 1);
-
- className = repid.substring(beg + 1, end);
- ClassLoader loader = Thread.currentThread()
- .getContextClassLoader();
-
- return javax.rmi.CORBA.Util.loadClass(className,
- codebase, loader);
- } catch (java.lang.ClassNotFoundException ex) {
- throw (org.omg.CORBA.MARSHAL)new org.omg.CORBA.MARSHAL(
- "cannot load class " + className).initCause(ex);
- } catch (java.lang.IllegalAccessException ex) {
- throw (org.omg.CORBA.MARSHAL)new org.omg.CORBA.MARSHAL(
- "no such field: " + ex).initCause(ex);
- }
- }
- });
-
- logger.fine("readResolve " + value + " => " + result);
-
- return result;
- }
-
/** Write an instance of this value to a CDR stream */
- public java.io.Serializable writeReplace(final java.io.Serializable value) {
- final Class type = (Class) value;
+ @Override
+ public Serializable writeReplace(final Serializable value) {
+ final Class<?> type = (Class<?>) value;
- final javax.rmi.CORBA.ClassDesc desc = new javax.rmi.CORBA.ClassDesc();
-
- return (java.io.Serializable) AccessController
- .doPrivileged(new PrivilegedAction() {
- public Object run() {
+ final ClassDesc result = AccessController
+ .doPrivileged(new PrivilegedAction<ClassDesc>() {
+ public ClassDesc run() {
try {
+ final ClassDesc desc = new ClassDesc();
- javax.rmi.CORBA.ValueHandler handler = javax.rmi.CORBA.Util
- .createValueHandler();
+ ValueHandler handler = Util.createValueHandler();
String repId = handler.getRMIRepositoryID(type);
repid_field.set(desc, repId);
- String codebase = javax.rmi.CORBA.Util
- .getCodebase(type);
+ String codebase = Util.getCodebase(type);
codebase_field.set(desc, codebase);
return desc;
- } catch (java.lang.IllegalAccessException ex) {
- throw (org.omg.CORBA.MARSHAL)new org.omg.CORBA.MARSHAL(
- "no such field: " + ex).initCause(ex);
+ } catch (IllegalAccessException ex) {
+ throw (MARSHAL)new MARSHAL("no such field: " + ex).initCause(ex);
}
}
});
+
+ if (logger.isLoggable(Level.FINE))
+ logger.fine(String.format("writeReplace %s => %s", value, result));
+
+ return result;
}
}
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 43d6b0b..5b8b833 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
@@ -41,9 +41,9 @@
@Override
public String toString() {
- return String.format("%s{class=\"%s\",repId=\"%s\",arrRepId=\"%s\"}",
+ return String.format("%s{class=\"%s\",repId=\"%s\"}",
this.getClass().getName(), getJavaClass(),
- getRepositoryID(), getRepositoryIDForArray());
+ getRepositoryID());
}
protected TypeDescriptor(Class type, TypeRepository repository) {
@@ -65,10 +65,6 @@
}
}
- public String getRepositoryIDForArray() {
- return getRepositoryID();
- }
-
public String getRepositoryID() {
if (_repid == null)
_repid = "RMI:" + getJavaClass().getName() + ":0000000000000000";
diff --git a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/TypeRepository.java b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/TypeRepository.java
index ddc5ca4..72d2d75 100755
--- a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/TypeRepository.java
+++ b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/TypeRepository.java
@@ -69,7 +69,6 @@
cleanStaleKeys();
final WeakReference<TypeDescriptor> value = new WeakReference<>(typeDesc);
map.putIfAbsent(new WeakKey<String>(typeDesc.getRepositoryID(), staleKeys), value);
- map.putIfAbsent(new WeakKey<String>(typeDesc.getRepositoryIDForArray(), staleKeys), value);
}
private void cleanStaleKeys() {
@@ -100,7 +99,7 @@
} else if (type == Class.class) {
return new ClassDescriptor(repo);
} else if (type == ClassDesc.class) {
- return this.get(Class.class);
+ return new ClassDescDescriptor(repo);
} else if (type == java.util.Date.class) {
return new DateValueDescriptor(repo);
} else if (staticAnyTypes.contains(type)) {
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 6d7eb3e..a4b869f 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
@@ -599,7 +599,11 @@
readValue(reader, value);
- return readResolve(value);
+ final Serializable resolved = readResolve(value);
+ if (value != resolved) {
+ offsetMap.put(offset, resolved);
+ }
+ return resolved;
} catch (IOException ex) {
throw (MARSHAL) new MARSHAL(ex.getMessage()).initCause(ex);