Java 25 makes running a single .java file easier than ever. Thanks to JEP 330 (Launch Single-File Source-Code Programs), combined with the new JEP 512 (Compact Source Files and Instance Main Methods), you can go from source to running program with a single command — no explicit javac step required.
Let’s walk through the options step by step.
1. Prerequisites
- JDK 25 installed and on your
PATH - Verify your setup:
java --version
javac --version
Both should report version 25.
2. Write a Single-File Program
Create a file called Hello.java. In Java 25, the simplest possible form is:
void main() {
IO.println("Hello, Java 25!");
}
No class, no static, no String[] args, no imports. The IO class is auto-imported in compact source files.
3. Run It Directly (No Compilation Step)
This is the recommended approach for scripts, prototypes, and small utilities:
java Hello.java
What happens under the hood:
- The
javalauncher detects that the argument ends in.java. - It invokes the compiler in memory (nothing is written to disk).
- The resulting bytecode is executed immediately.
Expected output:
Hello, Java 25!
Passing Arguments to Your Program
Anything after the source file name is passed as an argument to main:
java Hello.java arg1 arg2 arg3
To receive them, declare the parameter:
void main(String[] args) {
for (String arg : args) {
IO.println("Got: " + arg);
}
}
4. Compile and Run Separately (Traditional Way)
If you want a reusable .class file (for example, to distribute or run repeatedly without recompiling), do it in two steps.
Step 1 — Compile
javac Hello.java
This produces Hello.class in the current directory.
Note: For a compact source file without a class declaration, the compiler generates a synthetic class name based on the file name.
Step 2 — Run
java Hello
Note there is no .java extension here — you pass the class name, not the file name.
5. Choosing a Specific Source Version
If your default javac isn’t Java 25, you can request the level explicitly:
javac --release 25 Hello.java
Or, when running a single-file program:
java --source 25 Hello.java
This is handy if multiple JDKs coexist on your system.
6. Handling Files with a Non-Matching Name
With single-file source-code execution, the file name does not have to match any class defined inside — even if you declare public class Foo inside Bar.java, the following still works:
java Bar.java
However, if you switch to the classic two-step javac + java workflow, the standard rule applies: a public class must live in a file with the same name.
7. Adding a Shebang for Script-Like Execution (Unix/macOS)
You can turn a .java file into an executable script by adding a shebang line as the very first line:
#!/usr/bin/env java --source 25
void main() {
IO.println("Running as a script!");
}
Then make it executable and run:
chmod +x hello
./hello
The file must not have a
.javaextension when using the shebang trick — otherwise the launcher tries to compile the shebang line as Java source.
8. Quick Reference
| Goal | Command |
|---|---|
| Run a single source file | java Hello.java |
| Run with program arguments | java Hello.java foo bar |
| Force a specific source level | java --source 25 Hello.java |
| Compile only | javac Hello.java |
| Compile with an explicit release | javac --release 25 Hello.java |
| Run compiled class | java Hello |
9. Common Pitfalls
| Problem | Cause | Fix |
|---|---|---|
error: unknown source file extension |
You passed a file without .java to java |
Use java Hello.java (with extension) or java Hello (without) after compiling |
error: 'class', 'interface', ...' expected |
Older JDK doesn’t understand compact source files | Upgrade to JDK 25 |
main method not found |
Wrong signature (e.g., int main()) |
Use void main() or void main(String[] args) |
| Shebang script fails to run | File has .java extension |
Rename the file to remove the extension |
Summary
- For quick experiments:
java Hello.java— one command, no.classfile produced. - For repeated runs or distribution:
javac Hello.javathenjava Hello. - Combine with Java 25’s compact source files and instance
mainfor the shortest possible programs.
This unified workflow makes Java feel almost script-like while keeping the full power of the platform available when you need it.
