In this article I will demonstrate how we can work with JSON based data – for analysis, exploration, cleansing and processing – in JShell, much like we do in Python. I work with a JSON document with entries for all sessions at the Oracle OpenWorld 2017 conference (https://raw.githubusercontent.com/lucasjellema/scrape-oow17/master/oow2017-sessions-catalog.json)
The Java 9 SE specification for the JDK does not contain the JSON-P API and libraries for processing JSON. In order to work with JSON-P in JShell, we need to add the libraries – that we first need to find and download.
I have used a somewhat roundabout way to get hold of the required jar-files (but it works in a pretty straightforward manner):
1. Create a pom.xml file with dependencies on JSON-P
2. Then run
mvn install dependency:copy-dependencies
as described in this article: https://technology.amis.nl/2017/02/09/download-all-directly-and-indirectly-required-jar-files-using-maven-install-dependencycopy-dependencies/
this will download the relevant JAR files to subdirectory target/dependencies
3. Copy JAR files to a directory – that can be accessed from within the Docker container that runs JShell – for me that is the local lib directory that is mapped by Vagrant and Docker to /var/www/lib inside the Docker container that runs JShell.
4. In the container that runs JShell:
Start JShell with this statement that makes the new httpclient module available, for when the JSON document is retrieved from an HTTP URL resource:
jshell –add-modules jdk.incubator.httpclient
5. Update classpath from within jshell
To process JSON in JShell – using JSON-P – we need set the classpath to include the two jar files that were downloaded using Maven.
/env –class-path /var/www/lib/javax.json-1.1.jar:/var/www/lib/javax.json-api-1.1.jar
Then the classes in JSON-P are imported
import javax.json.*;
if we need to retrieve JSON data from a URL resource, we should also
import jdk.incubator.http.*;
6. I have made the JSON document available on the file system.
It can be accessed as follows:
InputStream input = new FileInputStream(“/var/www/oow2017-sessions-catalog.json”);
7. Parse data from file into JSON Document, get the root object and retrieve the array of sessions:
JsonReader jsonReader = Json.createReader(input)
JsonObject rootJSON = jsonReader.readObject();
JsonArray sessions = rootJSON.getJsonArray(“sessions”);
8. Filter sessions with the term SQL in the title and print their title to the System output – using Streams:
sessions.stream().map( p -> (JsonObject)p).filter(s -> s.getString(“title”).contains(“SQL”)) .forEach( s -> {System.out.println(s.getString(“title”));})
One other example: show a list of all presentations for which a slidedeck has been made available for download along with the download URL:
sessions.stream()
.map( p -> (JsonObject)p)
.filter(s -> s.containsKey(“files”) && !s.isNull(“files”) && !(s.getJsonArray(“files”).isEmpty()))
.forEach( s -> {System.out.println(s.getString(“title”)+” url:”+s.getJsonArray(“files”).getJsonObject(0).getString(“url”));})
Bonus: Do HTTP Request
As an aside some steps in jshell to execute an HTTP request:
jshell> HttpClient client = HttpClient.newHttpClient();
client ==> jdk.incubator.http.HttpClientImpl@4d339552
jshell> HttpRequest request = HttpRequest.newBuilder(URI.create(“http://www.google.com”)).GET().build();
request ==> http://www.google.com GET
jshell> HttpResponse response = client.send(request, HttpResponse.BodyHandler.asString())
response ==> jdk.incubator.http.HttpResponseImpl@147ed70f
jshell> System.out.println(response.body())
<HTML><HEAD><meta http-equiv=”content-type” content=”text/html;charset=utf-8″>
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF=”http://www.google.nl/?gfe_rd=cr&dcr=0&ei=S2XeWcbPFpah4gTH6Lb4Ag”>here</A>.
</BODY></HTML>
You can use TryArtifact to get the jars. https://github.com/bhagatsingh/try-artifact
TryArtifact is a tool for testing a maven artifacts in the JShell.
The below worked for me.
/resolve javax.json:javax.json-api:pom:1.1
/resolve javax.json:javax.json-api:jar:1.1
/resolve org.glassfish:javax.json:pom:1.1
/resolve org.glassfish:javax.json:jar:1.1