Draft JEP: Launch Single-File Source-Code Programs

Jonathan Gibbons jonathan.gibbons at oracle.com
Mon Feb 12 20:01:07 UTC 2018

On 02/12/2018 10:42 AM, John Rose wrote:
> On Feb 12, 2018, at 8:47 AM, Brian Goetz <Brian.Goetz at Oracle.COM> wrote:
>> The alternative — intruding this convention on the Java language syntax — is certainly a worse tradeoff. Think of this as “launcher 90% full” rather than “language 10% empty” :)
> This is all good, and I agree that we don't need to add shebang to
> the JLS. (See argument below.)  But, the proposal doesn't fully
> match the design of shebang processing.  I'd like to discuss that
> and propose a slight tweak.
> The purpose of the shebang is to allow a Unix command to be
> implemented by a script file with a designated script interpreter.
> This only works if the file is executable and is implemented by
> the system call execve[1].  BTW, marking a file executable without a
> shebang sends it to /bin/sh, but by a higher layer[2] of the system,
> not used in all cases.
> [1] https://linux.die.net/man/2/execve <https://linux.die.net/man/2/execve>  (OS-level definition of shebang)
> [2] https://linux.die.net/man/3/execl <https://linux.die.net/man/3/execl>   (library function adds implicit #! /bin/sh)
> This predates modern mechanisms, such as desktop launchers,
> which systematically recognize file extensions and map them to
> content types.  This is important:  Shebang doesn't care about
> file name extensions.
> The optional argument to the script interpreter, as supported by
> shebang, allows the interpreter to be run in a non-default scripting
> mode which accepts the two oddities which come from shebang:
> 1. the file starts with a shebang (which otherwise might be unexpected
> by the interpreter), 2. the file name might not have an extension
> expected by the interpreter (because it is a nondescript command
> name, implemented by a script).  The dtrace '-s' option does this,
> and so (I presume) would the java '--source' option.
> Higher-level launchers, above the level of the "exec*" families,
> look at file extensions, such as "*.jar" or "*.app".  These do
> not integrate as directly with Unix shell scripting, since "exec*"
> won't launch them.
> The net:  The design of shebang expects the interpreter to (sometimes)
> require nonstandard invocation modes to process the shebang file.
> The physical form of the file name is insignificant to shebang processing,
> although it may (of course) be significant to the interpreter.
> A quick survey of shebangs on my Mac show the following interpreters
> used on my $PATH: /bin/*sh [-vepf], *python [-OR], /usr/bin/env *,
> perl* [-w], ruby, *lua, dtrace -[q]s.  Only dtrace uses a specific script flag
> in all cases.
> At least one language (lua) documents shebang stripping as lexical
> exception, but only in a particular invocation mode.  We can get the
> same effect by factoring the exception into the launcher, not the JLS.
> The applications to the present case:  From the point of view of the
> design and use of shebang, it is reasonable to treat shebang
> as an extra-linguistic construct, to be stripped by a special mode
> of the script language processor (java).  From the same point of view,
> it is not reasonable to require a special file extension (such as *.java)
> to the shebang file, since that removes the main use case of shebang,
> building arbitrary Unix commands on top of scripts.
> So, if we want to properly integrate with the shebang, we need to drop
> the requirement that the file name end with ".java", in the presence
> of the "--source" option.  If the "--source" option is missing, it's fine
> to require the "*.java" file name extension, as a nod to EOU.
> And it's fine to have non-standard file processing (shebang removal)
> under a special invocation mode ("java --source").
> We might forbid shebang unless the "--source" option is present.  That
> would make it clearer that a non-standard mode is present.  It would be
> even more pedantically correct if there were a special "--shebang" mode
> (not its real name), leaving "--source" to accept only standard Java
> without shebang.
> My bottom line suggestions:  allow "java --source any-path" not just
> "java --source path.java" and strip shebang in that case; this enables
> full-range use of shebang in Unix.  Allow also "java path.java", but
> take a moment to reconsider whether shebang makes sense in that
> case.
> — John


Thank you for your detailed analysis of the landscape of the "shebang"
mechanism and files.

With respect to your bottom-line suggestions, it is definitely the intent
to allow  "java --source any-path", to facilitate full-range use of shebang
in Unix.  It would be easy to go either way with regarding to permitting
shebang lines when the --source option is not used. I'll admit to some
attraction to restricting the use of shebang lines to those cases where
the --source option is used.

While I note your pedantry with regard to having two options, --shebang
(not its real name) and --source, it is not clear there is enough benefit to
making a distinction here ... in other words, there is merit in having a
special option to invoke special behavior for files with a non-standard
naming and possible shebang first line, but there is not enough merit in
having an additional option for source files that follow the naming
convention and which just contain a standard compilation unit.

-- Jon

More information about the jdk-dev mailing list