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

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

Accepted Answer
1 vote

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 

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)

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.

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

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.

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.

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.

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.)

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

M. 

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)

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.

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.

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.

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.

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.

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(); 

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.

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);
...

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"

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());

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.

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);

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());

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. 

What version of JIRA are you using?

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.

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

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

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

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

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

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!

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

Accepted and voted!

Suggest an answer

Log in or Sign up to answer
Community showcase
Posted Sep 25, 2018 in Jira

Atlassian Research Workshop opportunity on Sep. 28th in Austin, TX

We're looking for participants for a workshop at Atlassian! We need Jira admins who have interesting custom workflows, issue views, or boards. Think you have a story to sha...

465 views 7 5
Join discussion

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you