JEP proposed to target JDK 11: 330: Launch Single-File Source-Code Programs
Jonathan Gibbons
jonathan.gibbons at oracle.com
Thu May 24 23:23:28 UTC 2018
Mario,
Your comments are well-taken, and the existence of other, arguably
better, ways to invoke Java source code from a script lend credence to
the argument that we should _not_ extend the Java language or javac to
directly support shebang lines.
Two suggestions have been made in this discussion, both of which can be
the subject of further investigation, separate from this JEP.
1. Support for "//!" in Linux and other Unix-based systems as an
alternative to "#!". Such a feature would totally remove the need for
suppressing shebang lines in the source files under consideration. But,
while we can advocate for such a solution, such would be an RFE for
those systems to consider, and would be beyond the scope of any JEP.
2. The use of "here" documents, as suggested by you and others. The JEP
as currently proposed should support such usage, albeit using the
somewhat cryptic "/dev/fd3" as an input file. It would be a relatively
minor change to the current work to support the commonly accepted use of
"-" to represent stdin. There is nothing in the current work that would
preclude that, and supporting "-" could be handled as a followup RFE.
Regarding your specific proposal for using "here" documents, I do not
follow your argument that your example is better for being "proper Java,
with all the benefits like debugging, IDE support etc.". At least to a
casual observer, the shebang line and the couple of lines to invoke java
using a "here" document look very similar: in both cases, there is a
cryptic header followed by some Java source code. In both cases the file
can be seen as a script that contains Java source code, as compared to a
Java source file that is a script.
As to the possible ways forward:
* Support for "//!" is attractive but requires a manual or automated
update to the underlying system, which is beyond our control.
* Support for using "here" documents as you suggest is possible: it is
ultimately more flexible than shebang lines, and should be advertised in
the JEP, but it requires a more advanced understanding of shell, when
much of the current focus is about simplifying the on-ramp to Java.
* The "shebang" line is attractive for its simplicity for all those
cases where it is sufficient, even if the Java launcher has to go out of
its way to remove the line before compiling the source code that follows.
The general theme here is not to evolve Java into a scripting language,
but to make tools like the Java launcher more friendly to supporting the
use of Java source code in an executable text file, in order to reduce
the ceremony of running simple programs.
In conclusion, while I don’t think pulling the emergency brake cord on
this feature is warranted, there are some simpler things we could do. I
suggest that we should update the JEP to be more clear about the
Non-Goals, and to cite additional alternative ways that Java source code
can be used in executable text files (scripts.) This is in addition to
yesterday's suggestion [1] to draw a more distinct separation between
Java source files (which end with a .java extension), and executable
scripts (which do not use any such extension.)
-- Jon
[1] http://mail.openjdk.java.net/pipermail/jdk-dev/2018-May/001248.html
On 5/24/18 2:02 AM, Mario Torre wrote:
> I hear those concern, and I agree with you, but this shows why this is
> an unwanted feature if any. I find this JEP dangerous to some extent
> (ok, that may be perhaps a strong wording) because it turns Java into
> a scripting language without full support from the JLS. Now, the
> controversial point is clearly the shebang support, the rest seems
> fine and reasonable, and like others have said if we allow to read
> files from stdin we should have full equivalence of shell scripting
> without all the unwanted side effects:
>
> #!/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
>
> Is functionally the same and almost as convenient as:
>
> #!/bin/java
> 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);
> }
> }
>
> Except that is proper Java, with all the benefits like debugging, IDE
> support etc.. in fact, the added benefit is that such utility is more
> naturally projected toward a use "_at the end of their development
> phase_", as it requires a developer to thing through the embedding,
> but at the same time it keeps the option open, since this is instantly
> compatible with any scripted java code you may have already around or
> any actual compiled class, no need to touch anything to make it work
> in the script, platform idiosyncrasies are where they belong, no
> special casing. Yes, the difference is really a one liner but the
> perception in how this is meant to be used is drastic.
>
> I think this should be part of the JEP and the controversial line
> about Shebang removed instead.
>
> Cheers,
> Mario
>
>
> On Wed, May 23, 2018 at 11:01 PM, Jonathan Gibbons
> <jonathan.gibbons at oracle.com> wrote:
>> On 5/17/18 1:12 PM, mark.reinhold at oracle.com wrote:
>>
>>> The following JEP is proposed to target JDK 11:
>>>
>>> 330: Launch Single-File Source-Code Programs
>>> http://openjdk.java.net/jeps/330
>>>
>>> Feedback on this proposal is more than welcome, as are reasoned
>>> objections. If no such objections are raised by 23:00 UTC on Thursday,
>>> 24 May, or if they're raised and then satisfactorily answered, then
>>> per the JEP 2.0 process proposal [1] I'll target this JEP to JDK 11.
>>>
>>> - Mark
>>>
>>>
>>> [1] http://cr.openjdk.java.net/~mr/jep/jep-2.0-02.html
>> A number of points have been raised, regarding the interaction with javac
>> and shebang scripts.
>>
>> It was never a goal to modify javac to support shebang-java scripts. This
>> can be seen indirectly in the JEP in the description of how the first line
>> may be removed before passing the rest of the file as a normal
>> CompilationUnit to the compiler. With hindsight, this deserves to be stated
>> as an explicit Non-Goal.
>>
>> There are various reasons to not want to change JLS or javac:
>>
>> 1. Changing JLS is a Big Deal, and comes with its own costs and constraints.
>> Further, shebang files are a platform-specific feature, and are not even
>> defined in the POSIX standard. The feature does not warrant changing a
>> JCP-controlled specification.
>>
>> 2. Changing javac to accept shebang-java files is also a Big Deal. Modifying
>> the command-line options to accept files that do not follow the standard
>> naming conventions would introduce complexity and potential ambiguity.
>>
>> 3. There is no compelling need to change JLS or javac. As demonstrated by
>> the proposed implementation, no change to JLS or javac is actually necessary
>> in order to implement the feature. It is therefore at most a convenience if
>> javac were to be adapted to ignore shebang lines.
>>
>> Shebang scripts are an executable format defined on some, but not all,
>> platforms. Creating a shebang script is typically more than just adding an
>> initial first line to a file; it typically involves a number of steps:
>>
>> a. Add an initial shebang line to the file
>> b. Rename the file to a "command-friendly" name
>> c. Make the file executable
>> d. Install the file in some standard location
>>
>> While renaming the file to a command-friendly name is optional, it is also
>> expected to be common practice. For example, a source file named
>> `HelloWorld.java` might be installed as `helloworld`. And, while the JEP
>> describes use cases for executing a small single-file program with `java
>> HelloWorld.java` or executing it as a platform-specific shebang script with
>> just `helloworld`, it does not seem like there is a common use case to
>> execute `HelloWorld.java`. So, if the shebang script is typically renamed to
>> a command-friendly name, it will not be possible to compile it directly,
>> with "javac helloworld", because that is not a valid command line for javac.
>> This reduces any potential convenience of having javac ignore shebang lines.
>>
>> Since Java source files are different artifacts to platform-specific
>> executable scripts, it makes sense to treat them differently, and since we
>> do not want to change the Java language to support shebang lines, the
>> suggestion is to amend the JEP and implementation so that shebang lines are
>> never stripped from Java source files, i.e. files ending in `.java`. This
>> avoids the problem of having the ecosystem of tools handling Java source
>> files having to deal with arbitrary artifacts like shebang lines. The
>> change would still permit the direct execution of Java source files, such as
>> `java HelloWorld.java`, and the execution of shebang scripts, such as
>> `helloworld`.
>>
>> -- Jon
>
>
More information about the jdk-dev
mailing list