Hello,
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!
Vladimir
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: https://wiki.almworks.com/x/x4J7
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.
Javadocs: http://almworks.com/structure/javadoc/latest/
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!
Igor
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Yes, that should work
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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 must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Vladimir, you need to inject the services, you cannot get them with `getComponent()`. Please read documentation here: https://wiki.almworks.com/x/x4J7 Also, there are some examples: https://wiki.almworks.com/x/y4J7
Kind regards,
Igor
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Igor,
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?
Vladimir
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Ah, I see. You can try ComponentAccessor.getOSGiComponentInstanceOfType() then, instead of getComponent()
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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,
Vladimir
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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,
Igor
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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,
Vladimir
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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 = searchService.search(user, 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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.