JEP proposed to target JDK 11: 330: Launch Single-File Source-Code Programs

Brian Goetz brian.goetz at
Thu May 24 00:41:20 UTC 2018

> On 21/05/18 16:41, Brian Goetz wrote:
>> I think this is mostly a "glass 5% empty" argument.  Let's retrace our
>> steps.
> Before we 'retrace' may I ask: was that meant to be 5% or 50%?

I did mean 5%.  The small number was not intended to minimize Roman's 
concern, but to minimize the place of the shebang feature in this JEP 
itself.  In setting our goals for the project, shebang support was 
always a pretty small, and entirely optional, part of the picture (a 
"stretch goal").  So if a small part of the whole is somewhat smaller 
than some might prefer, the difference is, necessarily, pretty small.  
(If we hadn't found a reasonably stable place to draw the line (I think 
we were kind of lucky to have done so), we would have been perfectly 
fine to have no shebang support, but I do think the status quo is much 
better than that.)

> It certainly is not what I
> was expecting and hoping to hear given your use of the word 'retrace'.

OK, let me explain the sense of "retrace" here.  As one of the 
instigators for this project, I am in a position to speak 
authoritatively to motivation, intentions, and goals.  While we of 
course attempt to lay these out in the JEP and in related 
communications, the reality is that one will never capture all the 
possible tradeoffs and interpretations in a short document.  So, when 
someone comes along with a different idea of what the goals of the 
project could have been, the sensible first step is to go back to our 
motivation, and clarify, in the context of the current relevant 
question.  (This isn't necessarily a failing of the expression of the 
JEP; no one would be served by a 200 page JEP that tries to anticipate 
every possible interaction and interpretation, and the cost of producing 
such a document would be way out of line with its value.)  So by 
retrace, I mean "let's go back to the inception of the project, which is 
necessarily uncaptured, and look at the thoughts that were in our heads 
at that time that might shed light on how we ended up where we did."

Since my first attempt seems to have missed the mark, let me retrace in 
slightly more detail.

We have spent countless hours listening to people's concerns about Java; 
these come from a wide range of sources, including developers, students, 
teachers, etc.  A general theme that people have expressed concern over 
is "activation energy"; that doing simple things in Java requires too 
much fixed work.  Examples include:
  - you have to download/install a JDK and IDE before you can write 
Hello World
  - "public static void main"
  - You have to compile before you run it.
  - Many libraries have a large fixed setup cost before you can do anything.
  - the list goes on

Obviously, even a small amount of brainstorming along these lines could 
generate hundreds of man-years of project work, so we can't do all of 
them.  So we made subjective choices about which had the best impact, 
and we consider both the cost (in multiple dimensions) and benefit (or 
our subjective estimates of the benefits) when making these choices.

One example of a project aimed, at least in part, at this problem was 
JShell.  I think this was very successful (but it was surely 
expensive.)  JEP 330 has both a smaller cost and a smaller benefit, but 
the balance seemed in line, and the cost was in budget.  So the goal 
here was to simplify approachability and streamline simple tasks that 
are perceived to have a high subjective activation energy.  That's the 
backdrop behind why we undertook this in the first place -- it provides 
some relief in the activation energy department, as long as it has a 
reasonable balance of cost and benefit.

Actually, the step-retracing goes much farther back than this.  When we 
did jshell, we considered whether jshell should also serve as a "batch 
script runner", and this issue has been brought up plenty of times 
since.  But from the very beginning of the jshell project, we felt 
strongly that this would be asking jshell to serve two masters; jshell 
is intended as an interactive tool, and many decisions were made in 
favor of a better interactive experience.  If people want to just run a 
single Java file in source form, a more principled approach would be to 
teach the launchers about source files -- which was entirely practical, 
and a much better fit for "I just want to run a 'script' file that is 
written in Java."  So the seeds of this project were sown several years 
ago, and over those years, there have been many discussions (in many 
places) about how to address this particular use case.

When we first started discussing this feature, we were thinking mostly 
in terms of a more streamlined means of execution, but it didn't take 
long to ask the question about packaging.  If people want to write 
"scripty" programs in Java, once developed, they're going to want to 
package and install them, and this is also a high-activation-energy 
aspect of Java (JARs, build scripts, etc). Shebang is a very 
low-overhead form of packaging, and -- as long as it didn't perturb the 
main goal or drive the cost or complexity over budget -- seemed to offer 
pretty reasonable incremental benefit for a not-terrible incremental cost.

But, one can go too far, and turning this into a language feature would 
have been taking it too far.  The Java Language and VM try very hard to 
be platform-neutral; shebang is definitively not platform-neutral.  And, 
anything having to do with the language spec incurs greater costs (I'm 
not just talking development costs) and complexity.  So, this isn't a 
language feature, it's a platform integration feature.  Which is why the 
launcher is the right vehicle here -- this is where the Java platform 
meets the underlying platform.

Volker raised this question early on.  We had already thought about the 
implications of this (we generally think pretty deeply about the many 
possible roads one could take before we propose a project), and we 
didn't like them -- because, as mentioned above, this is a platform 
integration issue, not a language issue.  I don't deny that it would be 
nice in certain situations if we made no distinction between "Java 
source file" and "scripts that happen to contain Java source code" -- 
and that might be a perfectly reasonable choice for some other languages 
-- but the goal was never "Java as a scripting language".   So, while 
"why not go all the way with shebang" is a reasonable question to ask, 
it seemed (and still seems) the wrong match for Java.  When the question 
came up again (as they always do in a large community), no new 
information had come to light to cause us to come to a different 

Jon's distinction here between "Java source file", and a separate notion 
of "script that contains Java code" or "platform-specific executable 
script", is a good one; we'd implicitly been thinking of these as two 
different things, but its clear that this is confusing to people, and 
making the distinction explicit should dispel some of that confusion.  
Sure, they _could_ be merged, but highlighting this distinction seems 
much more in keeping with the spirit of the platform than blurring the 
distinction (though that might be a fine choice for other languages.)  
So, +1 to Jon's suggestion.

So, what can be done here?  We could:
  - move forward with the feature, as is.
  - clarify the distinction between "Java source file" and "script 
containing Java", and tweak accordingly, as Jon suggests.
  - drop the JEP entirely.
  - drop the shebang support and keep the rest.

What does not seem like a reasonable choice is to turn the Java Language 
into a platform-dependent thing, for all the reasons Jon mentioned, and 

> I am afraid that adopting pejorative terms like 'infecting' doesn't
> really make your case stronger.

I'm sorry if you were offended by my use of this term.  I take the Java 
Language very seriously, and defend its boundaries vigorously!


More information about the jdk-dev mailing list