I am trying to get the JIRA issue details onto the salesforce Case object. I followed the documentation and I created to Apex classes and One VisualForce page.

I am getting the error on the visual force page section : Content cannot be displayed: Malformed JSON: Expected '[' at the beginning of List/Set.

What would be wrong in my code? Any ideas?

Following are my codes for this project:

JIRA fetch

public class JIRAFetchIssuesController {

private String issuesJson;

// Constructor of this class. Note that a request will be sent to JIRA when this class is constructed.
public JIRAFetchIssuesController(ApexPages.StandardController stdController) {
    Case theCase = (Case)stdController.getRecord();
    this.issuesJson = getResultJson('Case', theCase.id);

// Sends request to JIRA and returns the request body which should be a valid JSON.
private static String getResultJson(String objectType, String objectId) {
    try {
        HttpRequest req = buildRequest(JIRA.baseUrl, JIRA.username, JIRA.password, JIRA.systemId, objectType, objectId);
        HttpResponse res = JIRA.sendRequest(req);
        return res.getBody();
    } catch(System.CalloutException e) {
        return '';

// Constructs request needed to fetch JIRA issues from provided parameters.
@testVisible private static HttpRequest buildRequest(String baseUrl, String username, String password,
                                 String systemId, String objectType, String objectId) {
    HttpRequest req = new HttpRequest();
    String basicAuthHeader = JIRA.authHeader(username, password);
    String endpoint = getEndpoint(baseUrl, systemId, objectType, objectId);
    req.setHeader('Authorization', basicAuthHeader);
    return req;

// Creates the endpoint to fetch the issue from provided parameters.
private static String getEndpoint(String baseUrl, String systemId, String objectType, String objectId) {
    return baseUrl + '/rest/customware/connector/1.0/' + systemId + '/' + objectType + '/' + objectId + '/issue/fetch.json';

public String getIssuesJSON() {
    return this.issuesJson;

public List<JIRAIssue> getIssues() {
    return (List<JIRAIssue>)JSON.deserialize(this.issuesJson , List<JIRAIssue>.class);

// JIRA Issue Object.
@testVisible class JIRAIssue {

    public String summary { get; }
    public String project { get; }
    public String reporter { get; }
    public String key { get;}
    public String status { get; }
    public String resolution { get; }
    public String url { get; }
    public String type { get; }
    public String assignee { get; }
    public String description { get; }
    public String priority { get; }
    public String due_date { get; }



JIRA public with sharing class JIRA {

// Change values in this class according to you JIRA/Salesforce coordinates.

public static String baseUrl = 'http://jira.hdquotecenter.com/'; // Base URL of your JIRA instance
public static String systemId = '2'; // Salesforce Connector System ID in JIRA
public static String username = 'venkatdavuluri';  // JIRA username
public static String password = 'Wildcraft@987'; // JIRA password

public static String agentProfileName = 'JIRA Agent'; // Jira agent profile name in Salesforce

// Constructs Basic Http Authentication header from provided credentials
public static String authHeader(String u, String p) {
    Blob headerValue = Blob.valueOf(u + ':' + p);
    return 'Basic ' + EncodingUtil.base64Encode(headerValue);

// Sends a request and returns the response
public static HttpResponse sendRequest(HttpRequest req) {
    Http http = new Http();
    return http.send(req);

// Detects whether current user is not JIRA agent. By calling this you can make sure that
// infinite loops won't happen in triggers (for instance when synchronizing an issue with JIRA)
public static Boolean currentUserIsNotJiraAgent() {
    Boolean allow = false;
    List<Profile> jiraAgentProfile = [SELECT Id FROM Profile WHERE Name=:JIRA.agentProfileName];
    if (!jiraAgentProfile.isEmpty()) {
        String jiraProfileAgentId = String.valueOf(jiraAgentProfile[0].id);
        allow = UserInfo.getProfileId() != jiraProfileAgentId;
    return allow || Test.isRunningTest();



<apex:pageblock title="JIRA Issues" rendered="{!Issues.size > 0}">
<!-- Create table for JIRA issues. With  -->
    <apex:pageBlockTable value="{!Issues}" var="issue">
        <!-- Issue Key column -->
        <apex:column headerValue="Issue Key">
            <!-- Make it link to JIRA Issue -->
            <apex:outputLink value="{!issue.url}" target="_blank">{!issue.key}</apex:outputLink>
        <!-- Issue Resolution column -->
        <apex:column headerValue="Resolution" value="{!issue.resolution}"/>
        <!-- Issue Status column -->
        <apex:column headerValue="Status" value="{!issue.status}" />
        <!-- Issue Assignee column -->
        <apex:column headerValue="Assignee" value="{!issue.assignee}" />

<apex:pageblock title="JIRA Issues" rendered="{!Issues.size == 0}">
    <apex:outputLabel >No JIRA Issue associated with this Case</apex:outputLabel>

1 Answer 1


This code:

return (List<JIRAIssue>)JSON.deserialize(this.issuesJson, List<JIRAIssue>.class);

requires that the JSON is an array at its root (starts with [) but it appears that in your code it does not.

I suggest you System.debug(issuesJson); immediately before that line and see what the JSON format is. There may be a root object that has a name that holds the array. Or check the documentation for the end point you are using.

  • Should I put it in front of the return or (List<JIRAIssue>)?
    – abhi
    Feb 3, 2017 at 14:31
  • I got the Answer. I had a blackslash on the endpoint URL in the remote site settings. I figured it out.
    – abhi
    Feb 3, 2017 at 21:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.