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:1
export JAVA_HOME=`/usr/libexec/java_home -v1.
9
`
More details on setting JAVA_HOME on OSX are here.
- Verify the version:1234
~> 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:
1 2 3 4 5 6 7 | 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:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 | 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:12345678
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:01020304050607080910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
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:1234#!/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:12repl> 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:123#!/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:123
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:
1 2 | -> 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:
01 02 03 04 05 06 07 08 09 10 11 | -> /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:
1 | -> /save test |
Note this is not a Java file. Saved snippet is exactly what was entered:
1 2 | repl> more test System.out.println( "Hello World" ); |
And the tool can be exited as:
1 2 | -> /exit | Goodbye |
Or you can just hit Ctrl+C.
Complete list of commands can be easily seen:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | -> /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. |