Axis doesn't propertly support JavaBeans with array-type properties.
--------------------------------------------------------------------
Key: AXIS-2202
URL: http://issues.apache.org/jira/browse/AXIS-2202
Project: Apache Axis
Type: Bug
Components: Serialization/Deserialization
Versions: current (nightly), 1.2, 1.2.1
Reporter: Andrei Iltchenko
Priority: Critical
Axis fails to adequately support JavaBean classes with array-type properties
when objects of such classes are deserialized by a service endpoint exposed
with JBoss.
The problem occurs with those JavaBean array-type properties whose setters and
getters are not idempotent -- i.e. given a property called 'Prop', an array
value 'val1',
and a call to the the property's setter and getter:
BeanClass bean = ...;
ValueType val1 = ...;
bean.setProp(val1);
ValueType val2 = bean.getProp();
val1 != val2.
In other words Axis will work fine with the following JavaBean:
public class JavaBean1 {
Double values[];
Double[] getValues() {
return values;
}
void setValues(Double values[]) {
this.values = values;
}
}
but will fail to work with JavaBean2:
public class JavaBean2 {
ArrayList values;
Double[] getValues() {
return (Double[]) values.toArray(new Double[0]);
}
void setValues(Double values[]) {
this.values.clear();
this.values.addAll(java.util.Arrays.asList(values);
}
}
I investigated the cause of the problem and tracked it down to the 'set(Object,
int, Object)' method of the 'org.apache.axis.utils.BeanPropertyDescriptor'
class. Presented below is the code of the method with my fix for the problem
(another problem with this method is that it makes an unnecessary call to the
property's setter when growing the array, the fix takes care of that too). I
will also attach a diffs file for the patch:
public void set(Object obj, int i, Object newValue)
throws InvocationTargetException, IllegalAccessException {
// Set the new value
if (isIndexed()) {
IndexedPropertyDescriptor id = (IndexedPropertyDescriptor)myPD;
growArrayToSize(obj, id.getIndexedPropertyType(), i);
id.getIndexedWriteMethod().invoke(obj,
new Object[] {
new Integer(i), newValue});
} else {
// Not calling 'growArrayToSize' to avoid an extra call to the
// property's setter. The setter will be called at the end anyway.
// growArrayToSize(obj, myPD.getPropertyType().getComponentType(),
i);
Object array = get(obj);
if (array == null || Array.getLength(array) <= i) {
Class componentType = getType().getComponentType();
Object newArray = Array.newInstance(componentType, i + 1);
// Copy over the old elements
if (array != null) {
System.arraycopy(array, 0, newArray, 0,
Array.getLength(array));
}
array = newArray;
}
Array.set(array, i, newValue);
// Fix for non-indempondent array-type propertirs.
// Make sure we call the property's setter.
set(obj, array);
}
}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira