using Nashorn’s jjs 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. It works better in those languages though.

Cay Horstmann’s book, Java SE 8 for the Really Impatient, had good exercises for lambdas so I decided to the end of chapter exercises for Nashorn.

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

Nope. The so called advantage of using jjs is that you don’t need to write the plumbing code. But an IDE can generate a class and main method in a couple clicks.

  1. Strike 1 – With jjs, I need to type in the package of name of classes I want to use rather than just letting Eclipse deal with imports for me.
  2. Strike 2 – jjs doesn’t have tab complete (autocomplete) which means I have to type in the full class/method name of the class I am experimenting with. If I was an expert, I wouldn’t be in jjs in the first place.
  3. Strike 3 – jjs doesn’t support the up arrow. Which means when I make typos (see strike 1 and 2), I get to type the whole thing again.

Exercise 2 – Using JJS and 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 jjs:

  1. Create the test file in a text editor
  2. Run ./jjs
  3. Create a path object
    Attempt # Code Error Comments
    1 jjs> var paths = Paths.get(‘path/words.txt’) <shell>:1 ReferenceError: “Paths” is not defined Forgot to type the package name. Don’t know it by heart anyway. Need to look it up in the JavaDoc.
    2 jjs> var paths = java.nio.file.Paths.get(‘path/words.txt’) Success
  4. Read the file
    Attempt # Code Error Comments
    1 jjs> List<String> list = java.nio.files. Files.readAllLines(path) ECMAScript Exception: ReferenceError: <shell>:1:11 Invalid left hand side for assignment It’s JavaScript, not Java so no type declaration. Should just use var.
    2 jjs> var list = java.nio.files. Files.readAllLines(path)  <shell>:1 ReferenceError: “path” is not defined Typo in variable name. I wish I named it path, not paths. But I want to do the exercise in order and not go back.
    3 jjs> var list = java.nio.files. Files.readAllLines(paths) java.lang.RuntimeException: java.lang. ClassNotFoundException: java.nio.files. Files.readAllLines Typo in package name. It should be file and not files
    4 jjs> var list = java.nio.file. Files.readAllLines(paths) java.lang.RuntimeException: java.nio.file. NoSuchFileException: path/words.txt Missing forward slash in path name. On the bright side, I can rename the variable without feeling like I’m messing up the experiment.
    5 jjs> var path = java.nio.file. Paths.get(‘/path/words.txt’) Worked as expected (but at this point, I’m typing into this blog post and copy/pasting into the jjs console
    6 jjs> var list = java.nio.file. Files.readAllLines(paths)  java.lang.RuntimeException: java.nio.file. NoSuchFileException: path/words.txt Sigh. Didn’t use the corrected variable name
    7 var list = java.nio.file. Files.readAllLines(path) Worked as expected
  5. Filter the long words
    Worked.

    Attempt # Code Error Comments
    1 jjs> list.stream().grep({ l -> l.length() > 12}) ECMAScript Exception: SyntaxError: <shell>:1:23 Expected : but found – 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)
    2 jjs> list.stream().filter( l -> l.length() > 12) ECMAScript Exception: SyntaxError: <shell>:1:30 Expected an operand but found Hmm. Puzzled. it looks right this time. I copy/pasted into my IDE and it compiled. I then started searching online and found out that you have to use a function literal. (This was in the book. I forgot about it)
    3 jjs> list.stream().filter(function(e) { return e.length() > 12 }) Prints reference to stream (as does Java.) Now can add the print
    4 jjs> list.stream().filter(function(e) { return e.length() > 12 }).forEach(System.out::println) ECMAScript Exception: SyntaxError: <shell>:1:79 Expected , but found : Not surprised that :: doesn’t work since -> doesn’t. Now for the long way.
    5 jjs> list.stream().filter(function(e) { return e.length() > 12 }).forEach(function(e) { print(e) }) Works as expected
  6. Add sorting, uniqueness and refactor
    Attempt # Code Error Comments
    1 jjs> list.stream().filter(function(e) { return e.length() > 12 }).sorted().forEach(function(e) { print(e) }) Sorting worked
    2 jjs> list.stream().filter(function(e) { return e.length() > 12 }).sorted().distinct().forEach(function(e) { print(e) }) Uniqueness filter worked
    3 jjs> list.stream().filter(function(e) e.length() > 12 ).sorted().distinct().forEach(function(e)  print(e) ) Remove unneeded code

 My thoughts

That was so far away from being easier that it was ridiculous.  I’m comfortable with the NIO and lambda APIs. This shouldn’t have been hard. The Java version is:

import java.io.*;
import java.nio.file.*;
import java.util.*;

public class Exercise2 {
   public static void main(String[] args) throws IOException {
      Path path = Paths.get("/path/words.txt");
      List<String> list = java.nio.file.Files.readAllLines(path);
      list.stream()
                .filter(l -> l.length() > 12)
                .sorted()
                 .distinct()
		.forEach(System.out::println);
     }
}

OCA 8 Book: Online Material and Practice Exams now available

If you’re one of the individuals who already purchased the e-book of our OCA 8 Study Guide, you might have noticed the online materials weren’t up yet. They went up today.

If you’ve ordered a printed book, we are getting close. Amazon.com is currently predicting delivery between January 27th and February 25th. We will post again on this blog as soon as we hear of an actual US delivery. First printed book delivery was reported on January 31st.

We are also doing a book promotion at CodeRanch next week. Ask us a question and be entered to win a copy of the book.

sybex

What do the online materials include?

  1. 3 mock/practice exams (60 questions each)
  2. 2 sets of flashcards
  3. A searchable glossary
  4. Electronic versions of the assessment test and end of chapter review questions from the book

How do I register for access?

Step 1 – buy the book. Once you have an electronic copy or printed copy of the book in hand, it is easy. When going to the Sybex test bank site, you are asked to supply/create an access code. Creating one is easy. You are asked for your name and email. You are also asked to answer a question that is easy if you have the book. (Like “what is the answer to question 3 in chapter 2” or “fill in the blank from the text of figure 2.4”). Then the access code is emailed to you. It came immediately when I tested it.

With the access code, you go back to the test bank site and create an account. You get to use your email as username and the password of your choice making it easy to remember. Then you are in!

How is the test engine?

This is a new test engine from Wiley. Older books came with a CD that had a Flash based system for questions. While I’m sure this is very nice for non-coding exams, the old engine only showed a handful of lines of code on screen which was bad for programming exams. I’m SO glad they improved this before our book came out.

The new test engine is beautiful. It shows roughly as much code as the real exam. It has a timer so you know how long you have taken. (It counts up instead of down like the real exam does, but you know how long the real exam gives you so this is fine. It’s actually a good thing since Oracle likes to change the length of time allowed for the exam.) The engine lets you bookmark questions for review; as does the real exam. The whole system is intuitive and nice to use.

Author advice

  1. The engine lets you choose how many questions you want in the practice exam. I recommend taking them with the 60 questions each that are indented. A lot of thought went into which questions appear together on a practice exam and you’ll get the most realistic experience.
  2. The flashcards allow you to choose sequential or random order. I recommend random order. Just like you’d shuffle your physical flashcards to make sure you remember best.

OCA 8 Book: Online Material and Practice Exams

practice-test If you’re one of the individuals who already purchased our OCA 8 Study Guide, first we wanted to say thank you very much for your support. Jeanne and I both worked for a long time on the book and we really hope you enjoy it! Next, the Study Guide makes reference to online material available to purchasers of the book including an online glossary, flashcards, and three Practice Exams. It also includes online versions of the Assessment and Review questions found in the text of the book.

Jeanne and I wanted to let everyone know that the publisher is working on making that online material available right away, with an estimated release date of 1/25/15, less than two weeks from now. Of course, we will let you know if we hear anything sooner, but for now just sit tight, the material is being finalized.

UPDATE 1/23/2015: The online study material including practice exams has now been posted online! See this post for information.