Language selector

JavaScript(s)!

Java, version Script

There’s an old joke where I live about the IT recruiters and IT folks. I don’t find it that funny, hence I’ll spoil it: it’s about one person trying to hire another person and one of them knows ‘Java’, while the other needs ‘Java, version script’. Or the other way round ;-) Anyway, this similarity in names of these programming languages in not a coincidence, as you may read in Wikipedia.

Many non-Java developers find it shocking, that it’s possible these days to write a script (which will run in CLI) not only in Bash, Perl, Python, PHP, etc, but also in Java™. Frankly speaking, if ‘Java version script’ can run backends now, why scripts can’t be written in Java?

This post is not about jshell, which can be used both as a REPL, both to run in a batch mode. I’d like to show you how you can run a ‘script’, or cron it, without creating .class or .jar files. Heck, the scripts don’t even need to be placed in files with .java extension!

Hello World (again)…

Without further ado: you know this code, right?

1public class HelloWorldExample {
2    public static void main(String[] args) {
3        System.out.println("Hello, World!");
4    }
5}

Let’s say that this is a fancy script you need to call. It doesn’t have to be blazing fast, it should just do the job. Also, you have Java 11+ installed. Plus you’re not mastering Bash/Zsh/Perl/whatever-other-scripting-language-you-might-have…

What’s also important, you don’t want to run the well-known cycle of edit->compile->run. Pretty much like in Python, you’d like to edit a text file (or send a snippet to your friend), save it, then run it. If “the technology under the hood” needs to compile it/interpret it/shave a yak, fine, so be it! You just want the thing to run, because it’s getting late, and your manager really doesn’t care.

So what can you do? Let’s say the file is saved as HelloWorldExample.java. Then you can run/execute this file the following way:

$ java HelloWorldExample.java

The standard output is:

Hello, World!

Now, you don’t need to trust me. You can check on your own, that there’s no HelloWorldExample.class file in current directory on your machine. Everything happened ‘under the hood’ and ‘on the flight’. In this case the java acts like an “interpreter”.

Wait, that’s not all! I’ve promised you a script without explicit “interpreter” when calling, so here it comes.

Run example, run

run

Picture by Ryan McGuire from Pixabay

First, you should find out the location of your java command. You can do that by calling which java in the terminal. In my case it’s /home/piotr/.sdkman/candidates/java/15-open/bin/java, your results might be different, depending on how and where you have Java installed.

Next, let’s copy the HelloWorldExample.java to a file hello.script. Then let’s prepend one line to this file, so it looks like this:

1#!/home/piotr/.sdkman/candidates/java/15-open/bin/java --source 11
2public class HelloWorldExample {
3    public static void main(String[] args) {
4        System.out.println("Hello, World!");
5    }
6}

This line (if you don’t know it) is called shebang. In this very case it says that “what follows, should be interpreted as Java code, version 11”.

The last thing to do is to make this file executable, by calling chmod u+x hello.script in CLI.

Now it’s time to call our “Java Script”:

$ ./hello.script 
Hello, World!

As you can see, you can call in your terminal a “script written in Java”.

It can also do more fancy stuff, pretty much like any script. Wanna read some arguments?

1#!/home/piotr/.sdkman/candidates/java/15-open/bin/java --source 8 
2import java.util.stream.Stream;
3public class ArgumentsExample {
4    public static void main(String[] args) {
5        Stream.of(args).forEach(System.out::println);
6    }
7}
Here you go:
$ ./arguments.script ene due rabe
ene
due
rabe

Need to use the script in a piped chain of commands? Then (demo only!):

1#!/home/piotr/.sdkman/candidates/java/15-open/bin/java --source 11 
2import java.io.IOException;
3public class PipedExample {
4    public static void main(String[] args) throws IOException {
5        new String(System.in.readAllBytes()).lines().map(String::toUpperCase).forEach(System.out::println);
6    }
7}
So you can use it:

$ whoami | ./piped.script 
PIOTR

I’m not sure using “Java scripts” like these entitles you to call yourself “full-stack developer”, but for sure this might help if you’re not familiar with awk, or you don’t have a cat nearby to type some Perl.

For more details, please refer to JEP 330.

Language selector