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 third_party
directory:
% 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
third_party/BUILD
:
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.