Scriptrunner - add user from custom field (user picker) to watchers

Maya_Chase August 28, 2017

Hi, I'm very new to Scriptrunner, and I need help! I want to grab the user from a custom field (Business Analyst) and add them to Watchers. I cobbled together a script from a couple of other similar questions here, took out what it looked like I didn't need (and maybe took out too much!), and came up with this:

import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.component.ComponentAccessor;

def cf1 = customFieldManager.getCustomFieldObjectByName("Business Analyst");
def userid = issue.getCustomFieldValue(cf1);
def watcherManager = ComponentAccessor.getWatcherManager();
def userManager = ComponentAccessor.getUserManager();
def user = userManager.getUserObject("userid");

if (user) watcherManager.startWatching(user, issue.genericValue);

On the last line, I get the error [Static type checking] - Cannot find matching method com.atlassian.jira.issue.watchers.WatcherManager#startWatching(com.atlassian.jira.org.ofbiz.core.entity.GenericValue). Please check if the declared type is right and if the method exists.

If someone could help me straighten this out, I would really appreciate it.

 

1 answer

1 accepted

2 votes
Answer accepted
MoroSystems Support
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.
August 28, 2017

Hello Maya,

javadoc for WarcherManager says 

startWatching(ApplicationUser user, Issue issue)

Have you tried to write last line as

 if (user) watcherManager.startWatching(user, issue);

?

Milos 

Maya_Chase August 28, 2017

That got rid of the error, but it didn't actually add the Business Analyst to the watchers. :(

Running the script gave me this: 

The following log information was produced by this execution. Use statements like:log.info("...") to record logging information.

2017-08-28 14:24:52,338 ERROR [workflow.ScriptWorkflowFunction]: *************************************************************************************
2017-08-28 14:24:52,338 ERROR [workflow.ScriptWorkflowFunction]: Script function failed on issue: null, actionId: 1, file: <inline script>
groovy.lang.MissingPropertyException: No such property: customFieldManager for class: Script173
	at Script173.run(Script173.groovy:6)
Maya_Chase August 28, 2017

PS. I updated the first def to:

def cf1 = CustomFieldManager.getCustomFieldObjectsByName("Business Analyst");

So now it has an error for the line:

def userid = issue.getCustomFieldValue(cf1);

[Static type checking] - Cannot find matching method com.atlassian.jira.issue.MutableIssue#getCustomFieldValue(java.utilCollection <com.atlassian.jira.issue.fields.CustomField>). Please check if the declared type is right and if the method exists.

Hmm.

MoroSystems Support
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.
August 28, 2017

You are missing line:

def customFieldManager = ComponentAccessor.getCustomFieldManager();

before the line:

def cf1 = customFieldManager.getCustomFieldObjectByName("Business Analyst");

 Everything you want to use, has to be declared.

Milos

MoroSystems Support
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.
August 28, 2017

getCustomFieldObjectsByName() method returns Collections of CustomFields. 

getCustomFieldValue() method requires only single CustomField as input parameter.

 

So try to get first item from the returned collection:

def userid = issue.getCustomFieldValue(cf1.get(0));

 

M.

Maya_Chase August 28, 2017

Thank you very much. I now have a script that reads:

import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.MutableIssue;

def customFieldManager = ComponentAccessor.getCustomFieldManager();
def cf1 = customFieldManager.getCustomFieldObjectsByName("Business Analyst");
def userid = issue.getCustomFieldValue(cf1.get(0));
def watcherManager = ComponentAccessor.getWatcherManager();
def userManager = ComponentAccessor.getUserManager();
def user = userManager.getUserObject("userid");

if (user) watcherManager.startWatching(user, issue);

However, it's still erroring on the def userid line: [Static type checking] - Cannot find matching method java.util.Collection#get(int). Please check if the delared type is right and if the method exists. Possible solutions: grep(), grep(), getAt(int), grep(java.lang.Object), grep(java.lang.Object), getAt(java.lang.String) @ line 9, column 40.

[Static type checking] - Cannot find matching method com.atlassian.jira.issue.MutableIssue#getCustomFieldValue(com.onresolve.scriptrunner <can't read the rest> Please check if the declasred type is right and if the method exists. @ line 9, column 14.

MoroSystems Support
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.
August 28, 2017

Sorry, my mistake. I didnt realize that Collection does not have get() method. 

Use Iterator instead. Change it to:

def userid = issue.getCustomFieldValue(cf1.iterator().next());

M.

Maya_Chase August 28, 2017

Thank you, that got rid of the matching method errors. However, when creating the issue (the script is on the initial "create" transition), it didn't add the Business Analyst to the watchers, and I'm back to the run-time error like in my first reply (their spam filter won't let me re-post it, but it looks to be the same one.)

MoroSystems Support
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.
August 28, 2017

What exception did you get? Please post the log messages here. Without that, it's hard to find the problem.

M. 

Maya_Chase August 28, 2017

I think this is it:

Target exception: java.lang.NullPointerException
    
    Navigate to the following URL to edit the formula: https://resource.marketo.com/jira/secure/admin/EditCustomField!default.jspa?id=15266
2017-08-28 16:19:37,059 http-nio-8080-exec-3 ERROR machase 979x4766061x2 1odegs2 10.0.249.234,10.0.19.249,0:0:0:0:0:0:0:1 /secure/CreateIssueDetails.jspa [c.o.scriptrunner.customfield.GroovyCustomField] *************************************************************************************
2017-08-28 16:19:37,059 http-nio-8080-exec-3 ERROR machase 979x4766061x2 1odegs2 10.0.249.234,10.0.19.249,0:0:0:0:0:0:0:1 /secure/CreateIssueDetails.jspa [c.o.scriptrunner.customfield.GroovyCustomField] Script field failed on issue: TEST-5, field: LocationUser
java.lang.NullPointerException: Cannot invoke method getValue() on null object
 at Script2.run(Script2.groovy:3)
Maya_Chase August 28, 2017

Hmm, no, that's for field LocationUser, which I'm not even using.

Sorry, I'm looking in atlassian-jira.log, I don't know where else to look. I'm trying to find information on logging for scriptrunner, but all the references I've found so far, either the pages are moved, or I simply don't understand the instructions, sorry. If you know of a *simple* guide to getting scriptrunner to spit out log messages and where to find them, that would be great. Otherwise I'll keep reading and trying to figure this out.

MoroSystems Support
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.
August 29, 2017

You can use logging in your script:

log.setLevel(org.apache.log4j.Level.DEBUG);
log.debug("Your message...");

Then you should see log messages in atlassian-jira.log.

So try to log everything you use in your script to check if all is properly set (issue, user, input params and so on).

I think, you can also find some logs in post function settings. There should be logs for the last post function executions.

M.

Maya_Chase September 5, 2017

Hi, sorry for the delay in getting back to this, and thank you so much for your pointers so far. Ok, so, I have logging set up:


log.setLevel(org.apache.log4j.Level.DEBUG);
log.debug("userid ${userid} and user ${user} and issue ${issue}");


And from this I know that userid is set, and issue is the issue I'm creating, but user is null:

userid sthompson(sthompson) and user null and issue TEST-12

 

I'm thinking it's the userid that's the problem, because it's that nested structure, and userManager is just expecting a user id, but I'm not sure how to fix it, because I am using the line from a comment above:

 

def userid = issue.getCustomFieldValue(cf1.iterator().next());

 

and I'm not sure exactly what it's doing. Simplifying to def userid = issue.getCustomFieldValue(cf1); doesn't work, I get another "check if declared..." error even though the doc for issue.getCustomFieldValue() just says it takes a custom field and returns the custom field's value.

Maya_Chase September 5, 2017

ps. I tried simplifying to:

 

def cf1 = customFieldManager.getCustomFieldObjectByName("Business Analyst");
def userid = issue.getCustomFieldValue(cf1);

There's no error that way, but my userid and user are the same as above.

Maya_Chase September 5, 2017

pps. Went back to getCustomFieldObjectsByName, since Object is deprecated. Broke up the defs thus:

def BA = cf1.iterator().next();
def userid = issue.getCustomFieldValue(BA);

My logging now shows that BA is Business Analyst, and userid is still sthompson(sthompson). Looked up the iterator() bit and think I understand a little better now, and it appears to be doing what it's supposed to be doing. So, good.

Can't wrap my head around why getCustomFieldValue is returning sthompson(sthompson), though, instead of just sthompson. No idea how to make it return the singular value.

MoroSystems Support
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.
September 5, 2017

Maya, if the custom field is of Single user picker type, I think that returned value will be probably of ApplicationUser type. In Java it would be:

ApplicationUser user = issue.getCustomFieldValue(BA);

You can get the user name:

user.getUsername(); 
Maya_Chase September 5, 2017

I'm sorry, I don't understand where to use user.getUsername();

My current defs look like:

def customFieldManager = ComponentAccessor.getCustomFieldManager();
def cf1 = customFieldManager.getCustomFieldObjectsByName("Business Analyst");
def BA = cf1.iterator().next();
def userid = issue.getCustomFieldValue(BA);
def watcherManager = ComponentAccessor.getWatcherManager();
def userManager = ComponentAccessor.getUserManager();
def user = userManager.getUserByName(userid);

I get an error on the last one of "cannot find matching method com.atlassian.jira.user.util.UserManager#getUserByName(java.lang.Object). Please check if the declared type is right and if the method exists.

Apparently this is because userid is of the wrong type, ApplicationUser instead of a string, but I've tried

def user = userManager.getUserByName(userid.getUsername()):

and 

def username = userid.getUsername();

def user = userManager.getUserByName(username);

and both of those also give me errors of the "cannot find matching method" variety. So, I'm sorry, I know I'm missing something obvious.

MoroSystems Support
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.
September 5, 2017

If you get ApplicationUser object from custom field, you don't need UserManager at all and I think following code should work:

...
ApplicationUser user = issue.getCustomFieldValue(BA);
if (user!=null) watcherManager.startWatching(user, issue);
...
Maya_Chase September 5, 2017

Thank you again. Unfortunately it gives the error "Cannot assign value of type java.lang.Object to variable of type com.atlassian.jira.user.ApplicationUser"

MoroSystems Support
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.
September 5, 2017

I just tried that and for custom field of type User Picker (single user) it returns instance of com.atlassian.jira.user.DelegatingApplicationUser which implements ApplicationUser interface, so:

  • check custom fields in JIRA called Bussiness Analyst
  • if there are more fields with the same name, your script probably works with a wrong custom field which is not of single user picker type
  • in this case you can use this method to get correct custom field based on its ID.
  • if it does not work try to log the type of value returned using:
    • log.debug(user.getClass());
Maya_Chase September 7, 2017

Nope, only one field called Business Analyst, and it's a user picker (single user). I added log.debug(user.getClass()); to the script but it doesn't put anything in the output log.

Maya_Chase September 7, 2017

This is my current script:

import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.user.ApplicationUser;

def customFieldManager = ComponentAccessor.getCustomFieldManager();
def cf1 = customFieldManager.getCustomFieldObjectsByName("Business Analyst");
def BA = cf1.iterator().next();
def watcherManager = ComponentAccessor.getWatcherManager();
def userManager = ComponentAccessor.getUserManager();

ApplicationUser user = issue.getCustomFieldValue(BA);

log.setLevel(org.apache.log4j.Level.DEBUG);
log.debug(user.getClass());
log.debug("user ${user} and issue ${issue}");

if (user!=null) watcherManager.startWatching(user, issue);

MoroSystems Support
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.
September 7, 2017

It does not log that because it's failing on exception you mentioned right?

Change your script to:



import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.user.ApplicationUser;

def customFieldManager = ComponentAccessor.getCustomFieldManager();
def cf1 = customFieldManager.getCustomFieldObjectsByName("Business Analyst");
def BA = cf1.iterator().next();
def watcherManager = ComponentAccessor.getWatcherManager();
def userManager = ComponentAccessor.getUserManager();

def user = issue.getCustomFieldValue(BA);

log.setLevel(org.apache.log4j.Level.DEBUG);
log.debug(user.getClass());
Maya_Chase September 7, 2017

I take back what I said about the logging, I must have overlooked it, but here it is:

2017-09-07 12:24:10,808 DEBUG [workflow.ScriptWorkflowFunction]: class com.atlassian.jira.user.DelegatingApplicationUser
2017-09-07 12:24:10,808 DEBUG [workflow.ScriptWorkflowFunction]: user sthompson(sthompson) and issue TEST-20

Now here's the weird part. I just did a test issue and even though there's still an error in the script, the Business Analyst was actually added to the watchers list. 

MoroSystems Support
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.
September 7, 2017

What version of JIRA are you using?

Maya_Chase September 7, 2017

7.2.2

Maya_Chase September 7, 2017

I changed the script to what you have above, and it gives a "cannot find matching method ..." error on the last line:

if (user!=null) watcherManager.startWatching(user, issue);

but again, it does actually assign the Business Analyst to the watchers. Very weird.

MoroSystems Support
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.
September 7, 2017

ok, I'm stupid...just change ApplicationUser user to def user, it should work without exception now...

MoroSystems Support
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.
September 7, 2017

sorry, I didn't notice your last post...can we summarize that? can you add your current script and whole exception's stack trace?

MoroSystems Support
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.
September 7, 2017

ok I've got it...just use this at the end of your script:

if (user!=null) {
watcherManager.startWatching((ApplicationUser)user, issue);
}

this part is important:

(ApplicationUser)user

Like Vladislav likes this
Maya_Chase September 7, 2017

Sure thing. Here's the script:

import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.user.ApplicationUser;

def customFieldManager = ComponentAccessor.getCustomFieldManager();
def cf1 = customFieldManager.getCustomFieldObjectsByName("Business Analyst");
def BA = cf1.iterator().next();
def watcherManager = ComponentAccessor.getWatcherManager();
def userManager = ComponentAccessor.getUserManager();
def user = issue.getCustomFieldValue(BA);

log.setLevel(org.apache.log4j.Level.DEBUG);
log.debug(user.getClass());
log.debug("BA ${BA} and user ${user} and issue ${issue}");

if (user!=null) watcherManager.startWatching(user, issue);

-----------

Error on last line: [Static type checking] Cannot find matching method com.atlassian.jira.watchers.WatcherManager#startWatching(java.lang.Object, com.atlassian.jira.issue.MutableIssue). Please check if the declared type is right and if the method exists.

-----------

Log messages: 

2017-09-07 12:35:54,572 DEBUG [workflow.ScriptWorkflowFunction]: class com.atlassian.jira.user.DelegatingApplicationUser
2017-09-07 12:35:54,573 DEBUG [workflow.ScriptWorkflowFunction]: BA Business Analyst and user sthompson(sthompson) and issue TEST-21
Maya_Chase September 7, 2017

Oops, we were posting at the same time. Ok, let me try that last line.

Maya_Chase September 7, 2017

OMG IT HAS NO ERRORS AND IT WORKED!! THANK YOU, THANK YOU!! 

I really appreciate your time and effort and hanging in there with me! You rock!

MoroSystems Support
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.
September 7, 2017

you're welcome :) please accept the answer :)

Maya_Chase September 7, 2017

Accepted and voted!

Suggest an answer

Log in or Sign up to answer