We at Nimble love to develop and experiment with different technologies and share our experiences with our community. This time around developing an Atlassian plugin became our fancy. Atlassian of course offers tools for development, collaboration and continuous delivery such as Jira, Confluence, Bitbucket and Bamboo. Atlassian also offers a rich REST API to build integrations and plugins that one can add/extend their basic tool functionality.
So I started on my journey and found a few gotchas that I think are interesting if you happen to go down that path.
1. The basics
a. Sign up for an account at http://developers.atlassian.com. Atlassian offers two plugin development SDKs for their cloud based and their in-house server based versions.
b. Consider signing up for an account at bitbucket.org if you don’t already have a SCM or if you want to try out a nice cloud based code collaboration tool that provides Git repos to host your code and also offers integration with several tool suites including a cloud based continuous integration and delivery tool. More on this later…
2. Issues with the tutorial
I started exploring the server side development and accessed the tutorial at https://developer.atlassian.com/docs/getting-started/set-up-the-atlassian-plugin-sdk-and-build-a-project. The tutorial does a great job at the setup and gets you going, but it is dated.
Most of my time really went into trouble shooting issues with dependencies in pom.xml and conflicting directives in the plugin config file: atlassian-plugin.xml
Following a few sub links in the tutorial:
You are directed to convert the plugin component to a servlet model at https://developer.atlassian.com/docs/getting-started/learn-the-development-platform-by-example/convert-component-to-servlet-module by adding the following lines in the atlassian-plugin.xml
<component key="myPluginComponent" class="com.atlassian.plugins.tutorial.refapp.MyPluginComponent" public="true">
<servlet name="adminUI" class="com.atlassian.plugins.tutorial.refapp.MyPluginServlet" key="test">
Next there are SAL (Secure Access Layer) class components that need to be imported into the project. Look at https://developer.atlassian.com/docs/getting-started/learn-the-development-platform-by-example/control-access-with-sal which directs you to add the following lines to your atlassian-plugin.xml
<component-import key="templateRenderer" interface="com.atlassian.templaterenderer.TemplateRenderer" filter=""/>
<component-import key="userManager" interface="com.atlassian.sal.api.user.UserManager" filter=""/>
<component-import key="loginUriProvider" interface="com.atlassian.sal.api.auth.LoginUriProvider" filter=""/>
<component-import key="pluginSettingsFactory" interface="com.atlassian.sal.api.pluginsettings.PluginSettingsFactory" filter=""/>
Compiling this code promptly delivers an error messsage while using the latest version of Atlassian spring scanner and JDK 1.8. The error message is that servlet directive and the component import tags are not compatible
After a lot of time troubleshooting, I hit upon the reason. The latest version of spring scanner supports annotations instead of tags. Take a look at the revamp suggested at https://bitbucket.org/atlassian/atlassian-spring-scanner
The Atlassian-plugin.xml file should not contain any of the <component-import> tags and in your servlet code add annotations such as the below
private final UserManager userManager;
private final LoginUriProvider loginUriProvider;
private final TemplateRenderer templateRenderer;
private final PluginSettingsFactory pluginSettingsFactory;
This needs to be updated in the tutorial.
3. Use a RefApp
Instead of developing for a particular tool like jira or confluence, developing for RefApp gives you the flexibility of completing your plugin development irrespective of the tool and then generating a plugin version for the target tool. RefApp provides the shared framework between all Atlassian applications. This means that you can develop your plugin without accidentally relying on dependencies or features specific to one application, or encountering an application-specific bug later on. Developing a plugin with RefApp eliminates guesswork about the functionality of your project. You can rest assured that since all Atlassian applications share at least the framework present in RefApp, your plugin will work as expected.
4. Leverage bitbucket pipeline
One of the other advantages of hosting your code at bitbucket.org is that you can use Bitbucket pipeline. Bitbucket pipleline is a new offering and still in beta. I happen to be part of the beta program and got an opportunity to kick the tires. In short the tool is a continuous integration and continuous delivery tool that relies on the presence of a bitbucket-pipelines.yml file in your top level of your project. The yml file with the below directives helped me build my plugin on the cloud. The pipeline relies on running builds, tests and deployment with pre-configured docker images. Anytime you update your code, the pipleline runs based on the directives as in the below yml file.
# You can use a Docker image from Docker Hub or your own container
# registry for your build environment.
script: # Modify the commands below to build your repository.
- cd adminUI
- atlas-mvn clean install
5. Develop an Atlassian plugin like its 2016
Take a look at the details at the following two write ups….
You can find my latest code and use to kick start your plugin development at https://github.com/aniljaising/atlassian-plugin-tutorial
I would love to get your feedback on this article as well feel free to ask any questions…
July 20, 2016
by Anil Jaising