My client wants to be able to create a filter for issues where Field A has been updated in the last 7 days. As Jira doesn't have the ability to filter for updates made to specific custom fields I am trying to set up another date custom field (Field B) and using a ScriptRunner Listener to add the date every time field A is updated.
I have used some of the logic provided in this post: https://community.atlassian.com/t5/Jira-questions/Scriptrunner-listener-to-update-custom-date-time-field/qaq-p/387444
Specifically, the code below (although have changed the field names as needed).
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
def cfm = ComponentAccessor.getCustomFieldManager()
def watch = cfm.getCustomFieldObjectByName("% Complete")
def watchValue = event.issue.getCustomFieldValue(watch)
def updatedWatch = cfm.getCustomFieldObjectByName("% Complete Updated")
def today = new java.sql.Timestamp(new Date().getTime())
if (event.getChangeLog().getRelated('ChildChangeItem').find{ it.field == '% Complete'}){
def changeHolder = new DefaultIssueChangeHolder()
updatedWatch.updateValue(null, event.issue, new ModifiedValue(null, today), changeHolder)
}
This seems to be working and whenever I update Field A, Field B is populated with the date. However, when trying to build a JQL search for "Field B" > -7d it is not returning results, and when I try "Field B" is not EMPTY I also get no results. However, if I search for the specific key of an issue with Field B populated I can see the date populated in the column.
As a test, I manually updated Field B with tomorrows date which allows me to search for it in the issue navigator based on "Field B". I then updated Field A again which caused the Listener to update Field B with today;s date and viewing the issue in the issue navigator the date has been updated correctly to today's date. BUT, my JQL searches still seem to read it as tomorrows date, which I entered manually.
The JQL search only seems to be able to interpret the data I have manually entered into the field, and disregards amendments made by the Listener. Have I missed something obvious in the Listener code or is it known behaviour that JQL cannot parse data entered onto a field by a ScriptRunner listener?
Seems to be reindex related.
Can you add the reindex action at the end of the script?
Found a reference in https://community.atlassian.com/t5/Jira-questions/Scriptrunner-reindex-an-issue/qaq-p/803412 but i haven't tested those snippets myself
Hi @Fazila Ashraf thank you for responding.
I have included some code found on the link you attached but unfortunately my listener is failing to execute correctly. The new code I am using is (changes in bold):
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.index.IssueIndexingService
import com.atlassian.jira.util.ImportUtils
def cfm = ComponentAccessor.getCustomFieldManager()
def watch = cfm.getCustomFieldObjectByName("% Complete")
def watchValue = event.issue.getCustomFieldValue(watch)
def updatedWatch = cfm.getCustomFieldObjectByName("% Complete Updated")
def today = new java.sql.Timestamp(new Date().getTime())
if (event.getChangeLog().getRelated('ChildChangeItem').find{ it.field == '% Complete'}){
def changeHolder = new DefaultIssueChangeHolder()
updatedWatch.updateValue(null, event.issue, new ModifiedValue(null, today), changeHolder)
}
def reIndexIssue(issue){
//Re-index the issue after update
boolean wasIndexing = ImportUtils.isIndexIssues()
ImportUtils.setIndexIssues(true)
ComponentAccessor.getComponent(IssueIndexingService.class).reIndex(issue)
ImportUtils.setIndexIssues(wasIndexing)
}
Have I arranged the code incorrectly?
I receive an error at line 25 ( ComponentAccessor.getComponent(IssueIndexingService.class).reIndex(issue) ) that states:
[Static type checking] - Cannot find matching method
com.atlassian.jira.issue.index.IssueIndexService#reIndex(java.lang.Object).
Please check if the declared type is correct and if the method exists.
Possible solutions: find() @ line 25, column 5.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
can you try changing def reIndexIssue(issue){ to def reIndexIssue(event.issue){
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I then get an "unexpected token" error at that line and when trying to save the listener get the below error:
The script could not be compiled:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: Script48.groovy: 21: unexpected token: ) @ line 21, column 29. def reIndexIssue(event.issue){ ^ 1 error
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Just noticed that you are not calling this function you defined, anywhere..
Can you use the below snippet in the bottom after removing the function definition part?
MutableIssue mutableIssue = ComponentAccessor.getIssueManager().getIssueObject(event.issue.getKey());
boolean isIndex = ImportUtils.isIndexIssues();
ImportUtils.setIndexIssues(true);
IssueIndexingService IssueIndexingService = (IssueIndexingService) ComponentAccessor.getComponent(IssueIndexingService.class);
IssueIndexingService.reIndex(mutableIssue);
ImportUtils.setIndexIssues(isIndex);
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Fazila, I have removed the reIndexIssue function and replaced it with the MutableIssue script. Unfortunately, I now get the below error:
The script could not be compiled:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: Script40.groovy: 21: unable to resolve class MutableIssue @ line 21, column 14. MutableIssue mutableIssue = ComponentAccessor.getIssueManager().getIssueObject(event.issue.getKey()); ^ 1 error
.
script below:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.index.IssueIndexingService
import com.atlassian.jira.util.ImportUtils
def cfm = ComponentAccessor.getCustomFieldManager()
def watch = cfm.getCustomFieldObjectByName("% Complete")
def watchValue = event.issue.getCustomFieldValue(watch)
def updatedWatch = cfm.getCustomFieldObjectByName("% Complete Updated")
def today = new java.sql.Timestamp(new Date().getTime())
if (event.getChangeLog().getRelated('ChildChangeItem').find{ it.field == '% Complete'}){
def changeHolder = new DefaultIssueChangeHolder()
updatedWatch.updateValue(null, event.issue, new ModifiedValue(null, today), changeHolder)
MutableIssue mutableIssue = ComponentAccessor.getIssueManager().getIssueObject(event.issue.getKey());
boolean isIndex = ImportUtils.isIndexIssues();
ImportUtils.setIndexIssues(true);
IssueIndexingService IssueIndexingService = (IssueIndexingService) ComponentAccessor.getComponent(IssueIndexingService.class);
IssueIndexingService.reIndex(mutableIssue);
ImportUtils.setIndexIssues(isIndex);
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You will have to add these import lines as well
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.MutableIssue;
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I can now save the listener successfully, but it still fails to execute successfully:
2023-04-17 11:23:29,296 ERROR [runner.AbstractScriptListener]: *************************************************************************************
2023-04-17 11:23:29,296 ERROR [runner.AbstractScriptListener]: Script function failed on event: com.atlassian.jira.event.issue.IssueEvent, file: null
java.lang.NullPointerException: Cannot invoke method updateValue() on null object
at Script59.run(Script59.groovy:20)
code:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.index.IssueIndexingService
import com.atlassian.jira.util.ImportUtils
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.MutableIssue
def cfm = ComponentAccessor.getCustomFieldManager()
def watch = cfm.getCustomFieldObjectByName("% Complete")
def watchValue = event.issue.getCustomFieldValue(watch)
def updatedWatch = cfm.getCustomFieldObjectByName("% Complete Updated")
def today = new java.sql.Timestamp(new Date().getTime())
if (event.getChangeLog().getRelated('ChildChangeItem').find{ it.field == '% Complete'}){
def changeHolder = new DefaultIssueChangeHolder()
updatedWatch.updateValue(null, event.issue, new ModifiedValue(null, today), changeHolder)
MutableIssue mutableIssue = ComponentAccessor.getIssueManager().getIssueObject(event.issue.getKey());
boolean isIndex = ImportUtils.isIndexIssues();
ImportUtils.setIndexIssues(true);
IssueIndexingService IssueIndexingService = (IssueIndexingService) ComponentAccessor.getComponent(IssueIndexingService.class);
IssueIndexingService.reIndex(mutableIssue);
ImportUtils.setIndexIssues(isIndex);
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.