Script throws exceptions when executed as scheduled job

Uwe Mannl July 1, 2020

Script throws Exception when executed as scheduled job

We have a strange problem with a workflow transition script.
Script shall run once a day. If a date in issues (custom field) has been reached, the issue shall be transitioned from waiting to working.

When it runs in the scriptrunner console, everything is fine.
When we create a custom scheduled job and set the same file as script, we have a lot of errors in the atlassian log, although the transition happens.
Tested with preview run of the scheduled job.
Once it also crashed the complete Jira instance, so we cannot use it currently :(

Error message indicates something with "date formatting", but the script itself has no date processing?!

We would appreciate any help!

script:

import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.issue.IssueInputParametersImpl
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.component.ComponentAccessor
import org.apache.log4j.Level
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.issue.comments.CommentManager


def issueService = ComponentAccessor.issueService
def commentManager = ComponentAccessor.commentManager

def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
def searchService = ComponentAccessor.getComponent(SearchService.class)


//log.setLevel(Level.ALL)

def wartend2bearbeitenTransitionId = 41 as Integer

def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser

// Issues im Status 'Wartend'
def query = jqlQueryParser.parseQuery("project = SGABL AND status = Wartend AND Wiedervorlage <= endOfDay()")
def result = searchService.search(user, query, PagerFilter.getUnlimitedFilter())

// Vorgänge nach Bearbeiten überführen
result.getResults().each { issue ->

IssueInputParameters issueInputParameters = new IssueInputParametersImpl([:])
def validationResult = issueService.validateTransition(user, issue.id, wartend2bearbeitenTransitionId, issueInputParameters)
def errorCollection = validationResult.errorCollection

if (!errorCollection.hasAnyErrors()) {
issueService.transition(user, validationResult)
commentManager.create(issue, user, "Bot: Wiedervorlagedatum erreicht, Vorgang auf 'In Bearbeitung' gesetzt.", true)
} else {
log.error(errorCollection.errorMessages)
}

}

atlassian-jira.log:

2020-07-02 07:04:05,047+0200 http-nio-8080-exec-22 ERROR 0152M 424x18699x1 1bavjwx 130.93.1.168,10.214.22.80 /rest/scriptrunner/latest/scheduled-jobs/com.onresolve.scriptrunner.canned.jira.jobs.JiraCustomScheduledJob/preview [c.a.p.r.c.error.jersey.ThrowableExceptionMapper] Uncaught exception thrown by REST service: null
java.lang.StackOverflowError
at java.text.SimpleDateFormat.zeroPaddingNumber(SimpleDateFormat.java:1358)
at java.text.SimpleDateFormat.subFormat(SimpleDateFormat.java:1149)
at java.text.SimpleDateFormat.format(SimpleDateFormat.java:966)
at java.text.SimpleDateFormat.format(SimpleDateFormat.java:936)
at java.text.DateFormat.format(DateFormat.java:345)
at groovy.json.JsonOutput.writeDate(JsonOutput.java:363)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:290)
...
at groovy.json.JsonOutput.writeObject(JsonOutput.java:332)
at groovy.json.JsonOutput.writeIterator(JsonOutput.java:486)
2020-07-02 07:04:10,858+0200 Structure-Jobs69ee99a9 Generator-Thread#17 INFO 0062D<-0062D 797x1953x1 1soiuuw 130.93.1.136,10.214.22.80 /rest/structure/2.0/poll [c.a.jira.index.MonitoringIndexWriter] [lucene-stats] flush stats: snapshotCount=23, totalCount=271, periodSec=340, flushIntervalMillis=14805, indexDirectory=/konsens/data/jira/caches/indexesV1/issues, indexWriterId=com.atlassian.jira.index.MonitoringIndexWriter@22a94360, indexDirectoryId=MMapDirectory@/konsens/data/jira/caches/indexesV1/issues lockFactory=org.apache.lucene.store.NativeFSLockFactory@5c748f9e
2020-07-02 07:04:11,039+0200 Structure-Jobs69ee99a9 Generator-Thread#17 : Generating #144 (structure:41) ERROR 0062D<-0062D 797x1953x1 1soiuuw 130.93.1.136,10.214.22.80 /rest/structure/2.0/poll [o.o.c.entity.jdbc.SQLProcessor] !!! ABANDONED SQLProcessor DETECTED !!!
This probably means that somebody forgot to close an EntityListIterator.
Connection: com.atlassian.jira.diagnostic.connection.DiagnosticConnection@32942ec4
SQL: SELECT ID, ENTITY_NAME, ENTITY_ID, PROPERTY_KEY, propertytype FROM propertyentry WHERE ENTITY_NAME=? AND ENTITY_ID=? AND PROPERTY_KEY=?

Jira version: 8.5.3
Scriptrunner version: 5.6.15.1-p5

1 answer

0 votes
Leonard Chew
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.
July 1, 2020

Hi there.

Difficult to say what it is. It seems to be some kind of date format exception.

The only date related thing I see is that you query on 

endOfDay()

leading me to the question: At what time is the batch job executed? - Could it be related to "endOfDay" not being correct, because Midnight has passed?

Anyway, what I'd do is test it on your TEST-System. Here are some ideas of mine:

  • Write a Debug Log Statement after each line
  • Strip the query down to Issues you know that are effected (e.g. key=MYKEY-1), so that you can narrow down to specific issues (error might be caused by data in issues)
  • Check your postfunctions and validators on your transition
  • Check all your date fields involved in this process
  • Check the time of your batchjob and how it relates to "endOfDay"
Uwe Mannl July 2, 2020

Hi Leonard,

thanks for your response!

In the meantime I found a solution, so it seems the exceptions with date were just a consequence of another problem.

Below you can find the working script.

From what I understand it was a BAD idea to use an iterator over the query result (result.getResults().each { issue -> ... }), because the transition of issues to another state modified the query result (which depends to a specifiv state) and the iterator was struggling with that.

We now use a result list and everything works like expected:

def issues = result.getResults()
for (def issue : issues) { ... }

I still don't understand why everything was fine when processing the script (with closure) manually :-/

import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.issue.IssueInputParametersImpl
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.component.ComponentAccessor
import org.apache.log4j.Level
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.issue.comments.CommentManager
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.event.type.EventDispatchOption


def issueService = ComponentAccessor.issueService
def issueManager = ComponentAccessor.issueManager
def commentManager = ComponentAccessor.commentManager

def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
def searchService = ComponentAccessor.getComponent(SearchService.class)


//log.setLevel(Level.ALL)

def wartend2bearbeitenTransitionId = 41 as Integer

def jobUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser

// Issues im Status 'Wartend'
def query = jqlQueryParser.parseQuery("project = SGABL AND status = Wartend AND Wiedervorlage <= endOfDay()")
def result = searchService.search(jobUser, query, PagerFilter.getUnlimitedFilter())

// Vorgänge nach Bearbeiten überführen
def issues = result.getResults()
for (def issue : issues) {

def mutableIssue = issueManager.getIssueObject(issue.id)
def issueAssigneeId = issue.assigneeId

IssueInputParameters issueInputParameters = new IssueInputParametersImpl([:])
def validationResult = issueService.validateTransition(jobUser, issue.id, wartend2bearbeitenTransitionId, issueInputParameters)
def errorCollection = validationResult.errorCollection

if (!errorCollection.hasAnyErrors()) {
// Transition
issueService.transition(jobUser, validationResult)

// set sssignee
def validateAssignResult = issueService.validateAssign(jobUser, issue.id, issueAssigneeId)
issueService.assign(jobUser, validateAssignResult)

// add comment
commentManager.create(issue, jobUser, "Bot: Wiedervorlagedatum erreicht, Vorgang auf 'In Bearbeitung' gesetzt.", true)
} else {
log.error(errorCollection.errorMessages)
}
}
Like # people like this
Christoffer Karlsson March 10, 2021

Thank you so much for this Uwe!

I was stuck with almost the exact same problem and changing how we iterate the issue search result solved everything.

Regards
Chris

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events