W3docs

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 .java source files and produces .class files.
  • java — the launcher. Loads the JVM, finds a class by name, and runs its main method.
  • 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 --version

Compile 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.java

If there are no errors, you'll see a new file in the same directory called Greeting.class. That's the bytecode. Run it:

java Greeting
Hello 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 out tells javac to put generated .class files into the out/ directory (recreating the package directory structure).
  • -cp out tells java to look for classes on the out/ classpath.
  • com.example.greet.Greeting is 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.java

The 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> /exit

You 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 javacjava cycle on our server every time you press Run:

java— editable, runs on the server

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 missing import, 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, or javac was 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

Practice

Which command compiles Greeting.java into bytecode?