Plugin blocking Jira UI - can it load async?

Hey team,

During testing of a Jira plugin I’m developing I noticed that if the API requests my plugin makes (to a 3rd party system) are slow to return data, the entire Jira Issues view is blocked and is waiting for the plugin to render. I always assumed the plugin is loading asynchronously in the view, but looks like I guessed wrong.

To give you and idea what’s going on, my plugin extends the AbstractJiraContextProvider class and in the override of getContextMap I am calling some of my product APIs. For example:

String myTaskId = apiHelper.getProductTaskId(currentIssue);

where getProductTaskId is pretty much doing:

 public JSONObject executeApiRequest(String url, PluginSettingsFactory pluginSettingsFactory) {
        try {
            URL obj = new URL(url);
            HttpURLConnection con = (HttpURLConnection) obj.openConnection();

            String accountId = getAccountId(pluginSettingsFactory);
            con.setRequestProperty("User-Agent", "JiraPlugin");
            con.setRequestProperty("Authorization", getToken(pluginSettingsFactory));
            int responseCode = con.getResponseCode();

            if (responseCode < 200 || responseCode >= 300) {
                return null;

            try (InputStream inputStream = con.getInputStream()) {
                BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
                String jsonText = readAll(in);
                return new JSONObject(jsonText);
        } catch (Exception e) {

        return null;

Has anyone noticed similar behavior when implementing API calls to populate objects in contextMap? Any idea why the plugin is not loading async and what can I do to make it async?


The issue is that everything that goes into that contextmap is blocking the templates rendering (and thus the rest of Jira). Plugins are not isolated in this way.

Data providers also block.

The only real option you have to is make a call from the browser (use the fetch API) to the server, or to your own server. If your own service is globally distributed, that could be great for cross-geo customers to make that request from the client.

If you want to be a little more advanced you could return an ID from this helper function and do the request asynchronously on the server, then have the client call the server to get the result and thus effectively create a promise. That creates a lot of extra work for you to do though, like building an eviction mechanism, building a retry, blocking the client req if the server request hasn’t completed yet, etc. This also makes the assumption that end-users are close to the server too.