Tutorial - Custom fields in JIRA
Level of experience:
This is a beginner tutorial. Our tutorials are classified as 'beginner', 'intermediate' and 'advanced'. This one is at 'beginner' level, so you can follow it even if you have never developed a plugin before.
It should take you approximately 30 minutes to complete this tutorial.
On this page:
Overview of the tutorial
This tutorial shows you how to create a simple custom field that can store a currency value. To create this field, you build a JIRA plugin consisting of the following components:
- Java classes encapsulating the plugin logic.
- Resources for display of the plugin UI (Velocity templates).
- A plugin descriptor (XML file) to enable the plugin module in the Atlassian application.
Each component is further discussed below.
To complete this tutorial, you need to know the following:
- How to use an integrated development environment (IDE), such as Eclipse or IDEA.
- The basics of Java development, including classes, interfaces, methods, how to use the compiler, and so on.
You should already have the latest version of the Atlassian Plugin SDK on your development system. If you don't have the SDK and are not already familiar with it, you should start with the Getting Started information.
We encourage you to work through this tutorial. If you want to skip ahead or check your work when you have finished, you can find the plugin source code on Atlassian Bitbucket. Bitbucket serves a public Git repository containing the tutorial's code. To clone the repository, issue the following command:
Alternatively, you can download the source as a ZIP archive by choosing download here:
Step 1. Create the plugin project
In this step, you'll use two
atlas- commands to generate stub code for your plugin and set up the stub code as an Eclipse project. The
atlas- commands are part of the Atlassian Plugin SDK, and automate much of the work of plugin development for you.
- Open a terminal and navigate to your Eclipse workspace directory.
Enter the following command to create a JIRA plugin skeleton:
- Choose 1 for JIRA 5 when asked which version of JIRA you want to create the plugin for.
As prompted, enter the following information to identify your plugin:
- Confirm your entries when prompted.
- Change to the
tutorial-jira-custom-fielddirectory created by the previous step.
Run the command:
- Start Eclipse.
- Select File > Import.
Eclipse starts the Import wizard.
- Filter for Existing Projects into Workspace (or expand the General folder tree).
- Press Next and enter the root directory of your workspace.
Your Atlassian plugin folder should appear under Projects.
- Select your plugin and click Finish.
Eclipse imports your project.
Step 2. Review and tweak the generated stub code
It is a good idea to familiarize yourself with the stub plugin code. In this section, we'll check a version value and tweak a generated stub class. Open your plugin project in Eclipse and follow along in the next sessions to tweak some code.
Add plugin metadata to the POM
Add some metadata about your plugin and your company or organization.
- Edit the
pom.xmlfile in the root folder of your plugin.
Add your company or organization name and your website to the
- Save the file.
Review the generated plugin descriptor
Your stub code contains a plugin descriptor file
atlassian-plugin.xml. This is an XML file that identifies the plugin to the host application (JIRA) and defines the required plugin functionality. In your IDE, open the descriptor file which is located in your project under
src/main/resources and you should see something like this:
In the next step, you'll use the plugin module generator (another
atlas- command) to generate the stub code for modules needed by the plugin.
Step 3. Add your plugin modules to the plugin descriptor
For this tutorial, you will need a Custom Field plugin module. You'll add this by using the
- Open a console and go to the plugin root folder (where the
- Choose the option labeled
As prompted, enter the module parameters:
Enter New Classname
MoneyCustomField(This is the
Nfor Show Advanced Setup.
Nfor Add Another Plugin Module.
SDK adds the module declaration to the plugin descriptor and creates the source files for the module, including a class file and presentation templates.
Step 4. Update your project and refresh your IDE
Eclipse is not automatically aware of changes made to the project outside of Eclipse, as we've just made with the SDK. Moreover, sometimes your project dependencies require an update. Let's refresh the project in Eclipse:
- Switch to a terminal window.
- Change directory to the project root.
This is the directory with the
Update your Eclipse metadata with the changes to the plugin source code:
- Back in Eclipse, refresh the plugin project to pick up the changes.
Remember to do this update and refresh step each time you edit your
pom.xml and whenever you modify your plugin source with an Atlassian command.
Step 5. Write the plugin code
You have already generated the stubs for your plugin modules. Now you will write some code that will make your plugin do something. Recall that this plugin will add a custom text field in a JIRA issue that stores a money value. To do this, you'll need to implement the
CustomFieldType interface and create velocity templates for viewing and editing the field.
- Open Eclipse and browse to the
atlas-create-jira-plugin-modulecommand you ran earlier generated this class.
Let's start by adding some import statements. Add these to the ones the SDK added for you:
Custom Fields can store single values or multiple values. In our case, we want to store a single value, so change the class declaration to extend the
This class provides much of the field's implementation for you. Notice also that we'll use
BigDecimalas our "transport object" (for dealing with a currency in Java). A transport object is just a plain old Java object (POJO). The object's type represents the custom field used.
We won't override anything in
getVelocityParameters(), so you can delete this. Our field will use the default implementation from the superclass which is
AbstractCustomFieldType. If you want to explore the class hierarchy, access the docs appropriate for your version from the index of JIRA Javadocs.
We'll implement a few abstract methods from
AbstractSingleFieldType, first by adding the following the
getStringFromSingularObject()method to your class.
This method turns a value in our
BigDecimal, in our case) into text.
The method takes input from the user, validates it, and puts it into a a transport object. We want to validate that the user has entered a valid number, and that there are no more than two decimal places.
Now add the
getDatabaseType()method to tell JIRA what kind of database column to store the data in. You can choose text, long text, numeric, or date. We could use numeric, but we will use Text to keep it simple.
This takes a value from the DB and converts it to our transport object. The value parameter is declared as Object, but will be String, Double, or Date depending on the database type defined above. Because we chose
FieldType TEXT, we will get a String and can reuse
Finally, add the
getDbValueFromObject()method. It takes a value as our transport object and converts it to an Object suitable for storing in the DB. In our case we want to convert to String.
That's it for the
MoneyCustomField class. Removing unused code, your class should look like this:
Notice the Logger instance we instantiate in the first line of the class. The SDK added this to our stub code. By default, Atlassian plugins use the Simple Logging Facade for Java (SLF4J) for its logging facility. We haven't shown how to use logging in our sample, but in general, you can add log messages in your code where appropriate for troubleshooting and debugging. You then set the desired logging level in the JIRA administration console. For a tutorial of a plugin that uses logging, see Tutorial - Writing JIRA event listeners with the atlassian-event library. Also see the Confluence logging guidelines. While targeted for Confluence, that page covers some general concepts related to logging as well.
Step 6. Build and test your plugin
We're not finished yet, but let's try what we've created so far.
Start JIRA up with your plugin and create project
- Make sure you have saved all your code changes to this point.
- Open a terminal window and navigate to the plugin root folder (where the
Run the following command:
This command builds your plugin code, starts a JIRA instance, and installs your plugin in it. This may take several seconds or so, when the process completes you see many status lines on your screen concluding with something like the following lines:
- Open your browser and navigate to the local JIRA instance started by
If you followed the instructions, enter http://localhost:2990/jira in your browser.
- At the JIRA login, enter a username of
adminand a password of
Since this is a new instance, JIRA prompts you to select a project type.
- With Blank Project selected as the project type, choose Next.
JIRA displays the Add a New Project dialog.
Enter TUTORIAL for both the project name and the key.
- Click Submit.
JIRA displays the overview page for your new project.
Add your custom field to the project configuration
From the overview page of your new project:
- Choose the Administration tab.
- Scroll down to the Fields section and click Default Field Configuration.
- Click Custom Fields from the left menu.
- Click Add Custom Field
The system displays the Create Custom Field: Choose the Field Type step.
- Select Advanced and then the Money Custom Field
This is the custom field you just created.
- Click Next.
The system displays the Create Custom Field - Details (Step 2 of 2) step.
Set the fields as follows:
Accepts a money amount
Choose applicable issue types
Any issue type
Choose applicable context
Notice the Choose Search Template section. Since we haven't implemented any custom search templates, we don't have any to choose from here.
- Click Finish.
- Select Default Screen and click Update.
This ensures the field appears on the default screen.
Test the new field
Now we can see our new field in action by creating an issue:
- Choose Create Issue from the menu bar.
- Make sure the project is the TUTORIAL project and click Next.
- In the Create Issue form, scroll to the bottom of the page and notice the placeholder text, edit.vm.
The plugin worked, which is good, but it's not usable yet, which is not so good. We need to customize our template code to allow for user input to the field.
- Click Cancel, but keep JIRA running and your browser window open for now. We'll get back to it in a minute.
Step 7. Edit the Velocity templates
Plugins can expose interface in JIRA through Velocity templates. The SDK gave us two templates, one for viewing the field value and for another for editing it.
Customize the default templates as follows:
In a new console, navigate to this directory:
view.vmfile for editing and replace its contents with the following:
#ifclause simply checks for null values in the
valuevariable. If its value is null, nothing gets shown in the template rendering. Otherwise,
$valuein the second line is replaced by the value of our transport object in the rendered template. The additional "$" symbol is actually a literal dollar sign. You can change this to another currency symbol if desired (e.g.,
In the same directory, replace the contents of the
edit.vmfile with the following:
This is the same code found in the
edit-basictext.vmtemplate in the JIRA core code. This means that this field will look the same as many other text fields in JIRA that use the "basic text" input template. The
#customControlFooterare Velocity macros defined in the
macros.vmfile built into JIRA. It checks certain conditions and adds standard UI text around the field, including a label, description, and validation error messages. The interesting bit is the
inputelement. It's the HTML form element that exposes the text field for entering a value for our custom field.
Step 8. Do a live reload and try again
You can test your changes without restarting JIRA using live reload.
- Back in the JIRA browser window, expand the developer toolbar by clicking the expander arrow at the bottom left of the page.
- In the expanded toolbar, click the icon for Live reload noncompiled code:
Give JIRA a few moments, but note that you can continue to the next step while the progress indicator is still revolving.
- Now create an issue as you did before.
This time, our Expense field appears at the bottom of the form.
- Enter a value in Expense field.
- Press Create.
Experiment some more with this field. You can try entering values that are invalid. Try entering something like "2" or "2.5" and see how it gets rendered after you save. You could also not enter anything in the field. Edit some of the issues you create. Notice that if you don't enter value in the field, when you edit the issue later the field is hidden.
You can keep going by experimenting with different field types.
Also, try extending the plugin by adding a custom field searcher. You can use the Atlassian Plugin SDK to generate the initial code for your custom field searcher, using
atlas-create-jira-plugin-module and choosing the Custom Field Searcher option as the module to create. From there, you can choose the custom field searcher class to extend, such as text searcher or exact text searcher.
For more about custom field searchers, see custom field searcher.
Also, check out these other resources on custom fields: