Java 22: Run Multi-File Programs Without Compiling
Introduction
Java 11Click to read: Java 11 let the
Running the file containing
OUTPUT of the above command
How it works
Programs in packages
If the launched file declares a package, the launcher works out the root of the source tree from the package name and the file's location, and finds other classes relative to it - exactly as
OUTPUT of the above command
Because
The program can also be modular: if the source root contains a
When to move to a build tool
Launching from source is ideal for learning, scripts, prototypes and small utilities - the "grow your program gradually" path the feature was designed for, together with the compact source files of Java 25Click to read tutorial: Java 25 Compact Source Files and Instance main Methods. Move to
java command run a program straight from a .java file, compiling it in memory - but only if the whole program fitted in that one file. As soon as a small program grew a second file, you were back to javac and a build setup. Java 22Click to read tutorial: Overview of New Features in Java 22 (JEP 458) removed that limit: the launcher can now run a program made of several source files, compiling the other files the program uses on demand. This tutorial explains how to launch multi-file source-code programs with examples - several classes in several files, programs in packages, using libraries, and when it is time to move to a build tool.
A program in two files
Here is a small program split over two files in the same directory: Main.java, with the main method, and Invoice.java, a record it uses -
Main.java
//Main.java
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Invoice> invoices = List.of(new Invoice("INV-1", 1200.0), new Invoice("INV-2", 350.5));
double total = invoices.stream().mapToDouble(Invoice::amount).sum();
invoices.forEach(i -> System.out.println(i.describe()));
System.out.printf("Total: %.2f%n", total);
}
}
Invoice.java
//Invoice.java
public record Invoice(String number, double amount) {
String describe() {
return number + " for " + amount;
}
}
main is enough - no javac, no class files on disk -
java Main.java
INV-1 for 1200.0 INV-2 for 350.5 Total: 1550.50
- The launcher compiles
Main.javain memory. When the program refers to a class it cannot find - hereInvoice- the launcher looks for its source file in the directory tree of the launched file,Invoice.java, and compiles it too. - Files are compiled lazily, when a class is first needed while the program runs, so source files in the directory which the program never uses are never compiled. A compile error in a file is reported when that file is first needed.
- As in Java 11, nothing is written to disk, and the program is recompiled every time it runs.
javac would with a source path -
src/com/shop/App.java
//App.java
package com.shop;
import com.shop.model.Order;
public class App {
public static void main(String[] args) {
Order order = new Order("Laptop", 2);
System.out.println("Order: " + order + ", packaged in " + Order.class.getPackageName());
}
}
src/com/shop/model/Order.java
//Order.java
package com.shop.model;
public record Order(String item, int quantity) { }
java src/com/shop/App.java
Order: Order[item=Laptop, quantity=2], packaged in com.shop.model
App.java declares package com.shop and lives in src/com/shop, the launcher takes src as the source root and finds com.shop.model.Order in src/com/shop/model/Order.java.
Using libraries
A multi-file source program can use libraries in the usual way, by putting their JAR files on the class path. The --class-path option accepts a wildcard, so all JARs in a directory can be added at once -
java --class-path "lib/*" Main.java
module-info.java, the program is compiled and run as a named module, with libraries on --module-path.
javac and a build tool such as Maven or Gradle when the program needs to -
- download and manage dependencies,
- run tests, use annotation processors (which the source launcher does not run), or produce a JAR to distribute, or
- start quickly every time, since the source launcher recompiles on each run.
java Main.java, saw that the launcher compiles the other files lazily, in memory, when their classes are first needed, and ran a program in packages, where the source root is worked out from the package name. Lastly, we added libraries with --class-path and looked at when to switch to a build tool. Next, read the overview of new features in Java 22Click to read tutorial: Overview of New Features in Java 22.Continue Reading Java 22 to 25 Tutorials
Overview of New Features in Java 22Click to read tutorial: Overview of New Features in Java 22 Java 22 Foreign Function & Memory API TutorialClick to read tutorial: Java 22 Foreign Function & Memory API Tutorial Java 22 Unnamed Variables and Patterns with _Click to read tutorial: Java 22 Unnamed Variables and Patterns with _ Overview of New Features in Java 23Click to read tutorial: Overview of New Features in Java 23 Overview of New Features in Java 24Click to read tutorial: Overview of New Features in Java 24 Overview of New Features in Java 25Click to read tutorial: Overview of New Features in Java 25 Java 23 Markdown Documentation CommentsClick to read tutorial: Java 23 Markdown Documentation Comments Java 24 Stream Gatherers Tutorial with ExamplesClick to read tutorial: Java 24 Stream Gatherers Tutorial with Examples Java 24 Class-File API Tutorial with ExamplesClick to read tutorial: Java 24 Class-File API Tutorial with Examples
Overview of New Features in Java 22Click to read tutorial: Overview of New Features in Java 22 Java 22 Foreign Function & Memory API TutorialClick to read tutorial: Java 22 Foreign Function & Memory API Tutorial Java 22 Unnamed Variables and Patterns with _Click to read tutorial: Java 22 Unnamed Variables and Patterns with _ Overview of New Features in Java 23Click to read tutorial: Overview of New Features in Java 23 Overview of New Features in Java 24Click to read tutorial: Overview of New Features in Java 24 Overview of New Features in Java 25Click to read tutorial: Overview of New Features in Java 25 Java 23 Markdown Documentation CommentsClick to read tutorial: Java 23 Markdown Documentation Comments Java 24 Stream Gatherers Tutorial with ExamplesClick to read tutorial: Java 24 Stream Gatherers Tutorial with Examples Java 24 Class-File API Tutorial with ExamplesClick to read tutorial: Java 24 Class-File API Tutorial with Examples