Terminal Duke

How can you start using one of the coolest features of Java 9 starting today?

Last weekend I finally got around to getting my hands dirty with an early access version of Java 9. The first stop was JShell, which also goes by the name of Project Kulla; the reason that got me to gather up the courage to try the early access Java version in the first place. That’s right. The official Java 9 release date is currently set to September 2016, but the early access version already has a fully functional version of JShell. It’s still under development and has a few quirks in it, but that never stopped us before.

Fun fact #1: Project Kulla is the internal name for the team developing JShell. Kulla is the name of a builder god from the Mesopotamian mythology, who was banished after the construction work was completed. Hinting at Kulla’s use case as a learning tool?

So what is this JShell thing?

JShell / Project Kulla is the first official Java REPL (Read-Eval-Print-Loop), a command line tool that lets you run Java statements on their own without having to wrap them in classes or methods. Similar in a way to Python’s interpreter, or to other JVM languages that natively support REPL like Scala and Groovy. Among the upcoming features of Java 9, it’s definitely one of the more interesting ones. To check out more exciting features (apart from Project Jigsaw!) that are coming to the JDK near you, you can read a previous post of ours around the top 5 features in Java 9 that will change how you code. Up until now, if you wanted to REPL in Java you could have used alternatives like repl.it which has multi langauge support or the unofficial Java REPL project. With Java 9 though, REPL is bundled right into the JDK together with the langtools package. Fun fact #2: Another OpenJDK project with a mythological name is project Valhalla; aiming beyond Java 9, and working on features like value types and reified generics. Definitely badass. But enough with that, let’s fire it up and see what it can do. In the following short terminal recoding we’re going through a quick test run with JShell v0.61 (There’s a known issue with OSX 10.10.3 where the prompt mixes with some of the output so please don’t mind that, it’ll probably be fixed soon):

Firing up and playing around with JShell

Reviewing what we just saw: Some of the most interesting features of JShell

Find the Crap in Your Java App

Show me how >>

Fred

** [8/7/2015] Update: Edited with notes from Brian Goetz, Java language architect at Oracle

1. Semicolon is optional on bare statements

Hello JShell! With the quick and flexible nature of the REPL, we can relax a bit and forget about adding semicolons at the end of our statements:

JShell - No semicolon
Nope, no semicolon here

This was actually a popular response on a survey we ran around future Java features. Of course semicolons are here to stay, either as terminators or separators. The REPL allows entering bare expressions and statements one at a time so semicolons become optional for the terminator use case on Jshell.

2. REPL networking

With JShell we’re not confined to our machine and have networking access, this opens up some interesting opportunities. For instance, think about using it as a terminal to communicate with your server, connecting to it remotely and controlling some parameters from the outside. Another option would be querying your database, and the possibilities here are really endless.

JShell - Networking

Simple example showing getting an HTTP header with JShell

3. Help! Saving and loading workspaces

Apart from running and evaluating Java statements, JShell supports a range of commands to help get you around and navigate through the REPL environment. You can save and load workspaces (which kind of makes Java resemble a scripting language) and then get back on the command prompt after all the code was executed (this is actually where you can see the OS X bug I mentioned in the terminal recording).

Other useful commands are listing all the current available variables and methods, viewing all your command history, and listing the all the code you wrote so far (which sometimes still behaves a bit weird).

Here’s the full list of the currently available commands:

JShell - Help

JShell /help

4. No checked exceptions

If you’ve been worried about checked exceptions ruining your REPL experience – Fear no more, JShell wraps those for you in the background. In the following example, what would have forced us to catch an IOException, goes away unnoticed. Here we’re reading and printing out a file without handling IOExceptions:

JShell - Checked Exceptions

One case we did see a checked exception pop-up is when we tried to run a thread and used Thread.sleep() in it. Since it’s a whole method and not a single bare statement, it has to be fully valid Java:

JShell - Interrupted

Moving on to a few more features that didn’t make it to the terminal recording:

5. Java expressions

Another thing about the JShell terminal is that it can also evaluate Java expressions on their on. String concatenation, method calls, arithmetic, whatever. Basically anything that you could have wrapped inside a System.out.println(/* expression here */). As you may have already noticed with other evaluations, it immediately places the result in a variable of its own and prints it out:

JShell - Arithmetic

6. Forward reference

JShell has pretty nifty support for forward references, so you can define functions that reference other methods or variables that will only be defined later down the road. Here’s an example from the REPL tutorial by AdoptOpenJDK:

JShell - Forward Refernece

7. JShell API

Apart from its use as a standalone JDK tool, JShell will also provide an API which opens up all its functionality to external use. This means external tools could hook up and use JShell’s capabilities, and suddenly some interesting possibilities open up like including it as part of IDEs like Eclipse, IntelliJ or Netbeans. More creative use cases for the API could include tools using it to extend static analysis capabilities, automated testing or maybe even hooking up to live JVMs.

8. Changing definitions on the go

You can re-declare variables, methods and classes without worrying about the original declarations. Once you do so, you’ll be prompted with a message letting you know what happened, but other than that – it’s business as usual.

Bonus: All you need is love

If you dig up your way into the /repl/samples folder, you’ll find this cute sample that will draw you 3 little hearts using Swing:

JShell - Hearts

Java <3 REPL

How to get started on your own?

To get started, check out the instructions on the Adopt OpenJDK: Getting Started Kit from the London Java Community (LJC). Here’s a quick summary of the steps to help get you off the ground, especially if you’ve never played around with early access JDK versions before:

1. Install the Java 9 early access JDK

2. Build the kulla-dev branch:

hg clone http://hg.openjdk.java.net/kulla/dev kulla-dev
cd kulla-dev
bash configure –with-boot-jdk=/path/to/jdk1.8.0
make clean images
make install <=== optional

3. Build the REPL:

cd langtools/repl
bash ./scripts/compile.sh

4. And… now you’re ready to run.:

bash ./scripts/run.sh

Important note for OS X users: Before running compile.sh & run.sh edit the scripts and change #!/usr/bin/sh to #!/bin/sh.

If you have any questions about the process, please post them in the comments section below and we’ll do our best to help.

Conclusion

It’s exciting to see how Project Kulla is getting closer to maturity where it will have a feature-complete status. JShell has a wide range of use cases but first and foremost, it will help new and existing developers quickly test their newly learned skills. Be it basic Java or some new library you’re just starting to wrap your head around. Moreover, JShell brings Java on par with languages that have these capabilities for a while now, and perhaps even pushes the envelope further, with an official API and a smooth command line experience.

fredjava

15 tools to use when deploying new code to production – View tool list

Java 8

Java 8 exceptions have never been so beautiful – Try Takipi for Java 8

Yoda

Join over 30,254 Java developers

Get new posts about Java, Scala and everything in between

Watch a live demo
Yoda
Some kind of monster @ OverOps, GDG Haifa lead.
  • Mario Cormier

    Calling Thread.run() does not actually start a new thread, which would explain why the REPL suspended (assuming you did as in the video).

    • http://www.takipi.com/ Alex Zhitnitsky

      Right, thanks for the comment Mario! I’ve edited the text.

  • David Conrad

    lines.forEach(s -> System.out.println(s)) can be written more succinctly as lines.forEach(System.out::println)

    • http://www.takipi.com/ Alex Zhitnitsky

      Right, thanks David! Sweet syntactic sugar 🙂

  • http://www.codelytics.io Adrian Bartlett

    This looks great. The amount of times I have written a Test.java, to prototype some ideas, and then copied the code into my project, is countless. This interactive env is a much better way! Thanks for sharing.

    • http://www.takipi.com/ Alex Zhitnitsky

      Hi Adrian, thanks for the comment! Sure, no problem, glad that you’ve found the post useful. I think the great thing is that you can start using it today, even though the official release is over a year from now.

  • Carlos

    Hi guys, I have been trying like crazy to install this, but no luck so far.

    Mac 10.10.4
    Xcode 6.4

    I tried this
    bash ./configure –with-boot-jdk=[my_path]

    output:
    configure: Found potential make at /usr/bin/make, however, this is not GNU Make. Ignoring.
    configure: error: Cannot find GNU make 3.81 or newer! Please put it in the path, or add e.g. MAKE=/opt/gmake3.81/make as argument to configure.
    …./kulla-dev/common/autoconf/generated-configure.sh: line 82: 5: Bad file descriptor

    But If I do make -version I get: GNU Make 3.81, so it is the right version.

    I have tried downloading “gnu make” from the web and set it using MAKE=, but I get the same error message.

    What am I doing wrong?

    • http://www.takipi.com/ Alex Zhitnitsky

      Hey Carlos,

      Sorry for the late reply, did you manage to solve this? I think you might need to change #!/usr/bin/sh to #!/bin/sh in kulla-dev/configure as well. Let me know if this solves it and I’ll it to the instructions we have here.

      • Carlos

        no luck, configure file starts with #!/bin/bash, and no mention of bin/sh in this 36 lines file. common/autoconf/configure doesn’t have bin/sh

        common/autoconf/generated-configure.sh has this:
        SHELL=${CONFIG_SHELL-/bin/sh}
        export SHELL

        This is the exact command that fails
        bash ./configure –with-boot-jdk=/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java

  • Michael Smith

    I am so excited about Java 9 now. JShell adds a level of dynamic to the game that makes my mind go crazy with possibilities. It almost makes me want to write an insane mmud game, but I am way past those days. But imagine if the players could design the game!

    And if that idea takes off come get me I wanna code on it too 🙂

    • http://www.takipi.com/ Alex Zhitnitsky

      Hi Michael, heh, sounds like a cool side project actually! Well, drop us an email then (hello@takipi.com), and we might push this forward. We like these kind of side projects here at Takipi. Here’s one of the recent ones: http://www.javadeathmatch.com/

  • Jurrian Fahner

    If you want to try it out, you can use a docker image.
    You can find it on https://hub.docker.com/r/ensignprojects/javarepl/

  • Marcin Flis

    bash configure –with-boot-jdk=/path/to/jdk1.8.0? JDK1.8.0?

  • HaakonKL

    Jesus mate! Bash 3.2? That’s from 2006 or so.
    At least upgrade to 4.3, you’re missing out on features.

    Useful ones too, like mapfile and coproc.

  • midhun

    setting a float variable gives error
    float x =2; workes fine
    float b = 3.4 //possible lossy conversion from double to float error