Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Update MultiUserPicker in jira 6.4.+ script

David B January 11, 2016

Hi

 

In my JIRA instance I am using issue security schemes to control access to JIRA issues based on names in a multi user picker custom field.

When a sub task is created I want to give access to the parent issue by appending the assignee of the subtask to the multi user list of the parent during a script run in a post function.

I've found a number of examples that are basically outdated and didn't work or which worked but which did not save the changes to the database.

The stumbling block seems to be due to the far to common com.atlassian.jira.user.BridgedDirectoryUser cannot be cast to com.atlassian.jira.user.ApplicationUser bug in Jira.

The error shows that the error is occurring at a code point beyond which I have access indicating that this is nothing I will be able to resolve.

If anyone knows how to make this work it would be much appreciated. There has to be some way to populate a multi user picker without having to resort to updating it directly in the backend database.

 

 

java.lang.ClassCastException: 
com.atlassian.jira.user.BridgedDirectoryUser cannot be cast to 
com.atlassian.jira.user.ApplicationUser
	at 
com.atlassian.jira.issue.customfields.impl.MultiUserCFType.convertTypeToDbValue(MultiUserCFType.java:74)

	at 
com.atlassian.jira.issue.customfields.impl.AbstractMultiCFType.convertTypesToDbObjects(AbstractMultiCFType.java:208)

	at 
com.atlassian.jira.issue.customfields.impl.AbstractMultiCFType.updateValue(AbstractMultiCFType.java:154)

	at 
com.atlassian.jira.issue.customfields.impl.MultiUserCFType.updateValue(MultiUserCFType.java:109)

	at 
com.atlassian.jira.issue.customfields.impl.MultiUserCFType.updateValue(MultiUserCFType.java:74)

	at 
com.atlassian.jira.issue.fields.CustomFieldImpl.updateValue(CustomFieldImpl.java:543)

	at 
com.atlassian.jira.issue.fields.CustomFieldImpl.updateValue(CustomFieldImpl.java:504)

	at 
com.atlassian.jira.issue.fields.OrderableField$updateValue.call(Unknown 
Source)
	at Script99.run(Script99.groovy:63)

 

Here's the test code.

 

import com.atlassian.jira.ComponentManager;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder;
import com.atlassian.jira.issue.util.IssueChangeHolder;
import com.atlassian.jira.issue.customfields.impl.MultiUserCFType
import com.atlassian.jira.issue.fields.layout.field.FieldLayoutItem;
import com.atlassian.jira.issue.ModifiedValue;
//import com.atlassian.jira.user.ApplicationUser;
//import com.atlassian.jira.user.BridgedDirectoryUser;
//import com.atlassian.crowd.embedded.api.User;
import com.atlassian.jira.user.ApplicationUsers;
import com.atlassian.jira.issue.UpdateIssueRequest
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.event.type.EventDispatchOption;
import com.atlassian.jira.issue.index.IssueIndexManager;
import com.atlassian.jira.user.ApplicationUser
import org.apache.log4j.Category;
import com.atlassian.jira.util.ImportUtils
 
log = Category.getInstance("com.onresolve.jira.groovy.PostFunction");
ComponentManager componentManager = ComponentManager.getInstance();
CustomFieldManager customFieldManager = componentManager.getCustomFieldManager();
IssueChangeHolder changeHolder = new DefaultIssueChangeHolder();
def MutableIssue issue = componentManager.getIssueManager().getIssueObject("FLONINE-670");
MutableIssue splitIssue = issue;
MutableIssue parentIssue = splitIssue.getParentObject();
CustomField splituserlist = customFieldManager.getCustomFieldObject("customfield_10061");
Collection<ApplicationUser> oldusers = (Collection) parentIssue.getCustomFieldValue(splituserlist);
Collection<ApplicationUser> users = (Collection) parentIssue.getCustomFieldValue(splituserlist);
if(users != null)
{
  for(i in 0..users.size()-1)
  {
    Object AssigneeValue = users.get(i).getName();
    if( users.get(i).getName() == splitIssue.assignee.getName())
    {
        log.error "User found and exiting"
      // name found so exit.
      return; 
    }
    i++
  }
}
users.add(splitIssue.assignee)
log.error "Prepare the Update"
// documentation says this won't work to write to the database. Why does it even exist then?
//parentIssue.setCustomFieldValue(splituserlist, users);
FieldLayoutItem fieldLayoutItem = ComponentAccessor.getFieldLayoutManager().getFieldLayout(parentIssue).getFieldLayoutItem(splituserlist);
//public ModifiedValue(Object oldValue, Object newValue)
ModifiedValue modValueObj =  new ModifiedValue(oldusers, users)
log.error "Perform the Update"
splituserlist.updateValue(fieldLayoutItem, parentIssue, modValueObj, changeHolder);
log.error "Check the update"
Collection<ApplicationUser> users2 = (Collection) parentIssue.getCustomFieldValue(splituserlist);
if(users2 != null)
{
  for(i in 0..users.size()-1)
  {
    Object AssigneeValue = users2.get(i).getName();
      log.error "List = " + AssigneeValue
    i++
  }
}

2 answers

1 accepted

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

1 vote
Answer accepted
Vasiliy Zverev
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 11, 2016

David, here is a code example how to update multiUser field. It works on my JIRA 6.4.

Main idea is to use MutableIssue object for update. At first we set all new values to all requred fields and then store it to database at once via issueManager.updateIssue.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.user.util.UserManager;

CustomFieldManager customFieldManager = componentManager.getCustomFieldManager();
CustomField splituserlist = customFieldManager.getCustomFieldObject(13901);

List<ApplicationUser> newMultiUser = new ArrayList<>();
UserManager userManager = ComponentAccessor.getUserManager();
newMultiUser.add(userManager.getUserByKey("userKey"))

IssueManager issueManager = ComponentAccessor.getIssueManager();
MutableIssue issue = null;//place some code get get requared issue
issue.setCustomFieldValue(splituserlist,newMultiUser);

issueManager.updateIssue(ComponentAccessor.getJiraAuthenticationContext().getUser().getDirectoryUser(), issue, EventDispatchOption.ISSUE_UPDATED, false)
David B January 11, 2016

Thanks. I merged in what you gave me and have worked out that the solution to the problem was adding to the collection using the UserManager. You used userManager.getUserByKey("userKey") and I changed it to userManager.getUserByName("userName") for my purpose. Just adding the user to the collection didn't work. It needs to be userManager.getUserBySomething

0 votes
David B January 11, 2016

Final Script after Vasiliy's help.

import com.atlassian.jira.ComponentManager;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder;
import com.atlassian.jira.issue.util.IssueChangeHolder;
import com.atlassian.jira.issue.customfields.impl.MultiUserCFType
import com.atlassian.jira.issue.fields.layout.field.FieldLayoutItem;
import com.atlassian.jira.issue.ModifiedValue;
import com.atlassian.jira.user.util.UserManager;
import com.atlassian.jira.user.ApplicationUser;
import com.atlassian.jira.user.ApplicationUsers;
import com.atlassian.jira.issue.UpdateIssueRequest
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.event.type.EventDispatchOption;
import com.atlassian.jira.issue.index.IssueIndexManager;
import com.atlassian.jira.user.ApplicationUser
import org.apache.log4j.Category;
import com.atlassian.jira.util.ImportUtils
 
log = Category.getInstance("com.onresolve.jira.groovy.PostFunction");
//---------------------
ComponentManager componentManager = ComponentManager.getInstance();
CustomFieldManager customFieldManager = componentManager.getCustomFieldManager();
CustomField splituserlist = customFieldManager.getCustomFieldObject("customfield_10061");
 
List<ApplicationUser> newMultiUser = new ArrayList<>();
UserManager userManager = ComponentAccessor.getUserManager();

//------------------------------
IssueManager issueManager = ComponentAccessor.getIssueManager();
//MutableIssue issue = null;//place some code get get requared issue
//MutableIssue issue = componentManager.getIssueManager().getIssueObject("FLONINE-688");
MutableIssue splitIssue = issue;
MutableIssue parentIssue = splitIssue.getParentObject();
List<ApplicationUser> users = (List) parentIssue.getCustomFieldValue(splituserlist);
boolean  addAssigned = true;
if(users != null)
{
  for(i in 0..users.size()-1)
  {
    Object AssigneeValue = users.get(i).getName();
    if( users.get(i).getName() == splitIssue.assignee.getName())
    {
      addAssigned = false;
        log.error "User found and exiting"
      // name found so exit.
      return; 
    }
    newMultiUser.add(userManager.getUserByName(users.get(i).getName()));
    i++
  }
}
if( addAssigned) newMultiUser.add(userManager.getUserByName(splitIssue.assignee.getName()))
parentIssue.setCustomFieldValue(splituserlist,newMultiUser);
 
issueManager.updateIssue(ComponentAccessor.getJiraAuthenticationContext().getUser().getDirectoryUser(), parentIssue, EventDispatchOption.ISSUE_UPDATED, false)
Vasiliy Zverev
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 12, 2016

I would like to add that there are a lot of unused import. It is enough: import com.atlassian.jira.ComponentManager; import com.atlassian.jira.component.ComponentAccessor; import com.atlassian.jira.issue.CustomFieldManager; import com.atlassian.jira.issue.MutableIssue; import com.atlassian.jira.issue.fields.CustomField; import com.atlassian.jira.user.util.UserManager; import com.atlassian.jira.issue.IssueManager; import com.atlassian.jira.event.type.EventDispatchOption; import com.atlassian.jira.user.ApplicationUser

Vasiliy Zverev
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 12, 2016

Variables AssigneeValue and addAssigned also are not used. I use Intellij Idea to write scripts and recommend it to everyone.

David B January 12, 2016

Thanks. I was going to go through it today and tidy up the imports and clean out the debugging. I realised yesterday that I need to set up a separate machine for groovy dev. I hate mixing dev environments and my day job is oracle and some .net ;-)

TAGS
AUG Leaders

Atlassian Community Events