EVALUATION
The specification of CompositeType.isValue has been extended so it will ccept a CompositeData that has additional items beyond the ones in the CompositeType, provided it does have all the values in the CompositeType. Thus, a client that only references these items (because it has an earlier version or is only relying the standard items) will continue to work, but a client that knows the additional items can access them. This change also impacts TabularType.isValue and ArrayType.isValue, since TabularData contains a CompositeData, and arrays can also contain CompositeData. For the moment, there is no public isAssignableFrom method.
|
|
|
EVALUATION
A case where this would be useful is the Hotspot extension to the standard java.lang.management.GarbageCollectorMXBean. This defines a field called LastGcInfo which is mapped to a CompositeData containing some standard fields, plus some gc-type-specific fields. The derived CompositeType should include the standard fields, but a mapped CompositeData may contain additional ones.
|
|
|
EVALUATION
This question was recently raised on the JMX-FORUM; see <http://archives.java.sun.com/cgi-bin/wa?A1=ind0512&L=jmx-forum>. An important point that was raised there is that TabularDataSupport will refuse to add a row if that row's CompositeType is not exactly equal to the tabularDataSupport.getRowType(). So we don't support schema evolution very well in this case.
Here's what I wrote on the forum:
<<<
Making this work the way we would like appears moderately tricky, especially since we don't want to change the behaviour of any existing code. In particular we have to consider nested CompositeData, which is presumably subject to the same constraints.
What we might imagine would be the following. We add to OpenType a new method isAssignableFrom(OpenType) that looks like this:
public abstract class OpenType<T> implements Serializable {
...
public boolean isAssignableFrom(OpenType<?> ot) {
return this.equals(ot);
}
}
Then in CompositeType we override this method and we add a new constructor that says whether type matching is strict:
public class CompositeType extends OpenType<CompositeData> {
...
public CompositeType(String typeName, String description,
String[] itemNames, String[] itemDescriptions,
OpenType<?>[] itemTypes,
boolean allowExtraItems) {
...
this.allowExtraItems = allowExtraItems;
}
public boolean allowExtraItems() {
return allowExtraItems;
}
@Override
public boolean isAssignableFrom(OpenType<?> ot) {
if (!allowExtraItems)
return equals(ot);
if (!(ot instanceof CompositeType))
return false;
CompositeType ct = (CompositeType) ot;
for (String key : ct.keySet()) {
OpenType<?> otItemType = ct.getType(key);
OpenType<?> thisItemType = getType(key);
if (thisItemType == null ||
!thisItemType.isAssignableFrom(otItemType))
return false;
}
return true;
}
...
}
So if ct1 and ct2 are both CompositeTypes, and if ct1.allowExtraItems(), then ct1.isAssignableFrom(ct2) is true if all the items in ct2 also appear in ct1 with the same name and compatible type.
However this only addresses schema evolution in one direction, where ct2 is more recent than ct1 and therefore contains more items. We'd really like to address the case where ct2 is less recent and is missing some items. We could cover this case by allowing the constructor of CompositeType to specify a default value for certain items. If ct2 is missing some items, but all of those items have default values, then isAssignableFrom returns true.
>>>
|
|
|
EVALUATION
This seems obviously right to allow new items to be added during schema evolution. There does not seem to be any correspondingly obvious way to allow items to be removed, so the suggestion is that they cannot be.
###@###.### 2004-07-07
The CompositeData.values() method will probably need to be deprecated for schema evolution to work reliably. Since this method returns values in lexicographical order of the item names, if new items are added then the Collection returned by CompositeData.values() will be meaningless to a peer that does not know about them. This method is not of much obvious use anyway, except possibly to call toString() on the Collection. The proposed MXBean framework should mean that people no longer deal with CompositeData directly anyway.
###@###.### 2004-07-08
This support is not strictly necessary for MXBeans. MXBeans can use concrete Java classes for value types and they can add a @PropertyNames annotation (formerly @GetterNames) to more than one constructor. Evolution works as follows. The initial version of a value type has exactly one constructor with a @PropertyNames annotation. If a subsequent version adds further fields, then it adds another constructor with a @PropertyNames annotation mentioning the existing and new fields. The previous constructor retains its @PropertyNames annotation.
When a class has more than one @PropertyNames constructor, it must be possible to order them such that the names for any constructor are a subset of the names for all subsequent constructors.
When a CompositeData is to be converted into an instance of such a class, then the constructor to be used is the last one in the order just mentioned where all of the names are present in the CompositeData.
For example, if we have this class:
public class Thing {
@PropertyNames({"a"})
Thing(int a) {...}
@PropertyNames({"a", "b"})
Thing(int a, long b) {...}
@PropertyNames({"a", "b", "c"})
Thing(int a, long b, String c) {...}
}
then a CompositeData with items "a" and "b" would use the second constructor, while a CompositeData with items "a", "b", and "c" would use the third. A CompositeData with items "a", "b", and "x" would also use the second constructor. This would imply that the CompositeData came from code where class Thing evolved differently.
###@###.### 2005-05-03 15:46:35 GMT
|
|
|
PUBLIC COMMENTS
Allow new items to be added to CompositeType as used in an information model.
|
|
|
CONVERTED DATA
BugTraq+ Release Management Values
COMMIT TO FIX:
mustang
|
|
|
|