Plugin Developer Notes for JIRA 4.3
On this page:
Introduction
JIRA 4.3 introduces several changes that may break existing plugins which are not bundled with JIRA. For more details please see the API Change documentation.
If you are using or have been involved in the development of such a plugin, it may need to be updated to work with JIRA 4.3. Please read through the information below to see if any of this content is relevant to your plugin.
If you are using a plugin developed by a third party, please check with the plugin's author to see if the plugin has been tested with JIRA 4.3.
Please Note:
- This is not the complete list of changes for JIRA 4.3 — it only describes changes in JIRA 4.3 that will impact plugin developers.
- For details about which versions of Atlassian's Plugin Development Platform and its components (such as the Plugin Framework, Shared Access Layer (SAL), Atlassian User Interface (AUI) and the Atlassian REST Plugin) are included in JIRA 4.3, please refer to Plugin Development Platform Version Matrix.
I18nBean no longer in the PICO container
The I18nBean is no longer available for dependency injection. I doubt many people used it anyway, since it was broken if you tried to use it. (The bean didn't contain any keys defined in plugins.) As we move towards a translation-as-plugin and reloadable-plugin world the problem was just going to get worse. The current, correct way is to have an I18nHelper.BeanFactory injected and call getInstance() on it. This has the additional benefit of caching (only one object per-locale) which minimizes resource-bundle scanning.
GadgetRequestContextFactory no longer a host component
Previously there were two GadgetRequestContextFactory implementations being provided: one by JIRA directly (i.e. a "host component") and one by the gadget-renderer-plugin. The host component has been removed. If you are using a GadgetRequestContextFactory you will need to ensure that your atlassian-plugin.xml has a component-import statement so that OSGi gets wired up properly.
CacheManager deleted
The JIRA issue cache has not been in use for quite some time, and the CachingIssueManager
has not updated the cache for a while. This has now been completely removed out of JIRA. Previously, it may have been necessary to depend on this class to flush it, or call ManagerFactory.getCacheManager() to flush it, after certain operations. This has been a noop for quite some time, and is no longer necessary.
ApplicationPropertiesImpl
default constructor has been removed
As of JIRA 4.3, the default parameterless constructor of the ApplicationPropertiesImpl
class has been removed. This class was never intended to be instantiated directly from within plugin code. If you need to get an instance of the ApplicationProperties
component, please use one of the following approaches:
- dependency injection within plugin components,
- the
ComponentManager.getComponent()
method, or - the
ComponentLocator
injectable component
All of these approaches are compatible with versions of JIRA from 4.0.
Accessing delegators, connections and datasources in OfBiz
Delegator and datasource names will change in a future release
Calls to the following methods:
org.ofbiz.core.entity.GenericDelegator.getGenericDelegator("default");
org.ofbiz.core.entity.ConnectionFactory.getConnection("defaultDS");
are deprecated, and will break in a future version of JIRA. It should still work in JIRA 4.3, but it is planned that this will break in JIRA 4.4. The correct generic delegator can be injected, or if static access is needed, com.atlassian.core.CoreFactory.getGenericDelegator()
can be used. To get a connection, JIRA has added a new class called com.atlassian.jira.ofbiz.DefaultOfBizConnectionFactory
. This can be used using the following code:
new DefaultOfBizConnectionFactory().getConnection();
EntityConfigUtil refactoring
org.ofbiz.core.entity.EntityConfigUtil
has been significantly refactored. To access it, call EntityConfigUtil.getInstance()
. Accessing DatasourceInfo
should be done using the getDatasourceInfo()
method on the above mentioned DefaultOfBizConnectionFactory
.
Embedded Crowd
In JIRA v4.3 we have introduced a new User Management subsystem. Please refer to the JIRA 4.3 Upgrade Guide for general information.
This means that JIRA no longer uses the OSUser framework for user management. Instead it is now using modules taken from the Atlassian Crowd application, and hence this new subsystem is commonly referred to as "Embedded Crowd".
Approach to compatibility
In order to avoid compatibility and upgrade headaches for plugins, we have taken the following measures to transition the change as smoothly as possible:
A binary compatible copy of OSUser has been left in place
This means that existing code using OSUser Objects should continue to work.
The implementation of OSUser has been altered to call through to the underlying "embedded Crowd" user management layer.
The OSUser classes will remain for at least two versions (JIRA 4.3 and 4.4), but will be removed sometime after that.
OSUser's User and Group objects have been made to implement the new User and Group interfaces
public class User extends Entity implements com.atlassian.crowd.embedded.api.User
public class Group extends Entity implements java.security.acl.Group, com.atlassian.crowd.embedded.api.Group
This is useful because it means you can use the old User (or Group) object anywhere that is expecting the new User (or Group) object, which allows you to migrate your code piece by piece instead of trying to do it all in one go.
JIRA API methods that accept OSUser classes as input will remain but are deprecated
These methods will be removed when OSUser is removed.
For instance,
IssueService.getIssue(com.opensymphony.user.User user, Long issueId)
is now deprecated in favour of
IssueService.getIssue(com.atlassian.crowd.embedded.api.User user, Long issueId)
.
JIRA API methods that return OSUser classes as output will remain but are deprecated.
For instance,
GroupManager.getGroup(String groupname);
will continue to return com.opensymphony.user.Group
, but it is deprecated and replaced by
GroupManager.getGroupObject(String groupname);
which returns com.atlassian.crowd.embedded.api.Group
.
JIRA Plugin interfaces
Interfaces for plugin points sometimes include a User object in them (eg JqlFunction).
In these cases, we will leave the OSUser object in the short term for the sake of compatibility, and the interface will be altered when OSUser is removed.
Non-API Classes
Classes that are not considered part of JIRA's public API (Implementation classes) may be converted to the new User object at any time. Plugin developers should be avoiding these anyway.
New methods
New methods in API will only use the new User/Group interfaces.
Converting between old and new User objects.
The "old" User object has been made to implement the new User interface, and so no conversion is required in this direction.
You should not need to convert from the new to the old user Object very often, but if you do a Utility class OSUserConverter
is available.
Important changes
Don't use com.opensymphony.user.UserManager
This is a static factory class that implemented OSUser. It is supported in the short term but will be removed.
Use JIRA's dependency-injected Managers and Services instead:
- com.atlassian.jira.user.util.UserManager
- UserUtil (an extended UserManager)
- UserService
- GroupService
- GroupManager
Changes to the User object.
User-names are now case-insensitive. This is to reflect the way user-names are treated by LDAP.
Previously user-names were case-sensitive but forced to be all lower-case, so this change should not cause problems.
- getEmail() is deprecated to be replaced by getEmailAddress()
- getFullName() is deprecated to be replaced by getDisplayName()
DirectoryID
JIRA is now capable of connecting to multiple "User Directories" at once. A User Directory might be an LDAP server, a Crowd Server, or the "Internal Directory" (that is, users stored in JIRA's DB).
In order to tell which directory a User came from, there is a DirectoryID added to the User object. This means that in theory, you can have two users from two directories with the same username. (Note that this should be considered a rare and unusual situation — documentation will recommend that users try to avoid this).
For this reason, the username and directoryID are both considered in User.equals()
.
User Properties
OSUser allows you to store custom properties in a PropertySet
against a User. This will continue to be supported, but the PropertySet User.getPropertySet()
method is deprecated. Use the UserPropertyManager
to get user properties.
Changes to Seraph
If you are using a custom authenticator, note that two Seraph methods that were previously implemented in DefaultAuthenticator
to use OSUser have become abstract methods:
protected abstract java.security.Principal getUser(java.lang.String s);
protected abstract boolean authenticate(java.security.Principal principal, java.lang.String s) throws com.atlassian.seraph.auth.AuthenticatorException;
There is a concrete class in JIRA 4.3 called JiraSeraphAuthenticator
which extends the abstract DefaultAuthenticator
, implementing the above two abstract methods using Embedded Crowd. This means that, if you have written your own custom authenticator by extending DefaultAuthenticator
, you will need to either:
- continue to extend
DefaultAuthenticator
, but make sure you implement both abstract methods; or - extend
JiraSeraphAuthenticator
instead, which has already implemented those methods.
auth-refresh required for Gadget modules
You need to add the auth-refresh
feature to your Gadget module preferences inside the gadget.xml
file:
<Optional feature='auth-refresh' />
This enables your gadget to refresh its authentication token, which allows it to make requests. If you don't include the auth-refresh
feature, a JavaScript error will occur if your gadget makes a request after 30 minutes of inactivity.
Extension PICO Containers are no longer supported
Please note that from JIRA 4.3 onwards, the use of jira.extension.container.provider
in jira-application.properties is no longer supported.
New way to include browser-specific CSS
Previously when targeting a specific browser (e.g. IE6/IE7/IE8), you would put all CSS styles in a separate stylesheet and rely on IE-conditional comments to restrict which browsers received the files.
In JIRA 4.3 we have added some JavaScript which adds classes to the HTML tag on page load. This means that you can now put all browser-specific CSS fixes in the main stylesheet near related styles. Having styles in one file increases maintainability, and reduces the number of requests — which helps pages load faster.
Prior to 4.3 you would put IE styles in the IE stylesheet and prefix with * or _ depending on the browser. Now you can use the following:
- .msie (all versions of IE)
- .msie-7 (just IE7)
- .msie-8 (just IE8)
- .msie-gt-7 (IE8 and IE9)
- .msie-lt-8 (IE7, IE6, IE5.5, etc)
- .mozilla (all versions of Firefox. There are no version-specific options like IE)
- .webkit (all versions of Chrome/Safari. There are no version-specific options like IE)
- .opera (note: not a supported browser)
WebSudo - Temporary Administrative Access
We have added an extra layer of authentication to the administration actions in JIRA. If your plugin adds actions to the administration area, that is Actions that should only be for accessible by users with the admin or sys-admin roles, the Action should be annotated with WebSudoRequired on the class (not the action or package). If your administrative pages are not actions you can use the WebSudoManager following the instructions at Adding WebSudo Support to your Plugin.
JavaScript Reorganisation
To improve the consistency of JavaScript resources in JIRA 4.3, the namespaces of various JavaScript objects and functions have been changed and some JavaScript files have been moved or renamed.
JavaScript Namespace Changes
The table below lists all namespace changes to JavaScript objects and functions in JIRA 4.3. If your plugin uses JavaScript which refers to any of these objects and functions by their old namespace, you will need to update these in your plugin to the new namespace.
Old namespace |
New namespace |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
JavaScript File Changes
Along with the JavaScript namespace changes (above), several JavaScript files have been moved or renamed. Any plugins that load JIRA's JavaScript files directly may encounter "Resource not found" warnings due to this change.
Instead of loading these files directly, we recommend using the Web Resource framework to include JIRA's JavaScript files with plugins, as this method is backwards-compatible with JIRA 4.2.
<web-resource key="my-resource">
<dependency>jira.webresources:jira-global</dependency>
</web-resource>