Core Java

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.

jdk9-repl

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

  1. Download the latest build, 61 at the time of this writing.
  2. Setup JAVA_HOME as:
    export JAVA_HOME=`/usr/libexec/java_home -v1.9`

    More details on setting JAVA_HOME on OSX are here.

  3. 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.

  1. 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
    
  2. 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
    
  3. Edit langtools/repl/scripts/compile.shscript 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 adding JLINE2LIB to the location of your previously compiled jline2 workspace. javac is picked from JAVA_HOME that is referring to JDK 9.

  4. 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

  1. 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 adding JLINE2LIB.

  2. 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: keepcalm-repl

  • 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.

Arun Gupta

Arun is a technology enthusiast, avid runner, author of a best-selling book, globe trotter, a community guy, Java Champion, JavaOne Rockstar, JUG Leader, Minecraft Modder, Devoxx4Kids-er, and a Red Hatter.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button