Chapter 1. Plugin Basics
Overview
Building any plugin for JIRA starts with downloading the most recent Atlassian Plugin SDK (Software Development Kit) from the Atlassian Developers site at https://developer.atlassian.com/display/DOCS/Set+up+the+Atlassian+Plugin+SDK+and+Build+a+Project.[1] This chapter explains how to use the Plugin SDK and some other things common to all plugins. The same SDK is also used to develop plugins for other Atlassian products such as Confluence. Subsequent chapters contain details about specific kinds of JIRA plugins.
If you haven’t already found them, there are a number of tutorials about developing different kinds of plugins online at https://developer.atlassian.com/display/JIRADEV/JIRA+Plugin+Tutorials. I recommend using them and their source code at https://bitbucket.org/atlassian_tutorialalong with this book since they mostly complement each other.
The Atlassian Answers site at http://answers.atlassian.com is the best place to ask technical questions about how to develop plugins. The tag “jira-development” is most commonly used. The old JIRA Developer Forum at http://forums.atlassian.com/forum.jspa?forumID=100 is also a useful place to find answers but it’s now read-only.
Beyond some basic Java skills, in order to write a JIRA plugin you’ll also need to understand how Apache Velocity templates are used by JIRA. These are the files that control how HTML pages are formatted, and are covered in more detail in Apache Velocity. For more complicated plugins you may need to know more about Apache Maven, the build and deploy tool for Java described in the section Maven.
JIRA uses many other technologies and it can be useful to have some familiarity with any of these: Subversion, Mercurial, Ant, Apache JSP, JavaScript, JQuery, Soy and Jersey for REST. However for most plugins you won’t need to know anything about them—just Java and a bit of Velocity and Maven.
Creating a JIRA Plugin
JIRA plugins use an Apache Maven 2 project for each plugin to
produce a Java .jar
file that can be
installed in JIRA.
A Maven project has a fairly rigid layout, always with a top-level
XML file named pom.xml made up of the
plugin’s name, version, dependencies and so on. The groupId
and artifactId
variables in pom.xml are what make a plugin unique within
Maven. The artifactId
is also what will
appear as part of your plugin .jar file’s name. The name
variable is the more verbose name of the
plugin, as seen in the JIRA plugin administration pages. The SDK will
create a working pom.xml file for us
with some reasonable default values.
Tip
Atlassian’s guidelines on the use of “JIRA” are that a name such as “Acme plugin for JIRA®” is okay, whereas “JIRA® plugin for Acme” is not. The former connotes a 3rd party plugin for JIRA®, while the latter connotes an Atlassian-developed tool. More information is available at http://www.atlassian.com/company/trademark or contact developer-relations@atlassian.com.
The first thing to do is to unpack the SDK in a convenient location.
This location is referred to as $SDK_HOME
in the examples below. You can then
create a JIRA plugin with a single command:
$SDK_HOME/bin/atlas-create-jira-plugin
This command will prompt you for a few values and then create a new plugin directory with enough files to build a plugin. This skeleton plugin does nothing, but it can be installed in JIRA and will appear in the list of plugins shown in the Administration plugins page.
As mentioned earlier, the artifactId
and groupId
values appear directly in the Maven
pom.xml file. Every Atlassian plugin
has a unique identifier named key. The key for each plugin is defined in the file
atlassian-plugin.xml, and by default
the key is “artifactId
.groupId
”.
The version
argument is the
version of your plugin, not the JIRA version. Versions can be any text but
the Atlassian Marketplace (see the section Atlassian Marketplace) now requires that the version starts
with three sets of digits, not two. A version can also look like 5.1.0-alpha
. The package
argument is the name of the Java package
that the plugin’s Java source code will use.
Tip
If you want to, you can also provide the same information that was required to create a plugin directly from the command line:
$SDK_HOME/bin/atlas-create-jira-plugin \ --artifactId myplugin \ --groupId com.mycompany.jira.plugins \ --version 5.1.0 \ --package com.mycompany.jira.plugins.myplugin --non-interactive
Important Plugin Files
The most important files in a plugin directory and their purposes are as follows.
- pom.xml
The top-level Maven 2 project file for the plugin.
- README
The place to start for the description of what the plugin is intended to do. This can be renamed to anything you like or removed.
- LICENSE
A place holder for the license for the plugin. Many JIRA plugins use the BSD license by default, but the section Further Reading has more information about choosing a license.
- src
The directory that contains all the source files needed to build the plugin.
- src/main/resources/atlassian-plugin.xml
The XML file that specifies exactly what the plugin really contains. The order of the elements in this file doesn’t make a difference to how they work.
- src/main/java/com/mycompany/jira/plugins/myplugin
The default location for Java source files, based on the
package
name used when the plugin was created.- src/main/java/com/mycompany/jira/plugins/myplugin/MyPlugin.java
A sample Java source file, automatically generated. You can rename or delete this file later on.
- target
The location of all generated files after a build has finished. None of the files in this directory need to be version controlled.
- target/myplugin-5.1.0.jar
The generated plugin package that is deployed to JIRA to actually use the plugin. The filename contains the version that was specified in pom.xml.
There are a few other files generated in the src/test directory related to testing your plugin. You can delete them if they’re not wanted, but an even better practice is to write some tests as described at https://developer.atlassian.com/display/DOCS/Plugin+Testing+Resources+and+Discussion.
Reading a Plugin
Before diving into building a plugin, it’s useful to know how to understand what any JIRA plugin does. Knowing how to read a plugin also makes it easier to find examples on which to base your own work.
My own approach is to start with the top-level Maven file pom.xml and to look for the jira.version
element. That should tell you which
version of JIRA the plugin was last built against. If it’s too old for you
to use, then see Updating a Plugin Version at the Marketplace for
ideas on how to update it. There is also a jira.data.version
element that tells you the
version of the JIRA database schema the plugin last worked with. As might
be expected, this changes less frequently than jira.version
but should be close to the value of jira.version
.
The next file to read is src/main/resources/atlassian-plugin.xml. This file contains all the different plugin module types that are used in the plugin and tells you what the plugin provides; e.g., a new custom field type. The initial skeleton plugin doesn’t have any plugin modules in this file because it doesn’t do anything.
Then I’ll read any documentation or perhaps look at a few screen shots. Usually only after all that do I look at actual Java source code and Velocity template files.
Building and Deploying a Plugin
The minimal commands to build a plugin from the command line are:
$ cd myplugin $ $SDK_HOME/bin/atlas-package ... [INFO] ---------------------------------------------------- [INFO] BUILD SUCCESSFUL [INFO] ---------------------------------------------------- [INFO] Total time: 26 seconds [INFO] Finished at: Wed May 11 03:11:48 PDT 2011 [INFO] Final Memory: 56M/118M [INFO] ----------------------------------------------------
This last command will download the dependencies listed in the
pom.xml, which includes the large atlassian-jira-N.N.N.jar
for the version of JIRA
specified in jira.version
in pom.xml. Before spending time downloading these
large files, it’s worth checking that the jira.version
is set to the version of JIRA you
really want to use.
The command will then compile the Java source files and create the plugin’s .jar file. You should make sure that you have a recent Java JDK installed on the machine where the plugin is being built. JIRA 4.1 supports the Oracle (formerly Sun) JDK 1.5, but JIRA 4.2 and later require JDK 1.6. JIRA 5.1 does not support JDK 1.7.
The first time all this is done it can take a while but
subsequently should be faster. If the dependencies in your pom.xml file don’t change, then you can even
add the -o
or --offline
flag to atlas-package to work offline and make the build
a little faster.
When the build is finished you should see a .jar
file in the target directory. That’s your plugin .jar
file.
To deploy the plugin to a production JIRA instance, copy the plugin
.jar file to plugins/installed-plugins in the JIRA_HOME
directory—or with JIRA 4.3 and later,
you can upload it using Administration→Plugins and the Install or Manage Plugins tab.
Prior to JIRA 4.4, most JIRA plugins
require you to restart JIRA to complete a plugin installation or
update.
Using atlas-run and atlas-cli
The SDK also provides another way to build and deploy a JIRA plugin. If you type:
$SDK_HOME/bin/atlas-run
instead of atlas-package, then
a brand new instance of JIRA is automatically configured in the
target directory. Then the plugin
.jar file is deployed there and the new JIRA instance is started up at
http://localhost:2990/jira
. You can
log in with the user name admin
and
password admin
and test your plugin
directly there.
This second approach takes a little longer to start up the first time, but you don’t have to configure anything such as a license. The other benefit of this approach is that in some cases it allows for much faster redeployment of plugins. If you open another separate window from the same top-level directory and type:
$SDK_HOME/bin/atlas-cli
then a maven2>
prompt
appears. Typing pi
for “plugin
install” at the prompt will rebuild and redeploy your plugin in a
few seconds instead of the minute or so it can take to restart
JIRA. More information about all of the SDK commands can be found at https://developer.atlassian.com/display/DOCS/Atlassian+Plugin+SDK+Commands
This is a fast way to develop plugins, but prior to JIRA 4.4,
it only works if a plugin is using certain plugin module types. The list
of which types do and do not work with pi
can be found at https://developer.atlassian.com/display/DOCS/Plugins+that+Cannot+be+Reloaded+with+FastDev+or+pi.
The good news is that as of JIRA 4.4 almost all plugins can be reloaded
using pi
or from the Administration
menu, which will save everyone a lot of time during development.
The fastest way to develop a plugin now is to use the FastDev tool (https://developer.atlassian.com/display/DOCS/Automatic+Plugin+Reinstallation+with+FastDev). After starting JIRA using the atlas-cli command this tool checks each time that a page is reloaded whether the plugin needs to be rebuilt and also reloaded.
What Can JIRA Plugins Do?
Doing something useful in your plugin involves adding one or more plugin modules to the atlassian-plugin.xml file. You’ll also most likely need to add some Java source and Velocity template files. Chapter 2 and the rest of this book covers exactly how to do that.
There are over 30 different types of plugin modules listed at http://confluence.atlassian.com/display/JIRA/JIRA+Plugin+Guide. Each plugin module has a separate page documenting the XML attributes and elements that it supports.
Tip
Much of JIRA’s own functionality is defined using these same plugin module types in files with names that look like “system-*-plugin.xml”. These source code files are always a good place to check for working examples of each plugin module type. The complete list of JIRA’s plugin module types is configured in the file JiraModuleDescriptorFactory.java.
The different plugin modules that are documented at https://developer.atlassian.com/display/JIRADEV/JIRA+Plugin+Guide can be grouped as follows.
Custom Fields
Workflow
- workflow-condition
Adds a new workflow condition to restrict when the status of an issue is changed. There is an example in Conditions.
- workflow-validator
Adds a new workflow condition to validate the inputs when the status of an issue can be changed. There is an example in Validators.
- workflow-function
Adds a new workflow post-function to update an issue after its status has changed. There is an example of this in Post-Functions.
User Interface
- project-tabpanel
component-tabpanel
version-tabpanel
issue-tabpanel These plugin modules let you add new tabs to the Project page, a project’s Components page, a project’s Versions page and to the view screen of an issue.
- web-item
web-section
web-panel-renderer Add new operations or groups of links to existing JIRA web pages and their menus. Since JIRA 5.0 the renderer module gives you more control over how the content of different parts of JIRA web pages are displayed.
- keyboard-shortcut
Add a new keyboard shortcut to JIRA.
- issue-link-renderer
Change how an remote issue link is displayed. New in JIRA 5.0.
- webwork
Add a new URL and web page to JIRA. This is used as part of the example in Adding Configuration to a Custom Field.
- issue-operation
Prior to JIRA 4.0 this added a new operation to the screen that is shown when viewing an issue. Since replaced by the web-item plugin module
Reporting
- gadget
A new gadget that can be added to a JIRA dashboard.
- report
A report that can be selected from a projects Project page.
- jqlfunction
Add a new JIRA Query Language (JQL) function. JQL is mentioned briefly in How Searchers Work.
- search-request-view
Search Request views are the choices of how to view the list of issues in the Issue Navigator; e.g., Printable, Word or Excel.
- portlet
This has been deprecated since JIRA 4.0, when it was replaced by gadgets. It was removed in JIRA 5.0.
Remote Access
- rest
Define a new REST endpoint. REST is the future direction for remote access to JIRA.
- rpc-soap
Add a new SOAP endpoint for JIRA remote access. SOAP is currently the most common way of accessing JIRA remotely.
- rpc-xmlrpc
Add a new XML-RPC endpoint for remote access. This method of accessing JIRA is less frequently used.
Other Plugin Module Types
Some plugin module types are common to all Atlassian plugins. Most of these are documented further at https://developer.atlassian.com/display/PLUGINFRAMEWORK/Plugin+Module+Types.
- resource
web-resource
web-resource-transformer These module types refer to other files and resources used by JIRA plugins. Examples include JavaScript and CSS files, image files and internationalization files (Internationalization). Since JIRA 5.0 the transformer module gives you more control over how these files are used in a plugin at runtime.
- component
component-import These modules are how JIRA defines which classes can be injected into the constructors of the Java classes used within a plugin. They have nothing to do with a project’s components.
- servlet
servlet-context-listener
servlet-context-param
servlet-filter These modules allow you to intercept calls to JIRA URLs and change what is returned, as well as using new Java servlets.
- listener
This module lets you define a listener as part of an Atlassian plugin. More information can be found at https://developer.atlassian.com/display/CONFDEV/Event+Listener+Module. Since JIRA 5.0.
- module-type
This module lets you extend the JIRA plugin framework by defining new module types.
- user-format
These let you change how a user’s details appear in their profile.
- jira-footer
This undocumented module controls what appears at the bottom of every page in JIRA. An example of its use can be found in the JIRA source file system-footer-plugin.xml.
Which Methods Should My Plugin Use?
A public Java API was introduced in JIRA 5.0 (http://blogs.atlassian.com/2012/03/stable-apis-yes-we-have-them/). The classes and methods in the public API should not change as rapidly in each minor release. So if your plugin only uses the public API you shouldn’t have to update or recompile. A plugin built for JIRA 5.1 should just work when JIRA 5.2 is released. Obviously this promises to save everyone a lot of work. The rest of the core JIRA API is still available for plugins to use, but with the warning that it changes more rapidly that the public API.
To encourage plugin developers to use the public API, Atlassian have created a tool where you can upload a plugin’s .jar
file and see a report about which parts of the plugin are not using the public API for a particular version of JIRA.
More information about the plugin checkup tool see https://developer.atlassian.com/display/CHECKUP/Overview+of+the+Atlassian+Plugin+Checkup.
The official policy about what will and will not change in the different kinds of releases can be found at https://developer.atlassian.com/display/JIRADEV/Java+API+Policy+for+JIRA.
Troubleshooting a Build
In theory building your plugin should just work. In practice you may have one of the following common errors.[2]
If the build fails with the error Cannot
execute mojo: resources
then check that you’re in the same
directory as the pom.xml file.
If you get errors about missing dependencies it means that Maven
didn’t know how to download a particular file that was specified in a
dependency
element in pom.xml. Check for typos in the groupId
and artifactId
elements of the dependency
, particularly if you added them by
hand. You may also want to check for newer versions of the same dependency
using Google. A few files such as activation.jar are not available from a Maven
repository due to licensing restrictions, so they have to be downloaded
and installed locally if needed.
Maven nicely provides you with the necessary command to install a .jar file locally to resolve a missing dependency. If you do this, then don’t forget to note where the .jar file was originally downloaded from.
Finding the correct version number for a Maven dependency is not
always easy. Sometimes the version can be found by searching for an
artifactId
value in the pom.xml files within the JIRA source for the
appropriate version of JIRA, or by looking at the version of the different
.jar files that are shipped with JIRA. Since JIRA 5.0 the Atlassian Developer Toolbox has a page that shows the component versions being used in an instance of JIRA.
Tip
One useful tip is that any flags after an SDK command are passed
directly to Maven. So you can add a parameter such as --file other-pom.xml
to any atlas- command to try debugging a build by
using an alternative pom.xml
file.
Sometimes a build fails when it is building or running unit tests.
Those tests are there for a good reason, but if you
really have to build without them then you can
disable them. Adding the parameter -Dmaven.test.skip
to $SDK_HOME/bin/atlas-package
prevents Maven from compiling and executing
the tests. Or you can skip just their execution with the -DskipTests
parameter.
It’s a good idea to avoid using the com.atlassian.jira
namespace for your plugin’s
Java source code. The classes that
you create should be only visible to your plugin at runtime, but it’s confusing
for other people trying to understand your code and is not recommended.
Another thing to be careful about is making sure that you only have one instance of a plugin deployed. Multiple versions of a plugin can accidentally get deployed if you change the plugin’s version number and then forget to remove the old plugin .jar file when you deploy the new one. Or if you have deployed a plugin both manually and using JIRA’s own plugin manager. Which of the two .jar files is used by JIRA is not defined and unexpected results may occur.
One of the most common problems with JIRA plugins happens at
runtime. The log file contains an UnsatisfiedDependencyException
error about a
constructor in your plugin. This and
other runtime problems are described in more detail at. https://developer.atlassian.com/display/DOCS/Plugin+and+Gadget+Gotchas.
Another runtime error that can be hard to debug is using the wrong
version of JIRA in pom.xml. If one
particular JIRA URL produces a page with Java reflection errors about a
class that changed subtly between versions of JIRA, then you may have
compiled your plugin against one version of JIRA and be using it with
another incompatible version. The surest sign of this is usually that
there are no errors in JIRA log file. Check that the jira.version
in pom.xml matches your local JIRA instance,
delete the plugin’s target directory
and rebuild and redeploy the plugin.
Logging
JIRA uses the Apache log4j
logging framework to record messages in the log/atlassian-jira.log file under the jira.home
directory. This is one easy way to
understand what is happening within a plugin during its development.
Another way is to use a debugger, as described in Using a Debugger with JIRA.
To use logging within a plugin, first add a Logger
variable to your source code as shown in
Example 1-1. The name of the Logger
, in this case com.mycompany.jira.plugins.conditions.MyClass
,
can be any unique text but the full Java class name is often a convenient
string.
package com.mycompany.jira.plugins.conditions; import org.apache.log4j.Logger; public class MyClass { private static final Logger log = Logger.getLogger(MyClass.class); public void MyMethod() { log.debug("This message is only seen at the DEBUG log level"); } }
Next add the following two lines to the file atlassian-jira/WEB-INF/classes/log4j.properties. under the JIRA install directory:
log4j.logger.com.mycompany.jira.plugins.conditions.MyClass = DEBUG, console, filelog log4j.additivity.com.mycompany.jira.plugins.conditions.MyClass = false
The two lines in log4j.properties have a few parameters. The
first one is the log level to use (DEBUG
). The other two (console
and filelog
) are the names of
appenders, which define the places that logging
output goes. filelog
is the appender
for atlassian-jira.log. The second
line with additivity
stops any parent
loggers from logging the same message more than once so you don’t see
duplicate log entries.
The log level is the level of messages that you want to display. In
this case we’re using the DEBUG
log
level. A log level of WARN would only show messages created with log.error()
or log.warn()
, but not log.info()
or log.debug()
.
The most common log levels are in order: ERROR
, WARN
,
INFO
and DEBUG
. If your plugin is using FATAL
log messages, you’re doing something that
is at risk of stopping all of JIRA, which seems a bit much for a mere
plugin. There is also the less common TRACE
level which is lower than DEBUG
.
Restart JIRA to pick up the changes in log4j.properties and check the atlassian-jira.log file for output lines such as:
2010-12-31 15:23:41,123 http-9990-Processor24 DEBUG admin 55421x4x1 129mqbi http://localhost:8800/test.jspa [jira.plugins.conditions.MyClass] This message is only seen at the DEBUG log level
Tip
If you aren’t seeing the log messages you expect to see, check the precise spelling of the appropriate entry in log4j.properties. Also check that the log level of the message is equal or greater than the current level in log4j.properties.
Once the log4j.properties file has had the new entries added, they can be temporarily changed at Administration→System→Logging & Profiling. In this case, the next time JIRA is restarted the log level will be set back to the value in log4j.properties. Since JIRA 5.0 you can add new entries without restarting JIRA.
Another useful idea is to use the same identifier for all the
log
objects in a plugin across
different classes. You can do this by using the same MyClass.class
identifier in all the classes.
Another approach to do the same thing is to declare the log
variable as public
in one class and the refer to it as
a static variable from the other classes.
The entire log4j
framework is
described in much more detail at http://logging.apache.org/log4j/1.2/manual.html and https://developer.atlassian.com/display/DOCS/Using+your+own+log4j+configuration+for+your+plugin.
Apache Velocity
Apache Velocity is the templating language used by most JIRA plugins. A templating language allows you to use template files that contain most of the HTML that you want to appear on a web page, and then insert other pieces of HTML dynamically when the template is rendered into HTML by the JIRA server and is returned to a web browser. A plugin’s Java source files and its Velocity templates are usually closely related to each other.
Example 1-2 shows a simple example
of a Velocity template. If it is stored in a file for a plugin it would
usually have a .vm
suffix and be
located somewhere under src/main/resources/templates. Note that
Velocity template filenames have to be unique within JIRA, not just within
the plugin.
## A simple Velocity template file #if ($value) $value.toString() #else This field is empty. #end
Velocity commands and user-defined macros start with a #
character. Comments start with ##
and Velocity variables begin with a $
character. Velocity files are rendered
together with a Velocity context (basically a Java Map
) that contains the Java objects that each
Velocity variable refers to. These objects can be used like any ordinary
Java object. For example, Example 1-2
shows the toString
method being called
on the value
object. The rest of the
file is used unchanged in the generated HTML, including any leading spaces
and HTML comments.
If you use a variable such as $myvalue
that is not yet defined, Velocity will
display the string $myvalue
in the
HTML, and may log an error in the JIRA log file. If you’d prefer such an
undefined variable to be rendered as an empty string then just use a
“quiet reference” to the variable: $!myvalue
. A quiet reference looks like a Java
negation, but they are unrelated.
You can also access a property such as color
of a variable with $myvalue.color
. This is the same as using
$myvalue.getColor()
but is more
compact.
You will also see references to a variable named i18n
in many Velocity template files. This is
how text messages are internationalized and is described further in Internationalization.
Debugging Velocity template files can be a fiddly task if you’re not sure what variables are available for use in the Velocity context. To make this task easier, some of the Velocity contexts used by JIRA add the Velocity context itself as a variable to the context. This let’s you display all the variables in the context with Velocity code such as:
#foreach($variableName in $ctx.keySet()) $variableName.toString() - $ctx.get($variableName).getClass().getName()<br/> #end
which will produce a listing of all the variables and their Java classes such as this:
ctx - java.util.HashMap customFieldManager - com.atlassian.jira.issue.managers.DefaultCustomFieldManager issue - com.atlassian.jira.issue.IssueImpl field - com.atlassian.jira.issue.fields.CommentSystemField …
In email templates the context is available as $context
, and for some plugin types it is
available as $ctx
. However, the context
is not available for custom field types.
There is some more information about the different Velocity contexts that are used by JIRA at https://developer.atlassian.com/display/JIRADEV/JIRA+Developer+FAQ. There is a fairly concise Velocity User Guide available at http://velocity.apache.org/engine/devel/user-guide.html and which I recommend reading.
Tip
If you are developing Velocity templates that are not delivered in
a plugin .jar file, then you can edit velocity.properties to have JIRA reload all
the .vm
files without restarting.
This setting and various other changes can also be enabled using the
jira.dev.mode
flag to JIRA, as
described in JIRA Development Mode.
Velocity macros can be defined using the #macro
command inline in the same .vm
template file, but they can’t be shared
between the various template files of a plugin.
Including one template file in another can be done with the #parse
command. The name of the file to pass to
the #parse
command is everything below
the src/main/resources directory, for
example:
#parse("/templates/com/mycompany/jira/plugins/myplugin/file-to-be-included.vm")
The #macro
and #parse
commands can be combined to make Velocity
templates much easier to debug and maintain.
Maven
As introduced in Creating a JIRA Plugin, Apache Maven is a build and deploy tool used by JIRA and many other applications written in Java. This section contains more information about how Maven is used by JIRA plugins.
Maven downloads all the .jar
files needed to compile and deploy a plugin using the dependency
elements listed in the top-level
pom.xml file. For example, if a
plugin needs to access the HttpServletRequest
variable in a method, you
will need to add a dependency such as:
<dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency>
This tells Maven to search the repositories that it has been configured with for a group of releases named “javax.servlet”, and then search in those for the file named servlet-api-2.5.jar.
The part of dependencies that can be confusing if you’re not aware
of how it works is the scope
element.
If there is no scope, then the .jar
file is only available during compilation, but the .jar
will also be packaged up in the plugin’s
.jar
file. A scope of provided
means that the plugin can expect to
find it as part of the files shipped with JIRA application, and so the
.jar
file is not
added to the plugin .jar
file. There
are also other scopes such as test
that
have their own restrictions on when the classes in the .jar
file are available.
The Plugin SDK that is used to build JIRA plugins is actually a series of atlas- scripts that call a local copy of Maven at $SDK_HOME/apache-maven/bin/mvn with a settings.xml file that already contains the locations of Atlassian’s own Maven repositories. If you’re already comfortable with Maven then you can modify your existing Maven installation with those settings and use it to build JIRA plugins instead of the SDK.
More information about Apache Maven can be found at http://maven.apache.org. Most Maven behavior is controlled by plugins chosen from the ones listed at http://maven.apache.org/plugins. For example, plugin unit tests use the Surefire plugin (http://maven.apache.org/plugins/maven-surefire-plugin).
Further Reading
Software licensing is a complex matter. One place to start is with the list of different license types shown at http://www.gnu.org/licenses/license-list.html. Another helpful resource is the book Understanding Open Source and Free Software Licensing by Andrew M. St. Laurent (O’Reilly).
For the specific details of using different IDEs to create JIRA plugins, see https://developer.atlassian.com/display/DOCS/Generate+Project+Files+for+a+specific+IDE.
Dan Rosen of Atlassian wrote an excellent four-part blog post about creating Atlassian plugins that starts at http://blogs.atlassian.com/developer/2011/02/plugin_architecture_episode_iv.This. html series covers creating a cross-product plugin but contains other useful information as well. The order of the posts is significant: IV, V, VI and I (think Star Wars).
Another well-written starter tutorial for a JIRA plugin that adds new menus and links is http://blog.networkedcollaboration.com/2012/02/18/adding-menu-items-to-jira/.
Get Practical JIRA Plugins now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.