How to Compile and Run a Java Program
Use javac to compile .java source files into .class bytecode and the java launcher to run them on the JVM.
A Java program goes through two stages before it produces output. First, the compiler turns your .java source files into platform-neutral bytecode (.class files). Then the JVM loads that bytecode and executes it. Understanding both stages is what lets you reason about classpath errors, packaging, and the strange edge cases that occasionally show up.
This chapter walks through the toolchain — javac, java, and jshell — and the file layout the tools expect.
The toolchain
When you install the JDK you get three commands you'll use constantly:
javac— the Java compiler. Takes.javasource files and produces.classfiles.java— the launcher. Loads the JVM, finds a class by name, and runs itsmainmethod.jshell— an interactive REPL (read-eval-print loop) for trying out snippets without writing a full program. Added in Java 9.
You can confirm they're available by running each with -version:
javac -version
java -version
jshell --versionCompile a single source file
Suppose you have this file saved as Greeting.java:
public class Greeting {
public static void main(String[] args) {
System.out.println("Hello from javac!");
}
}Compile it:
javac Greeting.javaIf there are no errors, you'll see a new file in the same directory called Greeting.class. That's the bytecode. Run it:
java GreetingHello from javac!Notice you pass the class name, not the file name. java Greeting.class is wrong; so is java Greeting.java.
Compile a program with packages
Real programs are organised into packages that mirror their directory layout. A class declared as package com.example.greet; must live in com/example/greet/.
project/
└── src/
└── com/example/greet/
└── Greeting.java// src/com/example/greet/Greeting.java
package com.example.greet;
public class Greeting {
public static void main(String[] args) {
System.out.println("Hello with packages!");
}
}From the project/ directory, compile and run with the fully qualified class name:
javac -d out src/com/example/greet/Greeting.java
java -cp out com.example.greet.Greeting-d outtellsjavacto put generated.classfiles into theout/directory (recreating the package directory structure).-cp outtellsjavato look for classes on theout/classpath.com.example.greet.Greetingis the fully qualified class name — the package, a dot, and the class.
In practice you'd use a build tool (Maven or Gradle, covered later in this book) to do all of this. But knowing what they do under the hood helps when something breaks.
Source-file mode (single-file programs)
Since Java 11 you can skip javac entirely for one-file programs:
java Greeting.javaThe launcher compiles in memory and runs the result immediately. It's a great fit for quick scripts and book exercises.
jshell — the interactive REPL
jshell lets you type Java expressions and statements one line at a time, just like a Python or Node REPL:
$ jshell
| Welcome to JShell -- Version 21.0.4
| For an introduction type: /help intro
jshell> int x = 21
x ==> 21
jshell> int y = 21
y ==> 21
jshell> x + y
$3 ==> 42
jshell> System.out.println("Hello!")
Hello!
jshell> /exitYou don't need a class, a main method, or even semicolons for simple expressions. It's an excellent way to explore the standard library without setting up a project.
Run from the IDE
Every Java IDE — IntelliJ, Eclipse, VS Code — invokes javac and java behind the scenes when you click Run. The IDE also manages the classpath, displays compiler errors inline, and shows program output in a console pane. You don't have to use the command line, but knowing what the IDE is doing makes debugging build problems much faster.
A live example
The runnable block below goes through the same javac → java cycle on our server every time you press Run:
Edit the code, press Run, and the server compiles your modified source and prints whatever the program produces.
Common compile errors
A few mistakes you'll meet often:
class Greeting is public, should be declared in a file named Greeting.java— the file name and the public class name must match exactly.error: cannot find symbol— usually a typo, a missingimport, or a class that isn't on the classpath.';' expected— a missing semicolon at the end of a statement.error: package x.y.z does not exist— the package directory isn't on the classpath, orjavacwas pointed at the wrong source root.
When in doubt, read the error message — javac's diagnostics are unusually clear.
What's next
With the tooling under your fingers, the next part of the book starts on the language itself: Java Variables, Primitive Types, and the rest of the syntax basics.
Practice
Which command compiles Greeting.java into bytecode?