Launching Single-File Source-Code Programs

A new feature is proposed for Java 11: To launch a Java program consisting of a single file, you can skip compiling it. This is proposed as a feature to make learning java easier. Having some experience in teaching Java to beginners, I explain why it does not.

small-rocket

JEP 330 proposes to make it easier to launch a simple Java program. Instead of

javac HelloWorld.java
java HelloWorld

you just call

java HelloWorld.java

Ok, what's not to like? Python works like that. Behind the scenes, it compiles .py files to .pyc, and Python users live in the happy illusion that Python is an interpreted language.

Here is what's not to like.

JEP 330 proposes this to work only if the source code is in a single file. Two or more files? You are back to javac and java. The proposal is just for launching small rockets.

As someone who teaches Java, I can just see how this is going to work out.

Hey prof, I have this project with two Java files. When I run

java MyProj.java

it doesn't work. But

javac MyProj.java
java MyProj

works ok. But with HelloWorld, I didn't have to use that javac thing. Why?

Dear student, that's just the way it is. It works with one file, but not with two.

Private thought: Oh great! Yet another trivia fact that will be endlessly probed by certification exams.

Ok, there is another use case for JEP 330 that they didn't choose to highlight in the “Motivation” section. Lots of people write shell scripts in Python. Why not in Java? These days, the Java API for working with files and processes is just as good as Python.

JEP 330 proposes to ignore a “shebang” line

#!/path/to/java

I am all for that.

Now if someone had asked me what educational pain point the Java launcher could solve, I would have an answer in a heartbeat: Get rid of public static void main.

When I teach Java programming, I tell my students: Java was designed from the ground up to be an object-oriented programming language. You invoke methods on objects. Objects belong to a class. The class defines the methods. To make an object, you use a constructor.

Hey prof, what's that public static void main thing?

Ummm, that's different. static means it doesn't operate on objects. And that HelloWorld class—you don't construct any objects. It's just the way it is.

BTW, last week my publisher asked me to see if one of my video courses would be suitable for a certification exam, so I took the exam. And I was shocked how many trivia questions it had about public static void main. Really? People hire programmers because they demonstated that they can navigate the shoals of public static void main?

There is an easy way around. Suppose the Java launcher, when presented a class without public static void main but an accessible no-arg constructor, would just construct an instance. Then I could start out my course with

class HelloWorld
{
   HelloWorld() { System.out.println("Hello, World!"); }
}

I could talk about classes, objects, and constructors. I could teach computer science and not language trivia and minutiae.

I did propose this many years ago and even submitted a patch to the Java launcher to make it happen. It was promptly shut down for “compatibility reasons”. Years later, I watched with some bemusement that a similar feature was added to support long-suffering JavaFX developers. In JavaFX, and only JavaFX, you can use the java executable to launch a program that starts with

public class HelloWorld extends Application
{
   public void start(Stage primaryStage)
   {
      ...
   }
}

If the java launcher wants to build in ad-hoc support for shell scripts (yeah) or GUI toolkits (meh), whatever. But don't sell it as an advantage for the “early stages of learning Java”. There are far better ways for making those early stages less ceremonial.

Comments powered by Talkyard.