Scripting with Java 10 and JShell

While Java 9 has brought us JShell and a new Http Client (in incubation), Java 10 has brought the var keyword (aka Local-Variable Type Inference) to the “scripting with Java” table. In this post we will combine the powers of JShell together with the brevity of var.

You always wanted a JShell

If you haven’t heard of the JShell REPL introduced in Java 9 so far you should probably watch a video (like this one, starting at 59:00) from Venkat Subramaniam demonstrating the JShell REPL.

You probably want var

While the benefits of using var in the common Java world might be questioned by some, the benefits of using var in a scripting context are undeniably great. Namely:

  • no need to import the return type (less code)
  • no need to spell out types (less code, much easier to write)
  • easier readability

Now, do you have to use var? Absolutely not!

Do you want to? Yeah, probably you want to!

Putting it all together

Now, you might ask yourself:

Can I finally use Java as a scripting language and call it JavaScript?

Yes and No (No, you can’t call it JavaScript for obvious reasons).

What you can do with JShell is put your script code in a file code named myscript.jsh and execute it with: jshell myscript.jsh. It might be a stretch to say that this feature was intended to be used for real world scripting purposes, but it could absolutely work out great!

Have a look at following examples and be amazed! (or frightened — your choice)

HTTP Client

Often you want to check a remote source with a simple script.

E.g. has that website changed? Can I finally buy those concert tickets for the next Lady Java concert?

Using the new HTTP client, var and JShell we can put together this readable, neat script:

The /exit at the end is needed so that the JShell is left after execution.

Working with directories and files

Often in scripts you want to work with files and directories, but with the Java standard library that’s not exactly easy. So we simply use FileUtils from Apache Commons to reduce the amount of code:

Passing command line arguments

Unfortunately passing arguments via the command line is not directly supported in JShell. There is one quirky workaround that makes it possible to pass arguments via System properties as demonstrated in the example below:

Coming to an end (or /exit ?)

Let’s have a look at the pros and cons of scripting with JShell and Java.

Upsides

  • Commonly used packages are already imported
  • OS independent scripting (Java/JShell runs on Windows, Linux, macOS, …)
  • Use the same language for scripting that you already use for developing software
  • Might be a way around company guidelines that only allow Java as programming language (but not Groovy or Python)

Downsides

  • /exit at the end of script files is necessary if you want JShell to quit after execution
  • Multiline does not work as expected (don’t split one statement over multiple lines)
  • There is no easy handling of command line arguments (a workaround is via system properties)
  • The Java APIs are rather complicated for scripting use (especially when writing without IDE)

All in all it becomes clear that JShell wasn’t intended to be used as an interpreter for scripts, but with those few downsides in mind it works alright.

I have created a Github repository that contains several JShell sample scripts, which you can clone to get a jump start for your JShell career:

PS: The project is still on the lookout for a simple, secure web server script, that can be used to serve some JSON. Got an idea?