15

I found this question, and this other, so intriguing that it begs several questions, at least for me:

Rather open-ended question, but where is jshell confined to? Obviously, GUI apps aren't in the domain for jshell solutions, or IDE replacement:

Out of scope are graphical interfaces and debugger support. The JShell API is intended to allow JShell functionality in IDEs and other tools, but the jshell tool is not intended to be an IDE.

Bonus points for Venn diagrams or other visuals.

Certainly, snippets should be limited in size. I'm more asking what sort of problems cannot be solved with snippets.

see also:

https://openjdk.java.net/jeps/222

https://openjdk.java.net/jeps/330

Thufir
  • 7,241
  • 18
  • 103
  • 236
  • 2
    Yes, this includes an open-ended question and is seemingly too broad to be answered on SO as well. Maybe refer to the corresponding JEPs to start off with https://openjdk.java.net/jeps/222 and https://openjdk.java.net/jeps/330 – Naman Dec 20 '18 at 11:29
  • 1
    JShell exist because some people said that Java *must have* a REPL facility. I never needed one. – Holger Dec 20 '18 at 11:38
  • Tried to narrow it down a bit, @nullpointer. But, yes, I don't see the utility myself. It's intriguing and yet so limited at the same time. – Thufir Dec 20 '18 at 11:55
  • 1
    Dang, you changed the answer while I was answering it. Oh well, I learnt a bit in the process. Time to start a blog. – tucuxi Dec 20 '18 at 11:57
  • @tucuxi please do :) anyhow, awesome answer. but where are my pics!? – Thufir Dec 20 '18 at 11:59
  • 1
    All problems *can* be solved with snippets (and with a sufficiently complicated shell script, too). But JShell is best used to debug and learn java - a full-fledged program is much more flexible for all other use-cases. – tucuxi Dec 20 '18 at 11:59
  • Added a picture – tucuxi Dec 20 '18 at 12:09
  • 1
    thx, @nullpointer. I'm going to come back to `JShell`, but it's kinda interesting. I can certainly its utility as a teaching tool. – Thufir Dec 29 '18 at 16:54

2 Answers2

15

Answering the updated question

All problems can be solved with snippets (and with a sufficiently complicated shell script, too). But JShell is best used to debug and learn java - a full-fledged program is much more flexible for all other use-cases.

JShell, .jsh and java MyClass.java

JShell is an interactive shell for trying out java code. Essentially, it is a REPL for Java.

Since JShell is all about you typing in code snippets, which it then evaluates, and it often makes sense to put those snippets in a file instead of writing them several times, JShell supports .jsh scripts, which contain collections of snippets to be interpreted by JShell. In this sense, this is similar to bash accepting .sh files or command.com accepting .bat files -- typing them line by line is equivalent to importing them.

Single-source java-file execution is a very different beast. It is sugar that replaces, from JDK 11 onwards,

java MyClass.java arg1 arg2 arg3

by your local scripting equivalent of writing

TMPDIR=$(mktemp -d)
javac -d $TMPDIR MyClass.java
java -cp $TMPDIR MyClass arg1 arg2 arg3
rm -rf $TMPDIR

This allows single-source files to be quickly executed from the command line with a single command, and without leaving their compiled classes all over the place (no actual temporary directory needs to be created, as java can store those classes in memory). Since they already had 3 other execution modes in java (for classes, jar-files and modules), it is no great stretch to add this as a fourth one.

Since OP wanted a picture: Venn diagram showing how JShell, .jsh and JEP330 intersect

Java as a scripting language

Now that the distinction is clear (.jsh is for use with JShell, single-source java executables are only for, you guessed it, single-source java executables), what about using Java as a scripting language?

You have always had the option to write a launcher; for example,

 #!/bin/bash
 java -jar MyApp.jar

has worked for ages. It was technically possible to name a class directly, but not too useful, as jar files are far more handy when distributing binaries -- for one thing, they avoid mirroring the package structure as a bunch of folders. Having a launcher script as separate from the actual java code was, however, still somewhat unfriendly: you now need to keep both together, or at least have the launcher be able to locate the actual .jar to launch.

Now, they have also introduced the following shortcut: regardless of file name or extension, you can distribute your java source with a "shebang prefix" as follows:

#!/path/to/java --source 11
<source of MyClass.java>

mark it as executable, and launch it from the command-line just as you can launch any other executable. For example, copy and paste this into a helloworld file (and fix the jdk location before attempting to run it):

#!/opt/jdk-11.0.1/bin/java --source 11 
public class Test {
    public static void main(String ... args) {
        System.out.println("Hello " + (args.length == 0 ? "world!" : args[0]));
    }
}

After marking it as executable, you can launch it directly with

$ ./helloworld
Hello world!

and it even takes its arguments right:

$ ./helloworld Bob!
Hello bob!

For small programs, and provided you do not need to go outside of the JDK to pull in additional libraries, it will now be vastly easier to distribute java code for command-line use.

Java will still not be a "scripting language" (it will never compete with, say, python), but

  • it has a very nice REPL loop
  • you can execute short programs a lot easier
tucuxi
  • 15,614
  • 2
  • 36
  • 70
  • This does not appear to work in openJDK 14 on the Mac. I get "compilation failed" from the / after the #!. If I delete the shebang line, then running java directly on the source file does work. – John Jul 31 '20 at 12:35
  • @John Mac probably uses a different path to the java executable (so "fix the jdk location before attempting to run it" :-) – tucuxi Aug 25 '20 at 07:01
6

Well, of course, its confined to a bring a normal REPL utility in terms of scoping what an IDE and graphical user interfaces could provide. I would talk of more about its capabilities as compared to single source code programs. The features that keeps it apart still from single source code programs:

  • a history with editing
  • tab-completion
  • automatic addition of needed terminal semicolons and
  • configurable predefined imports and definitions

As mentioned in the alternatives to Single-File Source-Code Programs JEP as well:

We could delegate the task of "one-off runs" to the jshell tool. While this may at first seem obvious, this was an explicit non-goal in the design of jshell.

The jshell tool was designed to be an interactive shell, and many design decisions were made in favor of providing a better interactive experience.

Burdening it with the additional constraints of being the batch runner would detract from the interactive experience.


!!! Limitations and behavior!!!

On the other hands, few limitations(assumed functionalities) that one would mostly find while performing a hands-on using JShell rather than simply reading the docs would be :

!!! Features and more !!!

More details over the links that gives it an upper hand over Single File Source Code Programs :

Naman
  • 23,555
  • 22
  • 173
  • 290