Overview

Jira is an excellent issue tracking tool, and that needs no further introduction. Jira has a concept of Projects and each issue that is logged under a project has a pattern — [project_key]-[id], e.g: ABC-202. The id is unique only for that project, that is ABC-202 and DEF-202 are two issues which have an id of 202, unique within their own project context. If you have a requirement of displaying a unique issue Id across all the projects then that involves some work, writing a plugin, that I try to explain in this post.

JRA-7777 is an issue that was logged a while ago on Atlassian’s issue tracking site for this specific purpose.

Prerequisite

Atlassian’s Developer Network site has detailed steps on setting up your environment and more. Good resource, and no need to duplicate that here.

Approach

If you look at the Jira database schema, JiraIssue table has a unique identifier column (ID). The value of that field is unique across the system. So for ABC-202 this ID could be 14500 and DEF-202 it could be 15202. So the goal is to expose this value as a read-only custom field on the Jira UI.

Other characteristics of this ID that I have observed are —
- the value starts at 10000, and
- if you restart the servlet container hosting Jira the ID (for the next row) jumps to next 10’s. If the last value was 10256 before restart, after restart the ID for the subsequent row is 10260 (instead of 10257, that one may usually expect). Still unique, and serves the purpose.

Update: Matt Doar provided an explanation for this behavior in his comments:
According to Jira’s documentation it’s Ofbiz that allocates IDs in batches of 10, so the SEQ_ID is the next available ID rounded up to the nearest 10. So I would expect that restarting the servlet would just round it up, not increment it on every restart.

Plugin Development

Plugin Descriptor (atlassian-plugin descriptor)

An XML file that describes about the plugin and the modules contained in it. It is placed right under the root folder of the project. In this file the new custom field type is defined. atlassian-plugin-key is the name of the Java package under which the plugin class is placed. key of the custom-field-type is the unique name of the plugin, and provide the associated fully qualified plugin Class name.

< ?xml version="1.0" encoding="UTF-8"?>
<!-- the plugin key must be unique, think of it as the 'package' of the plugin -->
<atlassian-plugin key="com.suryasuravarapu.jira.plugins" name="Unique Id Plugin">
    <!-- a short block describing the plugin itself -->
    <plugin-info>
        <description>A unique issue id for the Jira issue</description>
        <!-- the version of the plugin -->
        <version>1.0</version>
        <!-- the versions of the application this plugin is for -->
        <application-version min="3.13" max="3.13"/>
        <!-- details of the plugin vendor -->
        <vendor name="SPS" url="http://suryasuravarapu.com"/>
    </plugin-info>

    <customfield-type key="uniqueIssueId" name="Jira Internal Id"
        class="com.suryasuravarapu.jira.plugins.UniqueIssueId">
        <description>
        Unique issue id correlates to the ID in the JIRAISSUE table
        </description>

        <!-- this template is used on the view issue page -->
        <resource type="velocity" name="view"
            location="templates/plugins/fields/view/view-uniqueIssueId.vm" />
    </customfield-type>

</atlassian-plugin>

Plugin Java Code
Fortunately, you don’t have to write this plugin from the scratch. Jira ships with quite a few concrete implementations. A custom field class extends CustomFieldType, but we can extend a more concrete implementation for numeric fields NumberCFType.

getValueFromIssue is the only method that you need to implement and return the auto-increment Id.

public class UniqueIssueId extends NumberCFType {
	public UniqueIssueId(CustomFieldValuePersister customFieldValuePersister,
			DoubleConverter doubleConverter,
			GenericConfigManager genericConfigManager) {
		super(customFieldValuePersister, doubleConverter, genericConfigManager);
	}

	public Object getValueFromIssue(CustomField field, Issue issue) {
            return issue.getId();
	}
}

Velocity Templates
view-uniqueIssueId.vm that we have described above in the plugin descriptor takes care of displaying the field value. One notable item below is we are displaying the value.longValue() as the value that is being returned by the NumberCFType is of type java.lang.Double. Without that conversion you would see values like 10380.0 instead of 10380, little annoyance!

#if($value &amp;&amp; !$value.equals(""))
	#set ($displayValue = ${value.longValue()})
#else
	#set ($displayValue = 'N/A')
#end
$!displayValue

Deployment

From Eclipse, export the JAR or use the Maven build scripts to generate one. Place that JAR under application’s WEB-INF/lib folder, and restart the container. You should be able to see your Plugin under Jira’s Administration -> Plugins.

All the hard work is done! Display the field value. For that, create a custom field using the type defined above and add it to the desired screens for display.

Share and Enjoy:
  • del.icio.us
  • DZone
  • Digg
  • StumbleUpon
  • Technorati
  • Reddit
  • Facebook
  • Twitter
  • Google Bookmarks
  • FriendFeed
  • Tumblr
  • HackerNews

You may also like:

  1. Jira Plugin: Unique Issue ID with Search Capability