Details
-
Bug
-
Status: Open
-
Major
-
Resolution: Unresolved
-
3.0.6
-
None
-
None
-
Groovy Version: 3.0.6 JVM: 11.0.9 Vendor: Amazon.com Inc. OS: Linux
Description
The following code:
import groovy.json.* import java.net.http.* import static java.net.http.HttpResponse.* def req = HttpRequest.newBuilder() .uri(URI.create('https://jsonplaceholder.typicode.com/todos/1')) .build() def parser = new JsonSlurper() // parser.parseText('{}') // <--- commenting in this line will make the code work def res = HttpClient.newHttpClient().sendAsync(req, BodyHandlers.ofString()) .thenApply(r -> r.body()) .thenApply(parser::parseText) .join() println "response: $res"
when run, will break with the following exception:
─➤ groovy queryjson.groovy Caught: java.util.concurrent.CompletionException: java.lang.RuntimeException: Unable to load FastStringService java.util.concurrent.CompletionException: java.lang.RuntimeException: Unable to load FastStringService Caused by: java.lang.RuntimeException: Unable to load FastStringService at org.apache.groovy.json.internal.FastStringUtils.getService(FastStringUtils.java:56) at org.apache.groovy.json.internal.FastStringUtils.toCharArray(FastStringUtils.java:66) at org.apache.groovy.json.internal.BaseJsonParser.parse(BaseJsonParser.java:113) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at com.sun.proxy.$Proxy17.apply(Unknown Source)
commenting in the indicated line will make the code work.
I assume this is caused by the fact that the `thenApply` block of code is run from a different (pooled) thread and from a different classloader context.
I get this, but in my mind having this simple example break is bad ergonomics and with the ubiquity of json APIs and the inclusion of a decent http client in java 11 I would expect this pattern to become quite common. I.e. wanting to create a no-deps groovy script / class which makes an http call and parses the returned json.