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 Join to comment
Community showcase
Sarah Schuster
Posted Jan 29, 2018 in Jira

What are common themes you've seen across successful & failed Jira Software implementations?

Hey everyone! My name is Sarah Schuster, and I'm a Customer Success Manager in Atlassian specializing in Jira Software Cloud. Over the next few weeks I will be posting discussion topics (8 total) to ...

2,897 views 12 18
Join discussion

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
Atlassian Team Tour

Join us on the Team Tour

We're bringing product updates and pro tips on teamwork to ten cities around the world.

Save your spot