JRJC JSONObject["type"] not found

Hi, I am trying to setup the Hygieia dashboard, and while trying to set up their jira-collector (which has jira-rest-java-client-core v3.0.0 as a dependency) I came across the following error:

2017-11-08 10:34:59,998 INFO  c.c.d.collector.CollectorTask - Running Collector: Jira
2017-11-08 10:35:00,007 INFO  c.c.d.collector.CollectorTask - -----------------------------------
2017-11-08 10:35:00,007 INFO  c.c.d.collector.CollectorTask - https://my.jira.com/
2017-11-08 10:35:00,007 INFO  c.c.d.collector.CollectorTask - -----------------------------------
2017-11-08 10:35:00,009 DEBUG c.c.d.client.team.TeamDataClientImpl - Constructing data collection for the feature widget, team-level data...
2017-11-08 10:35:00,024 INFO  c.c.d.collector.CollectorTask - Team Data               0        0s
2017-11-08 10:35:00,025 DEBUG c.c.d.c.p.ProjectDataClientImpl - Constructing data collection for the feature widget, project-level data...
2017-11-08 10:35:02,673 DEBUG c.c.d.c.p.ProjectDataClientImpl - Size of paged Jira response: 947
2017-11-08 10:35:04,434 INFO  c.c.d.collector.CollectorTask - Project Data          947        4s
2017-11-08 10:35:04,437 DEBUG c.c.d.c.story.StoryDataClientImpl - Constructing data collection for the feature widget, story-level data...
2017-11-08 10:35:05,430 DEBUG c.c.d.c.story.StoryDataClientImpl - Obtaining story information starting at index 0...
2017-11-08 10:35:13,707 ERROR c.c.d.client.DefaultJiraClient - No result was available from Jira unexpectedly - defaulting to blank response. The reason for this fault is the following:RestClientException{statusCode=Optional.absent(), errorCollections=[]}
2017-11-08 10:35:13,723 DEBUG c.c.d.client.DefaultJiraClient - Exception
com.atlassian.jira.rest.client.api.RestClientException: org.codehaus.jettison.json.JSONException: JSONObject["type"] not found.
	at com.atlassian.jira.rest.client.internal.async.DelegatingPromise.claim(DelegatingPromise.java:47) ~[jira-rest-java-client-core-3.0.0.jar!/:na]
	at com.capitalone.dashboard.client.DefaultJiraClient.getIssues(DefaultJiraClient.java:101) ~[jira-feature-collector.jar!/:2.0.5-SNAPSHOT]
	at com.capitalone.dashboard.client.story.StoryDataClientImpl.updateStoryInformation(StoryDataClientImpl.java:162) [jira-feature-collector.jar!/:2.0.5-SNAPSHOT]
	at com.capitalone.dashboard.collector.FeatureCollectorTask.collect(FeatureCollectorTask.java:119) [jira-feature-collector.jar!/:2.0.5-SNAPSHOT]
	at com.capitalone.dashboard.collector.FeatureCollectorTask.collect(FeatureCollectorTask.java:28) [jira-feature-collector.jar!/:2.0.5-SNAPSHOT]
	at com.capitalone.dashboard.collector.CollectorTask.run(CollectorTask.java:63) [core-2.0.5-SNAPSHOT.jar!/:2.0.5-SNAPSHOT]
	at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) [spring-context-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
	at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81) [spring-context-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_131]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_131]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_131]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [na:1.8.0_131]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_131]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_131]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131]
Caused by: com.atlassian.jira.rest.client.api.RestClientException: org.codehaus.jettison.json.JSONException: JSONObject["type"] not found.
	at com.atlassian.jira.rest.client.internal.async.AbstractAsynchronousRestClient$3.apply(AbstractAsynchronousRestClient.java:188) ~[jira-rest-java-client-core-3.0.0.jar!/:na]
	at com.atlassian.jira.rest.client.internal.async.AbstractAsynchronousRestClient$3.apply(AbstractAsynchronousRestClient.java:182) ~[jira-rest-java-client-core-3.0.0.jar!/:na]
	at com.atlassian.httpclient.api.ResponsePromiseMapFunction.apply(ResponsePromiseMapFunction.java:62) ~[atlassian-httpclient-api-0.13.2.jar!/:na]
	at com.atlassian.httpclient.api.ResponsePromiseMapFunction.apply(ResponsePromiseMapFunction.java:12) ~[atlassian-httpclient-api-0.13.2.jar!/:na]
	at com.atlassian.util.concurrent.Promises$Of$3.apply(Promises.java:285) ~[atlassian-util-concurrent-2.4.0-M9.jar!/:na]
	at com.atlassian.util.concurrent.Promises$2.onSuccess(Promises.java:162) ~[atlassian-util-concurrent-2.4.0-M9.jar!/:na]
	at com.google.common.util.concurrent.Futures$4.run(Futures.java:1154) ~[guava-14.0.jar!/:na]
	at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:293) ~[guava-14.0.jar!/:na]
	at com.google.common.util.concurrent.ExecutionList$RunnableExecutorPair.execute(ExecutionList.java:150) ~[guava-14.0.jar!/:na]
	at com.google.common.util.concurrent.ExecutionList.execute(ExecutionList.java:135) ~[guava-14.0.jar!/:na]
	at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:185) ~[guava-14.0.jar!/:na]
	at com.google.common.util.concurrent.SettableFuture.set(SettableFuture.java:53) ~[guava-14.0.jar!/:na]
	at com.atlassian.util.concurrent.Promises$Of$3.apply(Promises.java:285) ~[atlassian-util-concurrent-2.4.0-M9.jar!/:na]
	at com.atlassian.util.concurrent.Promises$2.onSuccess(Promises.java:162) ~[atlassian-util-concurrent-2.4.0-M9.jar!/:na]
	at com.google.common.util.concurrent.Futures$4.run(Futures.java:1154) ~[guava-14.0.jar!/:na]
	at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:293) ~[guava-14.0.jar!/:na]
	at com.google.common.util.concurrent.ExecutionList$RunnableExecutorPair.execute(ExecutionList.java:150) ~[guava-14.0.jar!/:na]
	at com.google.common.util.concurrent.ExecutionList.execute(ExecutionList.java:135) ~[guava-14.0.jar!/:na]
	at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:185) ~[guava-14.0.jar!/:na]
	at com.google.common.util.concurrent.SettableFuture.set(SettableFuture.java:53) ~[guava-14.0.jar!/:na]
	at com.atlassian.httpclient.apache.httpcomponents.SettableFuturePromiseHttpPromiseAsyncClient$1$1.run(SettableFuturePromiseHttpPromiseAsyncClient.java:46) ~[atlassian-httpclient-apache-httpcomponents-0.13.2.jar!/:na]
	at com.atlassian.httpclient.apache.httpcomponents.SettableFuturePromiseHttpPromiseAsyncClient$ThreadLocalDelegateRunnable$1.run(SettableFuturePromiseHttpPromiseAsyncClient.java:197) ~[atlassian-httpclient-apache-httpcomponents-0.13.2.jar!/:na]
	at com.atlassian.httpclient.apache.httpcomponents.SettableFuturePromiseHttpPromiseAsyncClient.runInContext(SettableFuturePromiseHttpPromiseAsyncClient.java:90) ~[atlassian-httpclient-apache-httpcomponents-0.13.2.jar!/:na]
	at com.atlassian.httpclient.apache.httpcomponents.SettableFuturePromiseHttpPromiseAsyncClient$ThreadLocalDelegateRunnable.run(SettableFuturePromiseHttpPromiseAsyncClient.java:192) ~[atlassian-httpclient-apache-httpcomponents-0.13.2.jar!/:na]
	... 3 common frames omitted
Caused by: org.codehaus.jettison.json.JSONException: JSONObject["type"] not found.
	at org.codehaus.jettison.json.JSONObject.get(JSONObject.java:360) ~[jettison-1.1.jar!/:1.1]
	at org.codehaus.jettison.json.JSONObject.getString(JSONObject.java:487) ~[jettison-1.1.jar!/:1.1]
	at com.atlassian.jira.rest.client.internal.json.IssueJsonParser.parseSchema(IssueJsonParser.java:344) ~[jira-rest-java-client-core-3.0.0.jar!/:na]
	at com.atlassian.jira.rest.client.internal.json.IssueJsonParser.parseFields(IssueJsonParser.java:309) ~[jira-rest-java-client-core-3.0.0.jar!/:na]
	at com.atlassian.jira.rest.client.internal.json.IssueJsonParser.parse(IssueJsonParser.java:223) ~[jira-rest-java-client-core-3.0.0.jar!/:na]
	at com.atlassian.jira.rest.client.internal.json.IssueJsonParser.parse(IssueJsonParser.java:88) ~[jira-rest-java-client-core-3.0.0.jar!/:na]
	at com.atlassian.jira.rest.client.internal.json.GenericJsonArrayParser.parse(GenericJsonArrayParser.java:39) ~[jira-rest-java-client-core-3.0.0.jar!/:na]
	at com.atlassian.jira.rest.client.internal.json.SearchResultJsonParser.parse(SearchResultJsonParser.java:40) ~[jira-rest-java-client-core-3.0.0.jar!/:na]
	at com.atlassian.jira.rest.client.internal.json.SearchResultJsonParser.parse(SearchResultJsonParser.java:27) ~[jira-rest-java-client-core-3.0.0.jar!/:na]
	at com.atlassian.jira.rest.client.internal.async.AbstractAsynchronousRestClient$1.handle(AbstractAsynchronousRestClient.java:145) ~[jira-rest-java-client-core-3.0.0.jar!/:na]
	at com.atlassian.jira.rest.client.internal.async.AbstractAsynchronousRestClient$3.apply(AbstractAsynchronousRestClient.java:186) ~[jira-rest-java-client-core-3.0.0.jar!/:na]
	... 26 common frames omitted
2017-11-08 10:35:13,724 DEBUG c.c.d.c.story.StoryDataClientImpl - Story information query took 8293 ms
2017-11-08 10:35:13,724 INFO  c.c.d.c.story.StoryDataClientImpl - Loop i 0 pageSize 0
2017-11-08 10:35:13,724 INFO  c.c.d.collector.CollectorTask - Story Data              0        9s
2017-11-08 10:35:13,724 INFO  c.c.d.collector.CollectorTask - Finished                        13s

The exception appears to be thrown from:

com.atlassian.jira.rest.client.internal.json.IssueJsonParser.parseSchema(IssueJsonParser.java:344)

and the line looks like this:

(line 343) JSONObject fieldDefinition = json.getJSONObject(fieldId);
(line 344) res.put(fieldId, fieldDefinition.getString("type")); <<<res is a map which is returned by this method

The root json object which IssueJsonParser is trying to parse is:

{"custom":"com.onresolve.jira.groovy.groovyrunner:scripted-field","customId":xxxxx}

which does not contain the "type" property, thus causing the exception.

Since IssueJsonParser.parseSchema is a private method only used by IssueJsonParser.parseFields, and that only looks for types of "key": 

res.add(new IssueField(key, namesMap.get(key), typesMap.get("key"), value != JSONObject.NULL ? value : null));

I was wondering if IssueJsonParser.parseSchema should contain a check for the field "type" to avoid this exception from being thrown, i.e.:

if (fieldDefinition.has("type")) {
res.put(fieldId, fieldDefinition.getString("type"));
}

Or perhaps should the json object with the missing "type" field be required to contain a "type" field? I am not too familiar with Jira, jrjc, or 'com.onresolve.jira.groovy.groovyrunner:scripted-field', so if it should be required to contain a "type" field, is there a way of adding one?

Currently I am implementing the if-statement, but that requires me to maintain my on jrjc version which I only feel comfortable doing as a last resort. I am hoping to start a discussion as whether or not this is something worth adding to IssueJsonParser.java 

0 comments

Comment

Log in or Sign up to comment
Community showcase
Published Nov 27, 2018 in Portfolio for Jira

Introducing a new planning experience in Portfolio for Jira (Server/DC)

In the past, Portfolio for Jira required a high degree of detail–foresight that was unrealistic for many businesses to   have–in   order to produce a reliable long-term roadmap. We're tur...

2,524 views 15 21
Read article

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you