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