Intro
(If you haven’t read the previous post in this series, I highly recommend starting with that.)
In order to make use of the Jira API documentation, we need to understand what classes, packages, and methods are. That’s because the JIRA API is documented, but only in the most technical sense. It is predicated on you having some knowledge of Java. You can go to https://docs.atlassian.com/software/jira/docs/api/latest and get information about all of the internal libraries that Jira uses to function, but it’s not much good to you without that prior knowledge.
At the same time, knowing how to read and make use of the API documentation is a vital skill when it comes to working with ScriptRunner. All of Jira’s functionality is available for you to use, but only if you can harness it through the power of classes.
What’s the Problem?
The problem I ran into when I was first starting to learn how to use ScriptRunner is that very little is written in a context that a beginner could make use of, and few examples are provided. A lot of the Jira’s internal functions are interdependent, and someone who is new to both Groovy and Jira might find themselves struggling to make sense of it.
While I now have some experience in making use of the documentation, a great deal of what I do is still trial and error. I have found much more success in identifying a library or class that might do what I need it to do, and then Googling for examples of people putting that class into active use. I’ve often found scripts that include both the primary class I was looking at, and the necessary related classes to make it useful.
Even still, sometimes I run into a problem I’m not sure how to solve. This weekend I was trying to implement a package that is fully referenced in the documentation, because I was working on a blog post about unit testing with Groovy. The package is com.atlassian.jira.functest.framework.assertions.* No matter what I did, ScriptRunner just couldn’t find it. As it turns out, even if a library is documented, that doesn’t mean that it’s necessarily available to all apps. That’s just how it be.
Let’s briefly look at how we might make use of a library or class that is available to an app like ScriptRunner.
What is All of This Stuff?
Jira is written in Java, and uses a collection of Java code to run. The code is made up of classes, which are collections of methods, which are literally the method by which Jira operates. Packages are collections of classes.
In other words, whenever Jira wants to do something it calls upon a method, which is stored in a class. Related classes (such as classes involved in managing or working with projects) are stored in a collection called a package.
There’s a lot more to Java classes and packages than that, but that’s enough to get us started.
Importing Classes and packages
So you’ve got your ScriptRunner script console open, and you’ve imported your Component Accessor. You’ve even declared the Component Accessor as something you’d like to work with. Now what?
import com.atlassian.jira.component.ComponentAccessor
def component = ComponentAccessor.getComponent()
If you put your cursor between the brackets after getComponent() and hit any letter, you’ll get a list of available methods that start with that letter. However, none of them are particularly useful. To do anything with the Component Accessor, we need to import a package or class with which we’d like to work. In this example, we’re going to use a class that allows us to work with projects. In this case, let’s look at the documentation for the ProjectManager class.
If you click the link above, you’ll find yourself on a page with a whoollllle lot of information. Once you know what you’re looking at and what to look for, I promise it’ll make more sense.
On that page, if we look above where it says Interface ProjectManager, you’ll see that it says com.atlassian.jira.project. That is the package in which the ProjectManager class lives (remember, related classes are often grouped together in a package). ProjectManager isn’t the only class that lives within this package, but it’s the one we’re after.
From this page, or any similar page in the documentation, we can assemble our import. We start by importing the package, and then the class. In this case, the class is ProjectManager:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.project.ProjectManager
def component = ComponentAccessor.getComponent()
So we’ve told the ScriptRunner console that we wish to import the ProjectManager class, which is stored in the Project package.
Making Use of Your Import
We’re not actually making use of the ProjectManager class yet, but the script console is now aware that you’d like to use it in your script. If you wanted to import every class in the package, you could simply import com.atlassian.jira.project.*. For the sake of simplicity, however, we’ll stick to importing the single class.
Once again put your cursor between the brackets () after getComponent.
Now type the name of the class that you’d like the Component Accessor to access. In this case, you’re typing ProjectManager (capitalization is important). The words you type should be a nice shade of green. While we’re at it, let’s rename the object you’re creating from component to projectManager. Notice the difference in capitalization between our reference to the class, and the name we gave the object. This is enough to differentiate them, as Groovy is case-sensitive:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.project.ProjectManager
def projectManager = ComponentAccessor.getComponent(ProjectManager)
We now have an object that instantiates (is an instance of) the ProjectManager class, and we can move on to exploring its methods.
working with methods
Before we go any further, let’s recap. We’ve imported our Component Accessor, with which we’ll access the functions of the Jira internal libraries. We’ve also imported the ProjectManager class, and used the Component Accessor to access it and to create an object called projectManager.
Now what?
We have our class, and we have an object that contains the details of that class. Now we get to access the methods of the ProjectManager class. These methods are literally the functions by which the class accomplishes what it is designed to do.
Going back to the Jira documentation page for ProjectManager, we see a section called Method Summary. Below this is a list of all the methods available to us through the ProjectManager class.
Some methods take input, some don’t. For example, there’s a method in the list called .getProjectObjects() There’s nothing between the brackets, so we know that it’s not expecting input of any kind. On the other hand, the method called getProjectObj(Long id) is expecting input that is of the type long.
Let’s experiment. If you want to make use of a method, simply tack it on to the end of the object that instantiated the ProjectManager class. So in this case, our object is projectManager:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.project.ProjectManager
def projectManager = ComponentAccessor.getComponent(ProjectManager)
return projectManager.getProjectObjects()
By running this code, the data that is returned should be the project Keys of every project in the instance (your list will be different):
[Project: DELETEME, Project: DESS, Project: DES, Project: DEMO, Project: DMCA, Project: DMCB, Project: KDES, Project: NMC, Project: SD]
This is the essence of working with class imports and objects in Jira: importing the class in question, accessing it with the Component Accessor, and then using the resulting object to access the class methods.
wrapping up
I encourage you to explore some of the other classes listed in the documentation. Maybe try to find a class that would let you work with issues, and explore its methods (hint: its class name is very similar to the class we used today).
The only way to really learn Groovy and to become a confident ScriptRunner user is to get your hands dirty, and to ask questions!
Leave a Reply