Search code examples
jsongroovyjson-simple

Unexpected character (g) at position 0 when trying to parse json - HttpResponseDecorator


Whenever I try to execute below script I keep getting error, saying unexpected character (g). Basically I want to be able to parse the json response and be able to get the upstream job name from it.

Script:

@Grapes([
        @Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.7.1'),
        @Grab(group='commons-collections', module='commons-collections', version='3.2.1'),
        @Grab(group='org.jsoup', module='jsoup', version='1.10.2'),
        @Grab(group='org.json', module='json', version='20190722'),
        @Grab(group='com.googlecode.json-simple', module='json-simple', version='1.1.1')
])



import static groovyx.net.http.ContentType.*
import groovyx.net.http.HttpResponseException
import groovyx.net.http.RESTClient
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
import java.net.*
import java.util.*
import org.json.simple.*
import org.json.simple.parser.JSONParser;


def getRestClient(){
    String jenkinsUrl="http://somedomainname:8080"
    def restClient = new RESTClient(jenkinsUrl)
    return restClient
}

def getJobsInfo(String jobname,RESTClient restClient){
    def requrl= '/job/'+jobname+'/lastBuild/api/json/?pretty=true'
    def response = restClient.get( path : requrl)
    return response
}

def writeToPropertyFile(){
    def jsonResponseObject = getJobsInfo("sampleJobName",getRestClient())
    println "\n\n\n\n\n Json String :----   "+ jsonResponseObject.toString()

    JSONParser jsonParser = new JSONParser();
    JSONObject jsonObject = (JSONObject) jsonParser.parse(jsonResponseObject.toString());

    JSONArray upstreamJobInfoArray = jsonObject.getJSONArray("causes");

    for (int i = 0; i < upstreamJobInfoArray.length(); i++) {
        JSONObject jobCauses = upstreamJobInfoArray.getJSONObject(i);
        String upstreamProjectName = jobCauses.getString("upstreamProject");
        println upstreamProjectName
    }
}

writeToPropertyFile()

Error :

 Json String :----   groovyx.net.http.HttpResponseDecorator@6b063470
Caught: Unexpected character (g) at position 0.
Unexpected character (g) at position 0.
        at org.json.simple.parser.Yylex.yylex(Yylex.java:610)
        at org.json.simple.parser.JSONParser.nextToken(JSONParser.java:269)
        at org.json.simple.parser.JSONParser.parse(JSONParser.java:118)
        at org.json.simple.parser.JSONParser.parse(JSONParser.java:81)
        at org.json.simple.parser.JSONParser.parse(JSONParser.java:75)
        at org.json.simple.parser.JSONParser$parse.call(Unknown Source)
        at getUpstreamJob.writeToPropertyFile(getUpstreamJob.groovy:39)
        at getUpstreamJob.run(getUpstreamJob.groovy:50)

EDIT 1 : START

JSON response that I am trying to parse :

{
    "_class": "hudson.model.FreeStyleBuild",
    "actions": [
        {
            "_class": "hudson.model.CauseAction",
            "causes": [
                {
                    "_class": "hudson.model.Cause$UpstreamCause",
                    "shortDescription": "Started by upstream project \"sampleJobName\" build number 712",
                    "upstreamBuild": 712,
                    "upstreamProject": "sampleJobName",
                    "upstreamUrl": "job/sampleJobName/"
                },
                {
                    "_class": "hudson.model.Cause$UserIdCause",
                    "shortDescription": "Started by user Malick, Asif",
                    "userId": "asifma00",
                    "userName": "Malick, Asif"
                },
                {
                    "_class": "com.sonyericsson.rebuild.RebuildCause",
                    "shortDescription": "Rebuilds build #300",
                    "upstreamBuild": 300,
                    "upstreamProject": "sampleJobName",
                    "upstreamUrl": "view/ABCProjectView/job/sampleJobName/"
                }
            ]
        },
        {
            "_class": "hudson.model.ParametersAction",
            "parameters": [
                {
                    "_class": "hudson.model.StringParameterValue",
                    "name": "SNAPSHOTNAME",
                    "value": "ABCDE_12121.2000-2121212121212"
                },
                {
                    "_class": "hudson.model.StringParameterValue",
                    "name": "BUILD_LABEL",
                    "value": "ABCDE_12121.2000"
                }
            ]
        },
        {},
        {},
        {},
        {},
        {
            "_class": "hudson.plugins.parameterizedtrigger.BuildInfoExporterAction"
        },
        {},
        {},
        {},
        {}
    ],
    "artifacts": [],
    "building": false,
    "description": null,
    "displayName": "#301",
    "duration": 1199238,
    "estimatedDuration": 1194905,
    "executor": null,
    "fullDisplayName": "sampleJobName #301",
    "id": "301",
    "keepLog": false,
    "number": 301,
    "queueId": 189076,
    "result": "SUCCESS",
    "timestamp": 1583500786857,
    "url": "http://somedomainname:8080/job/sampleJobName/301/",
    "builtOn": "Server12345",
    "changeSet": {
        "_class": "hudson.scm.EmptyChangeLogSet",
        "items": [],
        "kind": null
    },
    "culprits": []
}

EDIT 1 : END

I have tried looking at several Stack Overflow issues, but still haven't been able to resolve it.

Please guide.


Solution

  • It's because you're not getting the actual JSON string, you're getting the toString() output on a groovyx.net.http.HttpResponseDecorator class.

    You can see it printing it out here (it's easy to miss though... I missed it the first look 🙂):

     Json String :----   groovyx.net.http.HttpResponseDecorator@6b063470
    

    I think you need to call jsonResponseObject.data to get the parsed data, and it might even return you a Map parsed form the JSON (so you can get rid of all your JSONObject code). Test it by changing to:

        def data = jsonResponseObject.data
        println "\n\n\n\n\n Json ${data.getClass().name} :----  $data" jsonResponseObject.toString()
    

    If it is a java.util.Map, you can simplify your second part from:

        JSONParser jsonParser = new JSONParser();
        JSONObject jsonObject = (JSONObject) jsonParser.parse(jsonResponseObject.toString());
    
        JSONArray upstreamJobInfoArray = jsonObject.getJSONArray("causes");
    
        for (int i = 0; i < upstreamJobInfoArray.length(); i++) {
            JSONObject jobCauses = upstreamJobInfoArray.getJSONObject(i);
            String upstreamProjectName = jobCauses.getString("upstreamProject");
            println upstreamProjectName
        }
    

    To (using data from above):

        data.actions.causes.upstreamProject.flatten().each { println it }