Search code examples
rtc

ImmutablePropertyException periodically when changing enum field's value via Rational Team Concert API


Hitting this issue with changing certain enumeration-based fields in my new RTC work item for a RTC API tool I'm working on.

Basically, I get an ImmutablePropertyException the first time I change the field, but the next time it works without an exception.

Want to get rid of the exceptions. I'm using a value RTC is actually returning to me as a valid enum value for the field.

Assigning RTC work item field: odc.impact a field value of -> Integrity [odc.impact.literal.l4]

EXCEPTION: Could not assign value, even though it was found in the enumeration list: [Unassigned, Installability, Standards, Integrity]

com.ibm.team.repository.common.internal.ImmutablePropertyException at com.ibm.team.repository.common.internal.util.ItemUtil$ProtectAdapter.notifyChanged(ItemUtil.java:2070) at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:380) at com.ibm.team.repository.common.model.impl.StringExtensionEntryImpl.setTypedValue(StringExtensionEntryImpl.java:178) at com.ibm.team.repository.common.model.impl.StringExtensionEntryImpl.setValue(StringExtensionEntryImpl.java:360) at org.eclipse.emf.common.util.BasicEMap.putEntry(BasicEMap.java:303) at org.eclipse.emf.common.util.BasicEMap.put(BasicEMap.java:584) at org.eclipse.emf.common.util.BasicEMap$DelegatingMap.put(BasicEMap.java:799) at com.ibm.team.repository.common.model.impl.ItemImpl.setStringExtension(ItemImpl.java:1228) at com.ibm.team.workitem.common.internal.model.impl.WorkItemImpl.setEnumeration(WorkItemImpl.java:3779) at com.ibm.team.workitem.common.internal.model.impl.WorkItemImpl.setValue(WorkItemImpl.java:2915) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:95) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:56) at java.lang.reflect.Method.invoke(Method.java:620) at com.ibm.team.repository.common.internal.util.ItemStore$ItemInvocationHandler.invoke(ItemStore.java:597) at com.sun.proxy.$Proxy18.setValue(Unknown Source) at com.rtc.vda.WorkItemInitialization.setAttributeValueEx(WorkItemInitialization.java:237) at com.rtc.vda.WorkItemInitialization.setAttributeValue(WorkItemInitialization.java:210) at com.rtc.vda.WorkItemInitialization.execute(WorkItemInitialization.java:186) at com.ibm.team.workitem.client.WorkItemOperation.execute(WorkItemOperation.java:85) at com.ibm.team.workitem.client.WorkItemOperation.doRun(WorkItemOperation.java:272) at com.ibm.team.workitem.client.WorkItemOperation.run(WorkItemOperation.java:242) at com.ibm.team.workitem.client.WorkItemOperation.run(WorkItemOperation.java:189) at com.rtc.vda.RTCUtilities.createWorkItem(RTCUtilities.java:191) at com.rtc.vda.RTCMain.main(RTCMain.java:178)

Assigning: odc.impact -> Integrity [odc.impact.literal.l4]

This is the code snippet to set the enum value:

public boolean setAttributeValueEx (IWorkItem w, String attributeKey, String valueName) {

    // (REO) Get the attribute
    IAttribute a = customAttributesMap.get(attributeKey);

    // (REO) Buffer of valid values for error reporting
    StringBuffer b = new StringBuffer();

    try {
        // (REO) Get the enumeration for this attribute from the repository (DO NOT CACHE IT OR YOU WILL HAVE PROBLEMS)
        IWorkItemClient workItemClient = (IWorkItemClient) rtcParameters.getTeamRepository().getClientLibrary(IWorkItemClient.class);
        IEnumeration<? extends ILiteral> rtcAttrEnumeration = workItemClient.resolveEnumeration(a, curMonitor);

        // (REO) Find an enum value that matches this string and assign it
        for (ILiteral literal : rtcAttrEnumeration.getEnumerationLiterals()) {
            String vName = literal.getName();
            String vId = literal.getIdentifier2().getStringIdentifier();
            b.append(",");
            b.append(vName);
            if (valueName.equalsIgnoreCase(vName)) {
                String msg2 = "Assigning: " + a.getIdentifier() + " -> " + vName + " [" + vId + "]";
                RTCMain.out(msg2);
                w.setValue(a, literal.getIdentifier2()); // (REO) SOURCE OF PERIODIC EXCEPTION
                return true;
            }
        }
    } catch (Exception e) {
        RTCMain.out("EXCEPTION: Could not assign value, even though it was found in the enumeration list:\n\t[" + b + "]");
        e.printStackTrace();
        RTCMain.out("");
        return false;
    }

    RTCMain.out("VALUE NOT FOUND: Valid values are:" + b);
    return false;
}

Anyone know why I'm getting the periodic ImmutablePropertyException for only some of the fields, and why it goes away on the second call?

Thanks!


Solution

  • You just need to use the workingCopy.getWorkItem() object passed in to the execute() call rather than a cached version in a member variable. The attributes on the workingCopy object are not immutable and work fine.

    public class WorkItemCreator extends WorkItemOperation {
    
    ...
    
        @Override
        protected void execute(WorkItemWorkingCopy workingCopy, IProgressMonitor monitor) throws TeamRepositoryException {
    
            IWorkItem newWorkItem = workingCopy.getWorkItem();
            // Set attribute values on newWorkItem to avoid ImmutablePropertyExceptions