JEP proposed to target JDK 11: 330: Launch Single-File Source-Code Programs
Stuart Marks
stuart.marks at oracle.com
Thu May 24 05:08:03 UTC 2018
On 5/22/18 7:43 AM, Peter Levart wrote:
> If this JEP added a feature that specifying source file name as "-" would read
> STDIN as the Java source file, one could write executable scripts in the
> following "hybrid" way:
>
> #!/bin/bash
> exec /path/to/java - $* <<EOF
> public class Hello {
> public static void main(String[] args) {
> System.out.println("Hello world");
> }
> }
> EOF
>
> Notice that this does not need shebang support from java launcher. The benefit
> of this approach would also be that /path/to/java could be computed by the bash
> script prefixing the Java source. Java typically does not have a standard
> installation "place" like bash, so shebang scripts with hard-coded java path
> would be less portable as bash scripts.
> Support for "-" STDIN source in java launcher does have one drawback. Scripts
> written this way can not process STDIN passed to the script as STDIN of java
> launcher is redirected to obtain Java source.
Hi Peter,
This is an excellent point: one can use a shell script "wrapper" to do all kinds
of interesting things in addition to computing the path to java, such as
supplying additional arguments based on other logic, etc.
I'll note that while "-" as a filename is a fairly strong convention, it isn't
strictly necessary; /dev/stdin can be used on many systems as a filename that
represents stdin. As you note this prevents the script's stdin from being read
by the Java program. Instead, one can use a here-document with a file descriptor
and then use /dev/fd/n as the "source file" to be compiled and run.
This is system-specific, of course, but these facilities should be widely
available. I tested this on a Mac using Jon's patch from a couple weeks ago, [1]
and it works fine. I'm sure Linux has the /dev/fd stuff as well. Also, the
--source option must be used to coax the launcher to compile a file that doesn't
end in ".java".
This is a little clunky, but it's no worse than the bits of magic you'd have to
put at the top of a perl script in order to run it as a shell script.
Here's an example:
-------
#!/bin/bash
exec java --source 11 /dev/fd/3 "$@" 3<<EOF
public class Hello {
public static void main(String[] args) {
String name = System.console().readLine("Please enter your name: ");
System.console().printf("Hello, %s!%n", name);
}
}
EOF
-------
$ ./Hello.sh
Please enter your name: Stuart
Hello, Stuart!
-------
s'marks
[1] http://mail.openjdk.java.net/pipermail/compiler-dev/2018-May/011874.html
More information about the jdk-dev
mailing list