Plugin Developer Notes for JIRA 4.3

JIRA 4.3 Upgrade Guide

On this page

Still need help?

The Atlassian Community is here for you.

Ask the community

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.

(info) 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

jira.app.issue

JIRA.Issue

jira.app.issuenavigator

JIRA.IssueNavigator

jira.app.issuenavigator.shortcuts

JIRA.IssueNavigator.Shortcuts

AJS.DropDown

AJS.Dropdown

jira.widget.dropdown

JIRA.Dropdown

AJS.containDropdown

JIRA.containDropdown

AJS.SelectMenu

AJS.DropdownSelect

AJS.SecurityLevelMenu

AJS.SecurityLevelSelect

AJS.QueryableDropdown

AJS.QueryableDropdownSelect

AJS.IssuePicker

JIRA.IssuePicker

AJS.LabelPicker

JIRA.LabelPicker

jira.widget.favourite.Picker

JIRA.FavouritePicker

AJS.FlexiPopup

JIRA.Dialog

AJS.FormPopup

JIRA.FormDialog

AJS.LabelsPopup

JIRA.LabelsDialog

AJS.IssueActionsPopup

JIRA.IssueActionsDialog

AJS.UserProfilePopup

JIRA.UserProfileDialog

jira.app.attachments.screenshot.ScreenshotWindow

JIRA.ScreenshotDialog

jira.widget.autocomplete

JIRA.AutoComplete

jira.widget.autocomplete.JQL

JIRA.JQLAutoComplete

jira.ajax

JIRA.SmartAjax

jira.app.wikiPreview

JIRA.wikiPreview

jira.app.userhover

JIRA.userhover

jira.app.session.storage

JIRA.SessionStorage

jira.xsrf

JIRA.XSRF

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>
Last modified on Nov 16, 2011

Was this helpful?

Yes
No
Provide feedback about this article
Powered by Confluence and Scroll Viewport.