Updating Portfolio Target Start / End fails in a new thread

I’m using the MutableIssue API to update the Target Start and Target End dates which are provided by Portfolio.

These fields are set when there’s a SprintUpdateEvent to reflect the Sprint’s start and end date in the Target Start and Target End field.

Because a Sprint could contain a lot of issues, I’m running this code in a new thread, otherwise the UI freezes, or times out, for the user that updates the sprint.

What I notice is that when I’m running the code without a new thread, there are no problems in updating the issues and the fields are set, except that the UI freezes.

When I’m updating them within a thread, IllegalArgumentExceptions are thrown.

Thread.start("MyThread") {
    jtlu.preCall()
    try {
        // retrieving a user here in case it would get lost outside of the thread or the authenticated user would not have proper permissions
        ApplicationUser user = userManager.getUserByName("jira-admin")

        ... 
        issue.setCustomFieldValue(cfTargetStart, new Date(event.sprint.startDate.getMillis()))
        issue.setCustomFieldValue(cfTargetEnd, new Date(event.sprint.endDate.getMillis()))

         // another try / catch so it won't stop the thread
         ...
         issueManager.updateIssue(user, issue, EventDispatchOption.DO_NOT_DISPATCH, false) 

} catch(Exception ex) {
    log.error ex
} finally {
    jtlu.postCall(log)
}

The stacktrace (only when performing this within a thread)

[com.google.common.base.Preconditions.checkArgument(Preconditions.java:127), com.atlassian.jira.entity.property.BaseEntityPropertyService.setProperty(BaseEntityPropertyService.java:96), com.atlassian.jira.entity.property.DelegatingEntityPropertyService.setProperty(DelegatingEntityPropertyService.java:41), jdk.internal.reflect.GeneratedMethodAccessor2373.invoke(Unknown Source), java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.base/java.lang.reflect.Method.invoke(Method.java:566), com.atlassian.plugin.util.ContextClassLoaderSettingInvocationHandler.invoke(ContextClassLoaderSettingInvocationHandler.java:26), com.sun.proxy.$Proxy147.setProperty(Unknown Source), jdk.internal.reflect.GeneratedMethodAccessor2373.invoke(Unknown Source), java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.base/java.lang.reflect.Method.invoke(Method.java:566), com.atlassian.plugin.osgi.bridge.external.HostComponentFactoryBean$DynamicServiceInvocationHandler.invoke(HostComponentFactoryBean.java:131), com.sun.proxy.$Proxy147.setProperty(Unknown Source), com.atlassian.rm.common.bridges.jira.issue.properties.IssuePropertyServiceBridge81.setProperty(IssuePropertyServiceBridge81.java:83), com.atlassian.rm.common.env.issues.JiraIssuePropertyService.setProperty(JiraIssuePropertyService.java:268), com.atlassian.rm.common.env.issues.JiraIssuePropertyService.set(JiraIssuePropertyService.java:109), com.atlassian.rm.jpo.customfields.common.IssuePropertyCustomFieldValuePersister.updateValues(IssuePropertyCustomFieldValuePersister.java:95), com.atlassian.jira.issue.customfields.impl.AbstractSingleFieldType.updateValue(AbstractSingleFieldType.java:152), com.atlassian.jira.issue.fields.ImmutableCustomField.updateValue(ImmutableCustomField.java:426), com.atlassian.jira.issue.fields.ImmutableCustomField.updateValue(ImmutableCustomField.java:396), com.atlassian.jira.issue.managers.DefaultIssueManager.updateFieldValues(DefaultIssueManager.java:728), com.atlassian.jira.issue.managers.DefaultIssueManager.updateIssue(DefaultIssueManager.java:681), com.atlassian.jira.issue.managers.DefaultIssueManager.updateIssue(DefaultIssueManager.java:667), com.atlassian.jira.issue.managers.RequestCachingIssueManager.updateIssue(RequestCachingIssueManager.java:217), com.atlassian.jira.issue.IssueManager$updateIssue$0.call(Unknown Source), org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47), org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115), org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:151), Script1084$_run_closure1$_closure2.doCall(Script1084.groovy:88), java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method), java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62), java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.base/java.lang.reflect.Method.invoke(Method.java:566), org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:101), groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323), org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:263), groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1041), groovy.lang.Closure.call(Closure.java:405), groovy.lang.Closure.call(Closure.java:421), org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2330), org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2315), org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2356), org.codehaus.groovy.runtime.dgm$186.invoke(Unknown Source), org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:244), org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53), org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47), org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115), org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:127), Script1084$_run_closure1.doCall(Script1084.groovy:55), Script1084$_run_closure1.doCall(Script1084.groovy), java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method), java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62), java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.base/java.lang.reflect.Method.invoke(Method.java:566), org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:101), groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323), org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:263), groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1041), groovy.lang.Closure.call(Closure.java:405), groovy.lang.Closure.call(Closure.java:399), groovy.lang.Closure.run(Closure.java:486), java.base/java.lang.Thread.run(Thread.java:834)]
2020-10-14 11:21:37,289+0200 ScriptRunnerUpdateIssuesInSprint ERROR jira-admin 681x885654x1 kkcplu 95.142.96.205,127.0.0.1 /rest/greenhopper/1.0/sprint/18

Note that when I’m using self made custom fields there are no issues and it performs just fine while running within a thread.

I want to avoid setting up yet another listener that would try to update the Target Start / End date when my own custom field value would get updated via this code.

1 Like