Calculated custom field - using of searchService java class


In JIRA I have a calculated custom field with formula which do SJQL (Structure JQL) search. To do this search I use searchService java class. I also use Structure plugin. Then I open project's structure and have a view with this calculated custom field, the Structure loads very slowly (particularly, when this structure has a lot of issues). As I know, this happens due to the calculated custom field as it uses SJQL. Is it possible to optimize the formula using another methods or java classes to achieve the same result in this calculated custom field?

Thanks a lot in advance for any advises and suggestions!




3 answers

1 accepted

1 vote

Hi Vladimir, 

Thanks for the clarification. You can speed up the calculation a bit by bypassing query parsing and probably execution. It would require making your code import Structure Java API, as explained here:

Option 1. Use S-JQL but avoid query parsing

Check out StructureQueryBuilder class in the javadoc. It has some examples.

Option 2. Do not use S-JQL and traverse the structure manually

Use StructureManager service to retrieve Forest, locate your target issue, then walk upwards with getParentIndex() method, checking each issue. If you have only a few issues of type "Specific type", it would be a good idea to cache issue IDs or Issue objects for those to avoid costly getIssue() calls.


Additionally, I'm happy to say that Structure 3.0 will have a new "attributes engine", which would allow you to define an attribute of "propagate" kind – similar to aggregate, but in another direction – which is exactly what you need in this situation. You'll be able to display propagate attribute in Structure Widget, or re-implement your calculated field in a way to use the propagate. It will be very fast, because the system will implement correct caching based on the nature of the attribute. Unfortunately, the API will not be finalized with the upcoming release of Structure 3.0, it hopefully will be ready by Structure 3.1.

Hope this helps!

Hi Igor, Thank you once more for explicit answer! I think I should to implement Option 2, because, typically, there can be no more than one ancestor issue which is of this Specific type1 (in our project management model we have such restriction). If there is no such ancestor of this Specific type1, I have to search for ancestor of Specific type2 (and again in our model we have restriction that there can be only one ancestor issue which is of this Specific type2). One more question - to implement Option 2, do I have to import StructureServices, that is: import com.almworks.jira.structure.api.StructureServices; import com.almworks.jira.structure.api.StructureManager; StructureManager strucMan = structureServices.getStructureManager() ? Best regard, Vladimir

Yes, that should work

Hi Igor, I have one more question, but firstly about the problem. In our company we have structure for each project, then we have structure for each department (this structures consists of projects' structures that belong to that particular department) and finally, we have company's structure (consists of departments' structures). Is it better to retrieve Forest of company's structure (in this way I know its ID and it would be the same for all issues, but the Forest is huge because almost all issue are in it), or, firstly, to search for project's structure (in which the issue exists) and retrieve the Forest of this project's structure (in this case, the Forest is much smaller, but I have to search)? Thanks for the advice! Vladimir

Hi Vladimir, good question. I cannot tell you with 100% confidence that one way would be better than the other. I would try searching smaller structures first. How would you search for a per-project structure? You can use StructureManager.getStructuresWithIssue() to find all structures that contain given issue. Or maintain a cached map of Project => structure ID. Igor

Hi Igor,

I try to implement the formula by using StructureServices and StructureManager. Unfortunately, the following code doesn't run:

import com.almworks.jira.structure.api.StructureServices;

import com.almworks.jira.structure.api.StructureManager;

StructureManager strucMan = structureServices.getStructureManager()


I tried to implement very simple calculated text custom field in order to test various scenarios. In the following code I try just to check if issue is in a specific structure or not. Also, I use ComponentAccessor to get StructureServices class:

   import com.atlassian.jira.component.ComponentAccessor;

   import com.almworks.jira.structure.api.StructureServices;  

   import com.almworks.jira.structure.api.StructureManager;   


   Long issueID = issueObject.getId();

   StructureServices strucServices = ComponentAccessor.getComponent(StructureServices.class);

   StructureManager strucManager = strucServices.getStructureManager(); //error in this place


   if (strucManager.isIssueInStructure(issueID, 162)) {

      return "YES";

   } else return "NO";

And again it throws an error: CalculatedTextField: error evaluating formula of field "Test" of issue HX191-121: Sourced file: inline evaluation of: import com.atlassian.jira.component.Compone . . . '' : Typed variable declaration : at Line: 9 : in file: inline evaluation of: import com.atlassian.jira.component.Compone . . . '' : strucServices .getStructureManager ( ) Target exception: java.lang.NullPointerException: Null Pointer in Method Invocation

And here I stop because I don't understand, why it throws this error. Maybe you know?

Thanks a lot,


Vladimir, you need to inject the services, you cannot get them with `getComponent()`. Please read documentation here: Also, there are some examples:

Kind regards,


I think the difficulty is that I do not create any JIRA plugin, but instead I use JIRA Misc Custom Fields plugin. Does it mean, that I have to change pom.xml and atlassian-plugin.xml files of this plugin?


Ah, I see. You can try ComponentAccessor.getOSGiComponentInstanceOfType() then, instead of getComponent()

Hi, Igor,

The method ComponentAccessor.getOSGiComponentInstanceOfType() worked, but it is seems that this does not speed up the calculations. Again I got in some troubles:

Firstly, when I define a new variable "Forest forest = structManager.getForest(DEFAULT_STRUCTURE_ID, user, true)" and re-index the JIRA I got an error "Class: Forest not found in namespace : at Line: 26 : in file: inline evaluation of: `` // category import com.almworks.jira.structure.api.Structure . . . '' : Forest" (even if I did import com.almworks.jira.structure.api.forest.Forest). So, each time when I want to know the issuetype of issue's parent, I have to use "ComponentAccessor.getIssueManager().getIssueObject(strucManager.getForest(DEFAULT_STRUCTURE_ID, user, true).getParent(issueID)).getIssueTypeId()".

Secondly, even if I could define a new variable from the Forest class, I do not think this would help because for 20.000 issues to retrieve the Forest is time-consuming. Is it possible only once to retrieve the Forest of DEFAULT_STRUCTURE and then for each issue to find its parent and look for parent's issuetype? 

Thanks in advance,


Hi Vladimir, sorry for late reply. You're right, extracting Forest once and reuse would make things work faster. I don't have an immediate solution to offer, sorry, this requires extended work and analysis of your task. As I mentioned, Structure 3 should make this task easier. 

Kind regards,

Hi Igor,

Thanks a lot. Sorry for disturbing you!

By this time, I think it is most efficient just to use IssueLinkManager() and find parent of an issue by using Issue links.

Best regards,


0 vote

Hi Vladimir, Could you please specify what SJQL are you using and what else does the calculated field calculate? Typically, yes, calculated fields are very slow. Igor

Hi, Igor, Thanks for your reply. In the calculated custom field formula for a certain group of issue types I search their ancestor of a specific issue type and look for a field's value of that ancestor. Here are a few fragments from the code: String jqlSearch1 = "issue in structure(\"ancestor of (" + issueObject.getKey() + ") and [type = \'Speciific type\']\")"; ... parseResult = searchService.parseQuery(user, jqlSearch1); ... searchResult =, parseResult.getQuery(), PagerFilter.getUnlimitedFilter()); Is it possible to somehow optimize the search by using another procedures or java classes? I have found some information about jiraRestClient class, but I don't know, if using it will give a better result. Best regards, Vladimir

Suggest an answer

Log in or Join to answer
Community showcase
Louis De Jaeger
Posted Thursday in Off-topic

Friday fun: your best joke

Hi all Lets make this Friday fun really fun and post one (or more) of your best jokes! The joke can be about an Atlassian product, or just a really fun joke you want to share! I’m not the best j...

178 views 12 3
Join discussion

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you
Atlassian Team Tour

Join us on the Team Tour

We're bringing product updates and pro tips on teamwork to ten cities around the world.

Save your spot