Java REPL with JShell and Bazel
One great new feature of the upcoming Java 9 release is JShell, a Java REPL. Java is long overdue for an official REPL, so I was eager to try it out. I found this article to be a great starting point: Java 9 Early Access: A Hands-on Session with JShell – The Java REPL.
It’s easy to interact with the built in Java classes out of the box, but JShell becomes a lot more useful if you can interact with your existing application code. We use Bazel at Braintree, so I decided to add a Bazel target that would let me run my app code in JShell.
First, I downloaded the JShell (codenamed kulla) jar from their Jenkins and added it to the
% cd third_party % wget https://adopt-openjdk.ci.cloudbees.com/view/OpenJDK/job/langtools-1.9-linux-x86_64-kulla-dev/lastSuccessfulBuild/artifact/kulla-0.819-20150913005850.jar
Then, I imported this jar in Bazel by adding this to
java_import( name = "kulla_jshell", jars = ["kulla-0.819-20150913005850.jar"], )
Finally, I added a
java_binary target to the app. This target sets the
main class to JShell and adds both the app and kulla as dependencies:
java_binary( name = "repl", main_class = "jdk.internal.jshell.tool.JShellTool", runtime_deps = [ ":app", "//third_party:kulla_jshell", ], )
One issue is that JShell requires Java 9, but Bazel does not currently support it. The Bazel built jars are compatible, however, so we can build a deploy jar with Bazel and Java 8, and then run it with Java 9:
% bazel build //app:repl_deploy.jar % /usr/lib/jvm/java-9-oracle/bin/java -jar bazel-bin/app/repl_deploy.jar | Welcome to JShell -- Version 0.819 | Type /help for help -> import app.* -> App a = new App() | Added variable a of type App with initial value app.App@1761e840 -> a.go() | Expression value is: "go go go" | assigned to temporary variable $3 of type String
Now, I can interactively play with app code in a REPL. Once Bazel adds support for Java 9, it will be even easier.