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

Is there a way to have scriptrunner reliably update dependent classes?

Corey Leighton July 2, 2021

We have quite a few scriptrunner items that pull in lists of data to function, one example is we have a table that maps our products to the development team associated with it.  This mapping list shows up in several places; post-functions, listeners, scripted fields, etc... To make updates easier and less prone to mistakes, I moved it to a class (in scripts/Classes).  The problem we are encountering is that updates to the class file are not picked up unless we issue a groovy class/cache reset... which has a domino effect of breaking the custom JQL functions we have loaded, requiring a re-scan.... which breaks some filters, which breaks dashboards, etc.  It can be quite clumsy.

This is mentioned in the documentation, but is there any way to avoid it?  Some super secret handshake or clever trick to assure that changes to a dependent class like the one I mentioned are picked up immediately?

2 answers

1 accepted

Suggest an answer

Log in or Sign up to answer
2 votes
Answer accepted
Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
July 2, 2021

I tend to just clear the groovy cache as I don't have the same JQL dependency you describe.

But frequent change to a class file should only happen in a dev/test environment where you shouldn't care about this dependency, and only when doing the final deployment to prod would you need to rescan your JQL.

Maybe someone has a better way ... but if you're willing to give up on some performance, at least in your dev environment, you could always load your class dynamically like this:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.config.util.JiraHome

def
jiraHome = ComponentAccessor.getComponent(JiraHome).home
Class YourClass = new GroovyClassLoader(getClass().classLoader).parseClass(new File("$jiraHome/scripts/path/to/YourClass.groovy"))

But that's not suitable for a production environment since the class has to be loaded and compiled each time you use it.

Corey Leighton August 2, 2021

Well, for our purposes, it might work.  If this call 'sticks', i.e. it will refresh the class in the main cache, then we could call this if, and only if, there's an update to the class... maybe add something to the built-in scripts so it can be a one-click operation.  I've been attempting this recently, but hadn't managed to figure out the syntax...  time wasted had I checked this thread earlier!

Thanks!

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
August 2, 2021

This particular snippet doesn't refresh the cache.

In you have another script somewhere else that calls the class you just updated, it will still be the old version of the class unless you refresh the cache using the built-in script.

The above simply loads the class from file with each execution without caching it.

If you want to dynamically clear the cache, you can add these lines to your script:

import com.onresolve.scriptrunner.canned.jira.admin.JiraClearCaches
new JiraClearCaches().doScript(["FIELD_WHICH_CACHE":"gcl"])
Like Ilya Turov likes this
Corey Leighton August 2, 2021

What I am targeting is to clear/refresh the cache only for the updated class.  So, if I updated Classes/MyCustomFields.class  I can run/do something that does a persistent, targeted refresh of MyCustomFields only so the rest of the system can see the updates.

Curiously enough, it appears that the 'Preview' button when testing a Scripted Field does this.  If you test a given scripted field, it seems to trigger a full file reload and re-caching of any dependent classes.  And (as an added bonus) it somehow clears up whatever fault 'broke' the auto-refresh when an edit to a dependent class file occurs.... so there's no longer any need to fuss with anything as the class is updated as soon as you edit the class's file.

I have to look into what's going on here... I am not a 'pay no attention to the man behind the curtain' kind of person so I need to investigate what about 'Preview' makes it the great cure-all.  And I want to try to figure out what caused the auto-recache to stop working in the first place.

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
August 2, 2021

Yeah, you'd have to dig into the scriptrunner caching mechanism to figure out how to reload just a single class.

0 votes
Artur Salamon February 23, 2022

@Peter-Dave Sheehan 

import com.onresolve.scriptrunner.canned.jira.admin.JiraClearCaches
new JiraClearCaches().doScript(["FIELD_WHICH_CACHE":"gcl"])

Getting an error:

Could not find matching constructor for: com.onresolve.scriptrunner.canned.jira.admin.JiraClearCaches()

I am searching a way to do this groovy class loader cache clear via script in Scriptrunner.

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
February 23, 2022

Here is the new method for getting and executing a built-in script:

import com.onresolve.scriptrunner.canned.jira.admin.JiraClearCaches
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
def clearCaches = ScriptRunnerImpl.scriptRunner.createBean(JiraClearCaches)
clearCaches.doScript(["FIELD_WHICH_CACHE":"gcl"])
Ilya Stekolnikov
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.
March 2, 2022

@Corey Leighton Hi? did you find working method?

Corey Leighton March 2, 2022

@Ilya Stekolnikov I haven't, but I haven't tried the new method mentioned in the post from 2-23-2022 yet either.  But even if it does, it wouldn't be 'automatic' in the sense that changes would still require the additional additional step of reloading the cache  when deploying script changes (so clicking 'clear cache' is in some respects just as easy). 

I did resolve the problem where a groovy refresh would break the custom JQL functions (it was related to a case mismatch in class names), so the groovy refresh isn't a rough operation, so that was a big improvement. 

At this point, I think the only full solution would require changes to how scriptrunner detects and reloads file changes.

TAGS
AUG Leaders

Atlassian Community Events