using Java 9’s jshell for experimenting

In Java 8, Oracle introduced the new Nashorn engine and is encouraging the use of jjs. It’s a RPEL (read print evaluate loop) for JavaScript. Since JavaScript can call Java, this allows experimenting with Java APIs like you do in other languages like Python and Ruby. I actively disliked it and even wrote a blog post about what turned me off. Java 9 introduced JShell for this same purpose except it works with Java rather than a level of indirection through JavaScript.

In this blog post, I repeat the same experiment with JShell (using the Java 9 early access download) to see if it is any better. Again I used the exercises from Cay Horstmann’s book, Java SE 8 for the Really Impatient so it would be an equivalent experiment.

Exercise 1 – Play … to experiment with an API you want to explore; did you find it easier than writing test programs in Java?

With Nashorn/jjs in Java 8, I had three issues. Let’s see how jjs compares:

Nashorn/jjs JShell
Strike 1 – needing to type in the package name of classes. Better. At least common packages are included now like java.util. For others, like LocalDate, you still need to type the package name. Which often means looking up the package name. I rely heavily on “organize imports” in my IDE for package names.
Strike 2 – no tab complete Success! JShell has tab complete for packages, classes and methods
Strike 3 – no up arrow support Success! JShell lets you you use the up/down arrows to go through your command history.

Having solved these three issues, the question is a better one. If I’m on a UNIX system or don’t have my IDE open, JShell would definitely be faster. If I already have the IDE open, I have a “PlayTest” program with a main method already available to me so it is a tie. But that’s just my workflow. JShell looks good.

Note: I learned on Twitter that:

wickund: @jeanneboyarsky jjs in JDK9 uses the same API as jshell (JDK9), so there is code completion and up arrow.

Which means my issues with Nashorn are gone in Java 9. Thanks Jim Laskey

Exercise 2 – Using …. the stream library iteratively work out a solution to the problem to print a filtered list of unique long words in sorted order and see how it compares to your usual workflow.

Here was my workflow with JShell:

  1. Create the test file in a text editor (vi)
  2. Run ./jshell
  3. Create a path object
    Attempt # Code Error Comments
    1 jshell> Path paths = Path.get(“path/words.txt”) Success! This package is included in the list of known ones so I didn’t even have to look anything up.
  4. Read the file
    Attempt # Code Error Comments
    1 jshell> List<String> list = Files.readAllLines(path) Success
  5. Filter the long words
    Worked.

    Attempt # Code Error Comments
    1 jshell> list.stream().grep({ l -> l.length() > 12}) cannot find symbol This is completely wrong. Aside from the stream() call, it is using Groovy syntax. (I code Groovy at a command line so my fingers started there. I did the same thing when I was doing this with Nashorn)
    2 jshell> list.stream().filter( l -> l.length() > 12) Success
  6. Add sorting and uniqueness
    Attempt # Code Error Comments
    1 jshell> list.stream().filter(l -> l.length() > 12).sorted().forEach(System.out::println) Sorting worked
    2 jshell> list.stream().filter(l -> l.length() > 12).sorted().distinct().forEach(System.out::println) Uniqueness filter worked

 My thoughts

This was 6 attempts/iterations using JShell.  This is compared to 17 in Nashorn! JShell is clearly a superior tool for prototyping Java. Part of this is because they implement common RPEL features. And part is because they don’t try to shoehorn a rhinoceros into being a Java RPEL. Seriously, many of the problems with Nashorn came from mixing Java and JavaScript while trying to prototype Java.

java 8 jshell mock questions

I gave a presentation showing how to make mock exam questions. We used Java 9 JShell as the example. The idea was to pick a feature nobody knew much about. We started by picking key points from this blog. Then we made questions. This post is the results. (Edited for formatting, to alphabetize answers, after confirming, etc). Good job all!

Question 1

What does REPL stand for?

  1. Random Enterprise Process Logic
  2. Rapid Enterprise Process Line
  3. Rapid Execution of Programming Logic
  4. Read Evaluate Print Loop
  5. Read Evaluate Print Line
  6. Read Execute Print Loop

Question 2

When typing into JShell interactively, it uses ______.

  1. Nashorn
  2. JRE
  3. JS
  4. JVM
  5. REPL
  6. RPEL
  7. Streams

Question 3

Which of the following compiles when typed into JShell? (Choose all that apply)

  1. Class.forName(“String.class”)
  2. Class.forName(“String.class”);
  3. Thread.sleep(1000)
  4. Thread.sleep(1000);
  5. System.out.println(“hello”)
  6. System.out.println(“hello”);

Question 4

Which of the following compiles when typed into JShell? (Choose all that apply)

  1. void method() { throw new Exception(); }
  2. void method() { throw new RuntimeException(); }
  3. void method() throw Exception { throw new Exception(); }
  4. void method() throw Exception { throws new Exception(); }
  5. void method() throws Exception { throw new Exception(); }
  6. void method() throw Exception { throws new Exception(); }

Question 5

Which of the following compiles when typed into JShell? (Choose all that apply)

  1. System.out.println(“Hello Java”)
  2. System.out.println(“Hello Java”);
  3. public void method() { throw new Exception(); }
  4. public void method() { throw new Exception(); };
  5. public void method() {System.out.println(“Hello Java”)}
  6. public void method() {System.out.println(“Hello Java”);}
  7. public void method() {System.out.println(“Hello Java”);};

Question 6

What are valid statement terminators in JShell? (Choose all that apply)

  1. ;
  2. :
  3. \n
  4. None (just press enter)
  5. None of the above

Question 7

Which of the following lines will compile and display a value if it’s the first line you type after launching JShell? (Choose all that apply)

  1. 5 + 6
  2. a + b
  3. System.out.println(“Hello”);
  4. System.out.println(“Hello”)
  5. out.println(“Hello”)
  6. out.println(“Hello”);
  7. { System.out.println(7) }
  8. { System.out.println(7); }
  9. 6 + 6; 10
  10. None of the above

Question 8

Which of the following is valid code in JShell? (Choose all that apply)

  1. system.out.println(“hello world”);
  2. system.out.println(hello world);
  3. Println(“hello world”);
  4. “hello word”
  5. hello world
  6. Answer: 5+3
  7. 5f+3
  8. new String()

Question 9

What is the output of the code below if executed in JShell?(Check all that apply)

Integer a = 5;

Integer c = a + 10;

Integer a = 7

a

  1. Compiler Error
  2. Runtime error
  3. 7
  4. Error: Duplicate variable declaration
  5. None of the above

Question 10

Which of the following commands invokes the help command in Jshell?  Choose all that apply.

  1. /h
  2. /help
  3. /?
  4. ?
  5. f1
  6. ctrl-f1
  7. help

Question 11

How would you invoke help on a particular Jshell command?  Choose all that apply.

  1. /help=command
  2. /help:command
  3. /help command
  4. /he command
  5. /h command

Question 12

double area (double radius) {

return 3.14 * square(radius);

}

area(2)

What is the correct output?

  1. 6.28
  2. 6
  3. 7
  4. Attempted to call area(double) which cannot be invoked
  5. Attempted to call square which cannot be invoked

Answers

  1. Choice 4 – Read Evaluate Print Loop
  2. Choice 5 – REPL
  3. All 6 choices are correct. The first two throw an exception, but do compile.  (This question had public in the user group lab. I wrote this question and removed it after)
  4. Choices 2 and 5. The semicolon is only optional at the end of the statement; not within a block
  5. Choices 1, 2, 6 and 7. The last two give a warning about public not being allowed, but work. The others fail because of an exception or missing semicolon within a method.
  6. Choices 1 and 4. Semicolon terminates a statement or you can omit the terminator
  7. Choices 1, 3, 4, 8 and 9. The last one is tricky. It gets executed as two statements.
  8. Choices 4, 7 and 8. JShell is case sensitive; just like Java
  9. Choice 3. (In the user group lab, there was another choice about a warning for a duplicate variable. I couldn’t reproduce the warning so removed that choice to avoid ambiguity.)
  10. Choices 2 and 3. Isn’t memorization fun?
  11. Choices 3 and 4. More memorizing
  12. Choice 4. Creating the method works, but gives a warning that square(double) must be declared. Then calling area gives “attempted to call method area(double) which cannot be invoked until method square(double) is declared”