Come for the products,
stay for the community

The Atlassian Community can help you and your team get more value out of Atlassian products and practices.

Atlassian Community about banner
4,362,527
Community Members
 
Community Events
168
Community Groups

What does @WithPlugin do?

I know that it gets used when accessing other plugins in scriptrunner code but

  • What does it apply to?
    • The next line of code?
    • The entire source file?
  • What exactly is it doing?
    • Providing access to class definitions in those plugins?
  • Where should it appear in your code?
    • before using those classes?

Should I be able to use @WithPlugin with @Field? Is there anything I need to do differently?

1 answer

1 accepted

0 votes
Answer accepted

Hello, 

There's a description of what @WithPlugin does available in the ScriptRunner documentation, here. It should appear before you use the classes from another plugin, at the top of the file. What is does in short is that it grabs the classloader from the plugin you specify and adds it to the list of classloaders that get loaded when your script compiles. Thus, classes loaded by that plugin should be made available on the script you're writing. There are a few examples of it being used in the docs as well, such as with Tempo here. As far as using it with @Field, I believe you should be able to but I haven't tested this at all, so no guarantees.

Hopefully this helps you out. :)

Jenna

Thank you for your answer. This helps make sense of some of the results I've been getting from my tests

  • You need to clear the groovy class loader cache between tests otherwise groovy remembers the loader from a previous run (makes testing very confusing)
  • if you don't have the @WithPlugin anywhere in your script, then the corresponding import statements won't work (test 1 code below)
  • If you have 2 @WithPlugin statements in a single script, then you get the error "Cannot specify duplicate annotation on the same member". This never used to happen. (test 2 code below). The solution is to pass in a string array.
  • A script that doesn't do anything (only imports and @WithPlugin) cannot start due to "unexpected token: @ line 5, column 50" (test 3 and 4 code below)
  • Some classes have class loaders in  multiple plugin key (test 5 code below). I'm not sure how that works since the class lives in just one jar
  • If I assign a team manager field as I have done in test code 6 below, the value will be null (without the @Field it is non null)
  • If I assign it as I do in test code 7 below, the value is not null

BTW the reason for all these tests is I've been getting a lot of random java.lang.NoClassDefFoundError for scripts with the @WithPlugin statements and random changes seemed to temporarily fix the issue but I had no idea why. Still don't. Maybe it has something to do with the class loader cache.

code for each test

Test 1

import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
import com.tempoplugin.team.api.TeamManager
//@WithPlugin("com.tempoplugin.tempo-teams")

TeamManager teamManagerTemp = ScriptRunnerImpl.getPluginComponent(TeamManager)

Test 2

import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
import com.tempoplugin.team.api.TeamManager
@WithPlugin("com.tempoplugin.tempo-teams")
@WithPlugin("com.tempoplugin.tempo-platform-api")

TeamManager teamManagerTemp = ScriptRunnerImpl.getPluginComponent(TeamManager)

Test 3

import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
import com.tempoplugin.platform.api.user.TempoUser

@WithPlugin("com.tempoplugin.tempo-platform-api")

Test 4

import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
import com.tempoplugin.platform.api.user.TempoUser

@WithPlugin("com.tempoplugin.tempo-platform-api")

def x = null

Test 5

import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
import com.tempoplugin.platform.api.user.TempoUser

//Either of these 2 lines will work
//@WithPlugin("com.tempoplugin.tempo-platform-api")
@WithPlugin("com.tempoplugin.tempo-teams")

def x = null

Test 6

import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
import groovy.transform.Field
import com.tempoplugin.team.api.TeamManager
@WithPlugin("com.tempoplugin.tempo-teams")

@Field TeamManager teamManagerTemp = ScriptRunnerImpl.getPluginComponent(TeamManager)

Test 7

import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
import groovy.transform.Field
import com.tempoplugin.team.api.TeamManager
@WithPlugin("com.tempoplugin.tempo-teams")

@Field TeamManager teamManager
teamManager = ScriptRunnerImpl.getPluginComponent(TeamManager)

That sounds like you might be running into this bug, SRPLAT-77, depending on what version on SR you're using. If you keep having trouble with this or if you're on a version of SR where that bug is fixed I recommend that you submit a support inquiry over on the Adaptavist support site. We'd be able to get some more information from you over there that might help to get this working or identify the issue.

Jenna 

Suggest an answer

Log in or Sign up to answer
TAGS

Atlassian Community Events