Compiling and Running from the Command Line

Naveen AnamaneniUpdated · 5 min read

IDEs hide the build behind a green Run button, which is convenient until something breaks. Then you need to know what that button actually does. Underneath, it's always the same two tools: javac to compile and java to run. Once you can use them by hand, build errors, CI pipelines and server deployments stop being mysterious.

The Two Commands

CommandInputOutput
javac Bill.javaA file name, with .javaBill.class in the same folder
java BillA class name, without .classRuns the program
Bill.java▶ Try it
public class Bill {
    public static void main(String[] args) {
        int tea = 20;
        int samosa = 15;
        int total = tea * 2 + samosa * 3;
        System.out.println("Total: Rs. " + total);
    }
}
Output
Total: Rs. 85
Terminal
javac Bill.java
java Bill

How it works

  1. Lines 3 and 4 store two prices.
  2. Line 5 works out two teas and three samosas: 20 * 2 + 15 * 3. Multiplication happens before addition, so the result is 40 + 45 = 85.
  3. Line 6 prints it.

Try it yourself: add a third item, int coffee = 25;, and include one coffee in the total. What should it print?

Compiling More Than One File

Real programs have many classes, usually one per file. Pass all of them to javac, or use a wildcard:

Terminal
javac Main.java Fare.java
javac *.java

If Main uses Fare, javac also compiles Fare.java on its own when it can find it in the same folder. Run the program by naming the class that has main:

Terminal
java Main

Keep .class Files Separate with -d

Mixing .java and .class files in one folder gets messy fast. The -d option tells javac where to write the .class files:

Terminal
javac -d out Bill.java

This creates a folder named out with Bill.class inside. To run it, tell java where to look with -cp (short for classpath):

Terminal
java -cp out Bill
javac takes a file name; java takes a class name

The classpath is the list of folders and .jar files where the JVM searches for classes. By default it's the current folder, which is why plain java Bill works when Bill.class is right there.

Useful Options

CommandWhat it does
javac --versionPrints the compiler version
java --versionPrints the runtime version (-version also works)
javac -d out *.javaCompiles every file in the folder into out
java -cp out MainRuns Main, looking for classes in out
javac --release 17 Bill.javaCompiles for Java 17, so the class runs on a Java 17 JVM
java -cp out Main Srihitha 3Passes Srihitha and 3 as command-line arguments

Common Mistakes

Running with .class on the end. java Bill.class makes Java look for a class literally named Bill.class:

Terminal output
Error: Could not find or load main class Bill.class
Caused by: java.lang.ClassNotFoundException: Bill.class

Running from the wrong folder. If you compiled into out but run java Bill from the project folder, the JVM can't find the class. You get the same Could not find or load main class Bill error. Add -cp out, or cd into the right folder.

Running a class that has no main. java Fare on a helper class prints Error: Main method not found in class Fare. Run the class that contains main.

Editing the code and running the old .class. If you change Bill.java but forget to run javac again, java Bill runs the old version. Compile after every change, or use java Bill.java, which always compiles first.

Practice

  1. Easy: Compile Bill.java into a folder named classes, then run it from the parent folder.
  2. Harder: Create two files: Main.java, which prints Fare.total(450, 3), and Fare.java, with a static int total(int fare, int people) method. Compile both with one command and run Main.

Quick check: javac and java

4 questions
1Which command is correct?
2You compiled with javac -d out Bill.java. How do you run it from the same folder?
3What is the classpath?
4You changed Bill.java and ran java Bill, but the old output appears. Why?

Key Takeaways

Was this tutorial helpful?

Lesson 15 of 482