JDK 9 REPL: Getting Started
Conferences are a great place to meet Java luminaries. Devoxx France was one such opportunity to meet Java language architect, ex-colleague and an old friend – Brian Goetz (@briangoetz). We talked about JDK 9 and he was all raving about REPL. He mentioned that even though there are a lot of significant features, such as modularity and HTTP2 client, in Java SE 9, but this tool is going to be talked about the most often. The statement makes sense since it will really simplify exploration of Java APIs, prototyping, demos in conferences, and similar tasks a lot simpler. This blog is coming out of our discussion there and his strong vote on REPL!
Read-Evaluate-Print-Loop has been there in Lisp, Python, Ruby, Groovy, Clojure, and other languages for a while. Unix shell is a REPL which can read shell commands, evaluate them, print the output, and goes back in the loop to do the same thing.
You can read all about REPL in JDK 9 in JEP 222. Summary from the JEP is:
Provide an interactive tool which evaluates declarations, statements, and expressions of the Java Programming Language: that is, provide a Read-Evaluate-Print Loop (REPL) for the Java Programming Language. Also, provide an API on which the tool is built, enabling external tools to supply this functionality. JEP 222
The motivation is also clearly spelt out in the JEP:
Without the ceremony of class Foo { public static void main(String[] args) { … } }, learning and exploration is streamlined. JEP 222
JEP 222 targets to ship REPL with JDK 9 but openjdk.java.net/projects/jdk9 does not list it is as “targeted” or “proposed to target”. Seems like a documentation bug :)
As of JDK 9 build 61, REPL is not integrated, and needs to be built separately. Eventually, at some time before JDK 9 is released, this tool will be integrated in the build.
Lets see what does it require to have it running on OSX. This blog followed Java 9 REPL – Getting Started Guide to build and run REPL. In addition, it provides complete log output from the commands which might be helpful for some.
Lets get started!
Install JDK 9
- Download the latest build, 61 at the time of this writing.
- Setup JAVA_HOME as:
export JAVA_HOME=`/usr/libexec/java_home -v1.9`
More details on setting JAVA_HOME on OSX are here.
- Verify the version:
~> java -version java version "1.9.0-ea" Java(TM) SE Runtime Environment (build 1.9.0-ea-b61) Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b61, mixed mode)
Checkout and Install jline2
jline2 is a Java library for handling console input. Check it out:
workspaces> git clone git://github.com/jline/jline2.git Cloning into 'jline2'... remote: Counting objects: 6419, done. remote: Total 6419 (delta 0), reused 0 (delta 0), pack-reused 6419 Receiving objects: 100% (6419/6419), 3.23 MiB | 80.00 KiB/s, done. Resolving deltas: 100% (2945/2945), done. Checking connectivity... done.
And then build it:
jline2> mvn install [INFO] Scanning for projects... Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/scm/maven-scm-provider-gitexe/1.8.1/maven-scm-provider-gitexe-1.8.1.pom Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/scm/maven-scm-provider-gitexe/1.8.1/maven-scm-provider-gitexe-1.8.1.pom (3 KB at 0.3 KB/sec) . . . [INFO] Installing /Users/arungupta/workspaces/jline2/target/jline-2.13-SNAPSHOT-sources.jar to /Users/arungupta/.m2/repository/jline/jline/2.13-SNAPSHOT/jline-2.13-SNAPSHOT-sources.jar [INFO] Installing /Users/arungupta/workspaces/jline2/target/jline-2.13-SNAPSHOT-tests.jar to /Users/arungupta/.m2/repository/jline/jline/2.13-SNAPSHOT/jline-2.13-SNAPSHOT-tests.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 09:52 min [INFO] Finished at: 2015-05-06T19:23:14-07:00 [INFO] Final Memory: 25M/146M [INFO] ------------------------------------------------------------------------
Clone and Build JDK 9 REPL
OpenJDK codename for the project is Kulla which means “The God of Builders”. Planned name for the tool is jshell
.
- Check out the workspace:
workspaces> hg clone http://hg.openjdk.java.net/kulla/dev kulla requesting all changes adding changesets adding manifests adding file changes added 1453 changesets with 2226 changes to 172 files updating to branch default 109 files updated, 0 files merged, 0 files removed, 0 files unresolved
- Get the sources:
workspaces> cd kulla kulla> chmod +x ./get_source.sh kulla> ./get_source.sh # Repositories: corba jaxp jaxws langtools jdk hotspot nashorn corba: hg clone http://hg.openjdk.java.net/kulla/dev/corba corba jaxp: hg clone http://hg.openjdk.java.net/kulla/dev/jaxp jaxp corba: requesting all changes jaxp: requesting all changes corba: adding changesets jaxp: adding changesets corba: adding manifests jaxp: adding manifests corba: adding file changes jaxp: adding file changes corba: added 669 changesets with 4913 changes to 2576 files corba: updating to branch default corba: 1184 files updated, 0 files merged, 0 files removed, 0 files unresolved jaxws: hg clone http://hg.openjdk.java.net/kulla/dev/jaxws jaxws jaxws: requesting all changes jaxws: adding changesets jaxws: adding manifests jaxws: adding file changes jaxp: added 728 changesets with 10192 changes to 7393 files jaxp: updating to branch default jaxp: 3044 files updated, 0 files merged, 0 files removed, 0 files unresolved langtools: hg clone http://hg.openjdk.java.net/kulla/dev/langtools langtools langtools: requesting all changes langtools: adding changesets langtools: adding manifests jaxws: added 589 changesets with 20521 changes to 10746 files jaxws: updating to branch default jaxws: 3750 files updated, 0 files merged, 0 files removed, 0 files unresolved jdk: hg clone http://hg.openjdk.java.net/kulla/dev/jdk jdk langtools: adding file changes jdk: requesting all changes jdk: adding changesets jdk: adding manifests langtools: added 3173 changesets with 28112 changes to 9103 files langtools: updating to branch default langtools: 7100 files updated, 0 files merged, 0 files removed, 0 files unresolved hotspot: hg clone http://hg.openjdk.java.net/kulla/dev/hotspot hotspot hotspot: requesting all changes hotspot: adding changesets hotspot: adding manifests hotspot: adding file changes hotspot: added 8073 changesets with 45889 changes to 6290 files hotspot: updating to branch default hotspot: 5030 files updated, 0 files merged, 0 files removed, 0 files unresolved nashorn: hg clone http://hg.openjdk.java.net/kulla/dev/nashorn nashorn nashorn: requesting all changes nashorn: adding changesets nashorn: adding manifests jdk: adding file changes nashorn: adding file changes nashorn: added 1252 changesets with 11596 changes to 3595 files nashorn: updating to branch default nashorn: 2867 files updated, 0 files merged, 0 files removed, 0 files unresolved jdk: added 11805 changesets with 116593 changes to 42135 files jdk: updating to branch default jdk: 23192 files updated, 0 files merged, 0 files removed, 0 files unresolved # Repositories: . corba jaxp jaxws langtools jdk hotspot nashorn .: cd . && hg pull -u corba: cd corba && hg pull -u jaxp: cd jaxp && hg pull -u jaxws: cd jaxws && hg pull -u langtools: cd langtools && hg pull -u jdk: cd jdk && hg pull -u hotspot: cd hotspot && hg pull -u nashorn: cd nashorn && hg pull -u jaxws: pulling from http://hg.openjdk.java.net/kulla/dev/jaxws corba: pulling from http://hg.openjdk.java.net/kulla/dev/corba langtools: pulling from http://hg.openjdk.java.net/kulla/dev/langtools hotspot: pulling from http://hg.openjdk.java.net/kulla/dev/hotspot jdk: pulling from http://hg.openjdk.java.net/kulla/dev/jdk .: pulling from http://hg.openjdk.java.net/kulla/dev jaxp: pulling from http://hg.openjdk.java.net/kulla/dev/jaxp nashorn: pulling from http://hg.openjdk.java.net/kulla/dev/nashorn nashorn: searching for changes nashorn: no changes found jaxws: searching for changes jaxws: no changes found jaxp: searching for changes jaxp: no changes found corba: searching for changes corba: no changes found jdk: searching for changes hotspot: searching for changes hotspot: no changes found jdk: no changes found .: searching for changes .: no changes found langtools: searching for changes langtools: no changes found
- Edit
langtools/repl/scripts/compile.sh
script such that it looks like:#!/bin/sh JLINE2LIB=/Users/arungupta/workspaces/jline2/target/jline-2.13-SNAPSHOT.jar mkdir -p build javac -Xlint:unchecked -Xdiags:verbose -cp ${JLINE2LIB} -d build ../src/jdk.jshell/share/classes/*/*/*.java ../src/jdk.jshell/share/classes/*/*/*/*/*.java ../src/jdk.jshell/share/classes/*/*/*/*/*/*.java
Notice, the only edits are
#!/bin/sh
for OSX and addingJLINE2LIB
to the location of your previously compiledjline2
workspace.javac
is picked from JAVA_HOME that is referring to JDK 9. - Compile the REPL tool by invoking the script from
langtools/repl
directory:repl> chmod +x ./scripts/compile.sh repl> ./scripts/compile.sh
Run JDK 9 REPL
- Edit
langtools/repl/scripts/run.sh
script such that it looks like:#!/bin/sh JLINE2LIB=/Users/arungupta/workspaces/jline2/target/jline-2.13-SNAPSHOT.jar java -ea -esa -cp build:${JLINE2LIB} jdk.internal.jshell.tool.JShellTool "$@"
Notice, the only edits are
!/bin/sh
for OSX and addingJLINE2LIB
. - Run REPL as:
repl> ./scripts/run.sh | Welcome to JShell -- Version 0.428 | Type /help for help
JDK 9 REPL Hello World
Unlike the introduction of bouncing ball or dancing Duke that was used to introduce Java, we’ll just use the conventional Hello World for REPL
Run “Hello World” as:
-> System.out.println("Hello World"); Hello World
Voila!
No public static void main
, no class creation, no ceremony, just clean and simple Java code. The entered text is called as “snippet”.
The complete Java code can be seen using /list all
and looks like:
-> /list all 1 : import java.util.*; 2 : import java.io.*; 3 : import java.math.*; 4 : import java.net.*; 5 : import java.util.concurrent.*; 6 : import java.util.prefs.*; 7 : import java.util.regex.*; 8 : void printf(String format, Object... args) { System.out.printf(format, args); } 9 : System.out.println("Hello World");
This snippet can be saved to a file as:
-> /save test
Note this is not a Java file. Saved snippet is exactly what was entered:
repl> more test System.out.println("Hello World");
And the tool can be exited as:
-> /exit | Goodbye
Or you can just hit Ctrl+C.
Complete list of commands can be easily seen:
-> /help Type a Java language expression, statement, or declaration. Or type one of the following commands: /l or /list [all] -- list the source you have typed /seteditor <executable> -- set the external editor command to use /e or /edit <name or id> -- edit a source entry referenced by name or id /- or /drop <name or id> -- delete a source entry referenced by name or id /s or /save [all|history] <file> -- save the source you have typed /o or /open <file> -- open a file as source input /v or /vars -- list the declared variables and their values /m or /methods -- list the declared methods and their signatures /c or /classes -- list the declared classes /x or /exit -- exit the REPL /r or /reset -- reset everything in the REPL /f or /feedback <level> -- feedback information: off, concise, normal, verbose, default, or ? /p or /prompt -- toggle display of a prompt /cp or /classpath <path> -- add a path to the classpath /h or /history -- history of what you have typed /setstart <file> -- read file and set as the new start-up definitions /savestart <file> -- save the default start-up definitions to the file /? or /help -- this help message Supported shortcuts include: <tab> -- show possible completions for the current text Shift-<tab> -- for current method or constructor invocation, show a synopsis of the method/constructor
JDK 9 REPL Next Steps and Feedback
Follow the REPL Tutorial to learn more about the tool’s capability. Here is a quick overview:
- Accepts Java statements, variable, method, and class definitions, imports, and expressions
- Commands for settings and to display information, such as
/list
to display the list of snippets,/vars
to display the list of variables,/save
to save your snippets,/open
to read them back in. - History of snippets is available, snippets can be edited by number, and much more
Here is an RFE that would be useful:
- Export a snippet as full blown Java class
A subsequent blog will showcase how this could be used for playing with a Java EE application. How would you use REPL?
Discuss the project/issues on kulla-dev.
Enjoy!
Reference: | JDK 9 REPL: Getting Started from our JCG partner Arun Gupta at the Miles to go 2.0 … blog. |