Tutorial: Adding licensing support to your add-on (up to UPM version 2.0)

Level of experience BEGINNER
Time estimate 45 MINUTES
Applies to

UPM versions prior to 2.0, and libraries compatible with:

  • JIRA 4.1+
  • Confluence 4.0+
  • Bamboo 2.6+
  • Stash 1.1.2+
  • Fisheye/Crucible 2.4+

For older product versions, specify a Plugin Licensing Support plugin version older than 2.15 in step 4.7.

Tutorial overview

You'll learn how add-on licensing works in the Universal Plugin Manager (UPM). In this tutorial, you'll create a simple plugin and install it in JIRA. You'll add a license to your plugin via the UPM. Your plugin will use the Plugin Licensing Support API to ensure compatibility with UPM. You'll add a plugin module that automatically creates a "Hello, World!" servlet. Finally, you'll add a license to your add-on, and verify your servlet reflects the license.

This tutorial demonstrates how to write a license-aware plugin that is compatible with Atlassian products that are not yet supported by UPM 2.0. You can also use this pattern with products that support UPM 2.0 but which do not come bundled with it. If and when your customers with these products upgrade to UPM 2.0, the licensing pattern in this sample continues to work. By supporting situations where UPM 2.0 is not yet installed, this library also increases the potential audience of a plugin. All the components in this tutorial are contained within a single JAR file. 

Plugin source

We encourage you to work through this tutorial. If you want to skip ahead or check your work when you are done, 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:

git clone https://bitbucket.org/atlassian_tutorial/upm-licensing-compatibility.git

If you aren't sure how to use Git, see the Bitbucket Getting started guide. Alternatively, you can download the source using the get source option here: https://bitbucket.org/atlassian_tutorial/upm-licensing-compatibility/overview.


Before working through this tutorial, you may read Plugin metadata files used by UPM and Marketplace. You should also have an understanding the following:


You should have installed the following software on your local system:

  • An integrated development environment(IDE) such as Eclipse or IDEA.
  • The latest Atlassian Plugin SDK. Licensing-enabled plugins should be built with SDK version 3.10.2 or greater.
  • Git distributed source control system


You can use any supported combination of OS and IDE with this tutorial. These instructions assume Eclipse Classic Version 3.7.1 on a MacBook Air running Mac OS X Version 10.7.2. If you are using another combination of OS and IDE, you should use the equivalent operations for your specific environment.

Plugin Modules

It may help to be familiar with the following plugin modules:

Of course, you should also understand the Java development basics including classes, interfaces, methods, how to compile source into a JAR file, and so on.

Step 1. Create the plugin project

Before working through this procedure, make sure you have the latest version of the Atlassian SDK. Then:

  1. Open a terminal and navigate to your Eclipse workspace directory.
  2. Enter the following command to create a JIRA plugin skeleton:


    When prompted, enter the following information to identify your plugin:









  3. Confirm the properties configuration when prompted.
  4. Change to the tutorial-licensing-compatibility directory created by the previous step.

    cd tutorial-licensing-compatibility/
  5. Run the command:

    atlas-mvn eclipse:eclipse
  6. Start Eclipse.
  7. Select File > Import.
    Eclipse starts the Import wizard.
  8. Expand the General folder tree.
  9. Filter for Existing Projects into Workspace and press Next.
  10. Choose Select root directory and then Browse to the root directory of your workspace.
    Your Atlassian plugin folder should appear under Projects.
  11. Select your plugin project and click Finish.
    Eclipse imports your project.

Step 2. Review and tweak the stub code

Familiarize yourself with the generated stub plugin code. In this section, you'll check (and potentially tweak) the generated files. Open your plugin project in Eclipse and follow along in the next sections to tweak some values.

Edit your <properties> section

When you created the stub files, the generator created the <properties> of your pom.xml file (project object model). The generator lists the Atlassian host product version you chose when you ran the plugin command. The <amps.version> value specifies the atlas- commands you are running. Take a moment and examine these values:

  1. Scroll to the bottom of the pom.xml file.
  2. Find for the <properties> element and review the <jira.version> value.
  3. Make sure the <jira.version> value is set to the 5.0 release.
  4. Make sure the <amps.version> is set to 3.10.2 (or higher, if you have a more recent SDK).
    When you are done, the section should look like the following:

  5. Save the pom.xml file.

Add plugin metadata

Add some metadata about your plugin and your company or organization. If you haven't already, open the pom.xml file in the root folder of your plugin and do the following.

  1. Scroll to the top of the pom.xml file.
  2. Locate the <organization> element.
  3. Add your company or organization name and your website to the element:

        <name>My Company</name>
  4. Update the <description>element:

    <description>This is a sample plugin to demonstrate how to develop a licensing that is compatible with UPM.</description>
  5. 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. The descriptor references the metadata in your pom.xml file. In your IDE, open the PROJECT_DIR/src/main/resources/atlassian-plugin.xml file. You should see something like this:

<atlassian-plugin key="${project.groupId}.${project.artifactId}" name="${project.artifactId}" plugins-version="2">
        <vendor name="${project.organization.name}" url="${project.organization.url}" />

The project.groupId and project.artifactId that make up the key attribute you defined when you ran the atlas-create-jira-plugin command. The actual values you entered live in the pom.xml file, they are just referenced here. Every reference in the descriptor that starts with project reference information from the pom.xml file.

Step 3. Update your project and refresh your IDE

If you change your Atlassian project, Eclipse is not automatically aware of the changes. Moreover, sometimes your project dependencies require an update. You can use the Atlassian SDK commands to do this update:

  1. Switch to a terminal window.
  2. Change directory to the project root.

    This is the directory with the pom.xml file.

  3. Update the on-disk project metadata with the new POM information.

    atlas-mvn eclipse:eclipse
  4. Back in Eclipse, refresh the plugin project to pickup the changes.

    Remember to do this update and refresh step each time you edit your pom.xml or otherwise modify your plugin source with an Atlassian command.

Step 4. Add a licensing support module

Add the Atlassian Plugin Licensing support to your plugin. To do this, you add a Licensing Support API module to your plugin. This module contains a servlet that act as your license administration screen. You can use this screen to test your licensing.

To add the module:

  1. Open a command window and go to the plugin root folder (where the pom.xml is located).
  2. Run atlas-create-jira-plugin-module.
  3. Choose the option labeled Licensing API Support.
  4. Supply the following information as prompted and hit Return/Enter.

    License Servlet Classname


    Package Name


    License Servlet URL Path


    Include Example Code


    Hello World Servlet URL Path


    The system generates the module and prints out an informational message similar to the following:

    [INFO] Adding the following items to the project:
    [INFO]   [Maven plugin: maven-dependency-plugin]
    [INFO]   [bundledArtifact: com.atlassian.upm:atlassian-universal-plugin-manager-plugin]
    [INFO]   [bundledArtifact: com.atlassian.upm:plugin-license-storage-plugin]
    [INFO]   [class: com.example.plugins.tutorial.compatibility.servlet.LicenseHelloWorldServlet]
    [INFO]   [class: com.example.plugins.tutorial.compatibility.servlet.LicenseServlet]
    [INFO]   [component-import: com.atlassian.plugin.PluginAccessor]
    [INFO]   [component-import: com.atlassian.plugin.PluginController]
    [INFO]   [component-import: com.atlassian.sal.api.ApplicationProperties]
    [INFO]   [component-import: com.atlassian.sal.api.auth.LoginUriProvider]
    [INFO]   [component-import: com.atlassian.sal.api.message.I18nResolver]
    [INFO]   [component-import: com.atlassian.sal.api.pluginsettings.PluginSettingsFactory]
    [INFO]   [component-import: com.atlassian.sal.api.transaction.TransactionTemplate]
    [INFO]   [component-import: com.atlassian.sal.api.user.UserManager]
    [INFO]   [component-import: com.atlassian.templaterenderer.TemplateRenderer]
    [INFO]   [component: com.atlassian.upm.license.storage.lib.AtlassianMarketplaceUriFactoryImpl]
    [INFO]   [component: com.atlassian.upm.license.storage.lib.PluginLicenseStoragePluginInstaller]
    [INFO]   [component: com.atlassian.upm.license.storage.lib.ThirdPartyPluginLicenseStorageManagerImpl]
    [INFO]   [dependency: com.atlassian.sal:sal-api]
    [INFO]   [dependency: com.atlassian.templaterenderer:atlassian-template-renderer-api]
    [INFO]   [dependency: com.atlassian.upm:licensing-api]
    [INFO]   [dependency: com.atlassian.upm:plugin-license-storage-lib]
    [INFO]   [dependency: com.atlassian.upm:plugin-license-storage-plugin]
    [INFO]   [dependency: com.atlassian.upm:upm-api]
    [INFO]   [dependency: commons-lang:commons-lang]
    [INFO]   [dependency: javax.servlet:servlet-api]
    [INFO]   [dependency: org.apache.httpcomponents:httpclient]
    [INFO]   [dependency: org.mockito:mockito-all]
    [INFO]   [dependency: org.springframework.osgi:spring-osgi-core]
    [INFO]   [module: servlet]
    [INFO]   [pluginInfo: atlassian-licensing-enabled=true]
    [INFO]   [resource: license-admin.vm]
    [INFO]   bundle instructions: 5
    [INFO]   i18n strings: 52
  5. Choose N when prompted with Add Another Plugin Module.
  6. Open your pom.xml.
  7. Increment your upm.license.compatibility.version property to the latest stable target version, such as 2.15.1.

    Specify a version older than 2.15 if you're using an older product version than the following:

    • JIRA 4.1+
    • Confluence 4.0+
    • Bamboo 2.6+
    • Stash 1.1.2+
    • Fisheye/Crucible 2.4+

  8. Open the plugin descriptor file, atlassian-plugin.xml, in the project's resources directory and add a param element under plugin-info that identifies the license configuration servlet. The element should have a name value of configure.url and identify the location of the servlet in the body of the element, as in the following example:

    <param name="configure.url">/plugins/servlet/com.example.plugins.tutorial.plugin-license-compatibility-tutorial/license</param>

    For a full example of the descriptor file, see Plugin metadata files used by UPM and Marketplace.

  9. Update the on-disk project metadata with the new POM information created by the generator.

    atlas-mvn eclipse:eclipse
  10. Back in Eclipse, refresh your plugin project to pickup the changes.

What did the module generator do?

The module generator does a lot under the covers for you. It adds code dependencies to your POM, adds components to your atlassian-plugin.xml file, and adds two servlet classes for you. For now, we are just going to mention these changes and move onto seeing how your new plugin operates. If you want to review the details of the module generation now or in the future, see Understanding the generated license API support.

Step 5. Build and verify your plugin installation

At this point, you've edited a few metadata files and generated some new code with Atlassian's SDK. You can test your new modules easily through the SDK's atlas-run command. This command builds your plugin code, starts a JIRA instance, and installs your plugin in it.

  1. Make sure you have saved all your code changes to this point.
  2. Open a terminal window and navigate to the plugin root folder (where the pom.xml file is).
  3. Run the following command:

    atlas-run -DskipTests

    The code generator creates some test classes but we skipping the tests for now. The command can take several seconds or even a minute or two. When the process completes, you see several status lines in the terminal concluding with something like the following:

    [INFO] [talledLocalContainer] Tomcat 6.x started on port [2990]
    [INFO] jira started successfully in 104s at http://localhost:2990/jira
    [INFO] Type CTRL-D to shutdown gracefully
    [INFO] Type CTRL-C to exit

    You can see that this output includes the URL of the JIRA instance.

  4. Log into JIRA using the following credentials:





  5. Navigate to the Administration > Plugins page (http://myhost.local:2990/jira/plugins/servlet/upm).
  6. Locate the tutorial-licensing-compatibility plugin in User-installed Plugins.
  7. Click the listing to expand the details. You should see something like the following:
What version of UPM?

Confirm the UPM version JIRA is running by doing the following:

  1. Locate the Show System Plugins option on the page and click it.
    JIRA refreshes and displays a list of system plugins.
  2. Locate the Atlassian Universal Plugin Manager entry and click it to open the details.
  3. Locate the Plugin Version field.
    If you have followed this tutorial exactly to this point, you should see version 1.6.3.

Step 6. Test the plugin licensing

When you added the Licensing Support module, you generated a LicenseHelloWorldServlet servlet that represents the actual plugin functionality. You also generated a LicenseServlet that provides you (and your customers) with the means for entering a license in the pre-2.0 world. Upon starting up JIRA, your plugin is not licensed. In this step, you test how licensing works in a pre-2.0 version of UPM.

  1. Verify the plugin is unlicensed by visiting the LicenseHelloWorldServlet page.
    You should see a message like the following:
  2. Go to the LicenseServlet page.
    The servlet displays a Tutorial Plugin License Administration page like this:

    You need a license.
  3. Copy the 60 second license string as noted below:

    Timebomb License - 60 Second Expiration
  4. Paste the license into the Enter a new license field.
  5. Press Update.
    The system displays an image similar to the following:

    Now that your plugin has a valid license, you should be able to see "Hello, World!".
  6. Return the LicenseHelloWorldServlet page and you should now see:

Why can't I acquire a license from My Atlassian? I get an error about an invalid plugin key.

You can acquire licenses from My Atlassian only after you list your add-on with the Atlassian Marketplace. However, after you list your add-on, the buttons should automatically start working.

Step 7. Get some additional licenses and test a bit

A 60 second license does not give you much time. We also realize you might want to test various license error conditions. So, if you need more licenses go to Timebomb licenses for testing.

To clear out a license on the Tutorial Plugin License Administration page and add a new license, do the following:

  1. Select the contents of the Enter a new license field and press Delete on your keyboard.
    The system should provide you with a message that Your license has successfully been removed.
  2. Copy and paste a new license into the field.
  3. Press Update.

You cannot reuse licenses by entering them multiple times. If you exhaust your test licenses:

  1. Log out of JIRA.
  2. Return to the terminal where you ran atlas-run.
  3. Press Ctrl-D on your keyboard to end JIRA.
  4. Run atlas-mvn clean to clear out your target instance.
  5. Restart JIRA:

    atlas-run -DskipTests

Step 8. Test how the plugin behaves after an upgrade to UPM 2.0.1

Recall that the JIRA 5.0 bundled UPM 1.6.3. UPM version 1.6 and later are capable of updating to newer UPM versions. In this step, you upgrade your JIRA instance from UPM 1.6.x to UPM 2.x. Then, you test the license administration interaction after the upgrade to see how it is different.

What happens in version UPM 2.0.1+?

Once UPM 2.0.1+ is installed in the Atlassian host application, all license administration must occur within the Plugins pageā€”UPM's user interface. Although UPM 2.0 is the first version to be licensing-aware, the LicenseServlet page becomes read-only and refers customers to the Plugins page.

If you haven't already done so, start JIRA and do the following:

  1. Login as admin with a password of admin.
  2. Go to the Plugins page in JIRA .
  3. Navigate to the Upgrade tab.
  4. Locate the Atlassian Universal Plugin Manager entry in the list.
  5. Click the entry to view the details.
  6. Click Upgrade Now.
    JIRA downloads and installs the new version of the UPM:
  7. When prompted, Refresh the page.
  8. Navigate to the Manage my Plugins tab.
    Note that the tab navigation is different than it was prior to the UPM update.
  9. Scroll down to User-Installed Plugins and locate the plugin-license-compatibility-tutorial entry.
  10. Click the entry to view its details:

    You should now see a License Key value and a pencil icon.
  11. Click on the pencil icon to reveal the license:

    If you set a license already using the LicenseServlet you should see the same license here.
  12. Go to the LicenseServlet page.
    You should see a response with a link back to the UPM like the following:

Step 9. Add some branding

You can add branding materials to your license aware plugin. This branding material appears only when UPM 2.0 is installed together with your plugin in the Atlassian product. If you want to try adding this, go ahead and skip to Step 7. of How to Create a Submission-ready JAR

Was this page helpful?

Have a question about this article?

See questions about this article

Powered by Confluence and Scroll Viewport